OpenGL系列之八:立方体纹理贴图

目录

相关文章

OpenGL系列之一:OpenGL第一个程序
OpenGL系列之二:绘制三角形
OpenGL系列之三:三角形顶点增加颜色
OpenGL系列之四:绘制四边形
OpenGL系列之五:绘制点和线
OpenGL系列之六:绘制立方体
OpenGL系列之七:纹理贴图

实现效果

实现步骤

1.修改渲染器

这里是以之前第七个程序(OpenGL系列之七:纹理贴图)为基础,修改GLRender中的JNI函数ndkLoadGLTexTureID,增加了一个索引(因为需要有六个纹理,因此纹理ID存到了数组里,因此需要用到索引),然后GLRender类修改如下:

class GLRender(val context:Context) : GLSurfaceView.Renderer{
    init {
        System.loadLibrary("CCOpenGLRender")
    }
    private external fun ndkInitGL()
    private external fun ndkPaintGL()
    private external fun ndkResizeGL(width:Int,height:Int)
    private external fun ndkLoadGLTexTureID(fileName:String,textTureIndex:Int)
    override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
        //初始化
        ndkInitGL()
        for (i in 0..6){
            val file = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),"texture/${i}.png")
            if(file.exists()){
                Log.e("测试",file.absolutePath)
                ndkLoadGLTexTureID(file.absolutePath,i)
            }
        }
    }

    override fun onSurfaceChanged(p0: GL10?, p1: Int, p2: Int) {
        //改变大小
        ndkResizeGL(p1,p2)
    }

    override fun onDrawFrame(p0: GL10?) {
        //绘制
        ndkPaintGL()
    }
}

onSurfaceCreated中循环加载6张图片



图片如下


5.png
0.png
1.png
2.png
3.png
4.png
2.修改JNI函数

这里我们修改Java_com_itfitness_opengldemo_GLRender_ndkLoadGLTexTureID函数如下:

GLuint m_texID[6];
int width, height, nrChannels;
extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkLoadGLTexTureID(JNIEnv *env, jobject thiz,
                                                          jstring file_name,jint texTureIndex) {
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1,&m_texID[texTureIndex]);//产生纹理索引
    glBindTexture(GL_TEXTURE_2D,m_texID[texTureIndex]);//绑定纹理索引,之后的操作都针对当前纹理索引

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//指当纹理图象被使用到一个大于它的形状上时
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//指当纹理图象被使用到一个小于或等于它的形状上时
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    const char* fileName = env->GetStringUTFChars(file_name,0);
    // 让图像正过来(如果不加图像是倒过来的)
    stbi_set_flip_vertically_on_load(true);
    // 加载并生成纹理
    unsigned char *data = stbi_load(fileName, &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }
    // 释放资源
    env->ReleaseStringUTFChars(file_name, fileName);
    stbi_image_free(data);
}

主要是增加了索引,然后textureID用数组存储,然后是渲染函数中因为需要绘制立方体因此增加了顶点数量,同时在绘制的时候采用循环的方式,切换textureid来进行绘制:

extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkPaintGL(JNIEnv *env, jobject thiz) {
    //清空颜色缓冲区或深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    //加载模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glCullFace(GL_BACK);

    //定义立方体顶点
    CCFloat5 cubeVert[] = {
            { -0.5f, -0.5f, -0.5f,  0.0f, 0.0f},
            { 0.5f, -0.5f, -0.5f,  1.0f, 0.0f},
            { 0.5f,  0.5f, -0.5f,  1.0f, 1.0f},
            { 0.5f,  0.5f, -0.5f,  1.0f, 1.0f},
            {-0.5f,  0.5f, -0.5f,  0.0f, 1.0f},
            {-0.5f, -0.5f, -0.5f,  0.0f, 0.0f},

            {-0.5f, -0.5f,  0.5f,  0.0f, 0.0f},
            {0.5f, -0.5f,  0.5f,  1.0f, 0.0f},
            {0.5f,  0.5f,  0.5f,  1.0f, 1.0f},
            {0.5f,  0.5f,  0.5f,  1.0f, 1.0f},
            {-0.5f,  0.5f,  0.5f,  0.0f, 1.0f},
            {-0.5f, -0.5f,  0.5f,  0.0f, 0.0f},

            {-0.5f,  0.5f,  0.5f,  1.0f, 0.0f},
            {-0.5f,  0.5f, -0.5f,  1.0f, 1.0f},
            {-0.5f, -0.5f, -0.5f,  0.0f, 1.0f},
            {-0.5f, -0.5f, -0.5f,  0.0f, 1.0f},
            {-0.5f, -0.5f,  0.5f,  0.0f, 0.0f},
            {-0.5f,  0.5f,  0.5f,  1.0f, 0.0f},

            {0.5f,  0.5f,  0.5f,  1.0f, 0.0f},
            {0.5f,  0.5f, -0.5f,  1.0f, 1.0f},
            {0.5f, -0.5f, -0.5f,  0.0f, 1.0f},
            {0.5f, -0.5f, -0.5f,  0.0f, 1.0f},
            {0.5f, -0.5f,  0.5f,  0.0f, 0.0f},
            {0.5f,  0.5f,  0.5f,  1.0f, 0.0f},

            {-0.5f, -0.5f, -0.5f,  0.0f, 1.0f},
            {0.5f, -0.5f, -0.5f,  1.0f, 1.0f},
            {0.5f, -0.5f,  0.5f,  1.0f, 0.0f},
            {0.5f, -0.5f,  0.5f,  1.0f, 0.0f},
            {-0.5f, -0.5f,  0.5f,  0.0f, 0.0f},
            {-0.5f, -0.5f, -0.5f,  0.0f, 1.0f},

            {-0.5f,  0.5f, -0.5f,  0.0f, 1.0f},
            {0.5f,  0.5f, -0.5f,  1.0f, 1.0f},
            {0.5f,  0.5f,  0.5f,  1.0f, 0.0f},
            {0.5f,  0.5f,  0.5f,  1.0f, 0.0f},
            {-0.5f,  0.5f,  0.5f,  0.0f, 0.0f},
            {-0.5f,  0.5f, -0.5f,  0.0f, 1.0f}
    };

    //启动一组顶点坐标
    glEnableClientState(GL_VERTEX_ARRAY);
    //启动TEXTURE
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    // 指定绘制的定点数组
    // 第一个参数:绘制几个点(这里其实就是CCFloat5中的前三个点x,y,z)
    // 第二个参数:类型为float
    // 第三个参数:第一个点到第二个点之间的步长(也就是结构体的长度)
    // 第四个参数:绘制数据的地址
    glVertexPointer(3,GL_FLOAT,sizeof(CCFloat5),cubeVert);
    // 指定绘制的定点数组
    // 第一个参数:绘制几个点(这里其实就是CCFloat5中的后两个点u,v)
    // 第二个参数:类型为float
    // 第三个参数:第一个点到第二个点之间的步长(也就是结构体的长度)
    // 第四个参数:绘制数据的地址
    glTexCoordPointer(2,GL_FLOAT,sizeof(CCFloat5),&cubeVert[0].u);

    //旋转起来
    m_angle += 0.01f;

    glm::mat4x4  cubeMat;
    //平移矩阵
    glm::mat4x4  cubeTransMat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -0.5));
    //旋转矩阵
    glm::mat4x4  cubeRotMat = glm::rotate(glm::mat4(1.0f),m_angle,glm::vec3(0.5f, 0.5f, 1.0) );
    //缩放矩阵
    glm::mat4x4  cubeScaleMat = glm::scale(glm::mat4(1.0f),glm::vec3(0.5f, 0.5f, 0.5) );
    cubeMat = cubeTransMat * cubeRotMat * cubeScaleMat;

    //加载矩阵
    glLoadMatrixf(glm::value_ptr(cubeMat));

    //循环绘制六个面
    for(int i=0; i< 6; i++)
    {
        glBindTexture(GL_TEXTURE_2D,m_texID[i]);
        glDrawArrays(GL_TRIANGLES,i*6,6);
    }

    //关闭一组顶点坐标
    glDisableClientState(GL_VERTEX_ARRAY);
    //关闭TEXTURE
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

案例源码

https://gitee.com/itfitness/opengl-cube-texture.git

你可能感兴趣的:(OpenGL系列之八:立方体纹理贴图)