美文网首页
九:OpenGL纹理(下):宇宙星球

九:OpenGL纹理(下):宇宙星球

作者: Mr姜饼 | 来源:发表于2020-10-29 09:37 被阅读0次

    前言:

    还记得之前的案例为大家写过了一个地球月球的demo吧,光是颜色渲染是不是显得太过单调了,这次我们在其基础上来为他们渲染上纹理吧,这样我们显得高大上一点。

    实现效果:

    效果图

    代码实现:

    Step1:
    //绑定纹理
    bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
    {
        
        GLbyte *bits;
        int wid,hig,nCompent;
        GLenum eFromat;
        
        //读取纹理数据
        bits = gltReadTGABits(szFileName, &wid, &hig, &nCompent, &eFromat);
        if(bits == NULL){
            return false;
        }
        
        //设置纹理参数
        //环绕方式
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
        //过滤方式
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
        
        
        //载入纹理
        glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, wid, hig, 0, eFromat, GL_UNSIGNED_BYTE, bits);
        
        
        if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
           minFilter == GL_LINEAR_MIPMAP_NEAREST ||
           minFilter == GL_NEAREST_MIPMAP_LINEAR ||
           minFilter == GL_NEAREST_MIPMAP_NEAREST)
        {
            //4.加载Mip,纹理生成所有的Mip层
            //参数:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    
        
        free(bits);
        
        
        return true;
    }
    
    

    我们先把纹理绑定的核心代码给加上。

    Step2:重绘制地板的模型
        GLfloat texSize = 10.0f;
    
        //创建地板批次类
        floorBatch.Begin(GL_TRIANGLE_FAN, 4,1);
    
        floorBatch.Vertex3f(-20, -0.5f, 20.f);
        floorBatch.MultiTexCoord2f(0, 0, 0);
    
        floorBatch.Vertex3f(20, -0.5f, 20.f);
        floorBatch.MultiTexCoord2f(0, texSize, 0);
    
        floorBatch.Vertex3f(20, -0.5f, -20.f);
        floorBatch.MultiTexCoord2f(0, texSize, texSize);
    
        floorBatch.Vertex3f(-20, -0.5f, -20.f);
        floorBatch.MultiTexCoord2f(0, 0, texSize);
    
        floorBatch.End();
    

    之前我们是循环创建的以线段显示的地面,现在我们要使用纹理贴图,所以我们定义四个顶点坐标,即可。

    Step3:为每个纹理进行绑定和加载
         //分配纹理
        glGenTextures(3, uiTextures);
        
        //绑定纹理
        glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
        LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
    
        
        glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
        LoadTGATexture("Marslike.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
    
        glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
        LoadTGATexture("Moonlike.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
    
    Step4:渲染场景
    //开始渲染
    void RenderScene(void) {
        //清除一个或一组特定的缓冲区
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
        
        
        //设置一组浮点数来各个颜色
        GLfloat vRed[] = {0.0f,1.0f,0.0f,1.0f};
        GLfloat vBlue[] = {0.0f,0.0f,1.0f,1.0f};
        
        static GLfloat vFloorColor[] = { 1.0f, 1.0f, 0.0f, 0.75f};
    
        //漫反射颜色
        static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    
    
        //2.基于时间动画
        static CStopWatch    rotTimer;
        float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
    
        //4.光源位置
        M3DVector4f vLightPos = {0.0f,10.0f,5.0f,1.0f};
    
        
        modelViewMatrix.PushMatrix();
        
        
        //4.加入观察者 并且压入栈顶
         M3DMatrix44f mCamera;
         cameraFrame.GetCameraMatrix(mCamera);
         modelViewMatrix.MultMatrix(mCamera);
        
     
        
        //绑定对应纹理
        glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
        //地板绘制
        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,transformPipeline.GetModelViewProjectionMatrix(),vWhite ,0);
        floorBatch.Draw();
        
        
        //地球绘制
        //5.使得地球和后来创建的月球位置向z轴平移向屏幕里面
        modelViewMatrix.Translate(0.0f, 0.0f, -3.0f);
        
        
        //6.压栈(复制栈顶)
        modelViewMatrix.PushMatrix();
        //7.地球自转
        modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
        //绑定对应纹理
        glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
        //8.指定合适的着色器(点光源纹理着色器)
        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(),
                                     transformPipeline.GetProjectionMatrix(), vLightPos, vWhite,0);
        earthBatch.Draw();
        modelViewMatrix.PopMatrix();
        
        
        //月球
        modelViewMatrix.PushMatrix();
        //围绕地球旋转,先x自身旋转,然后再依靠距离x轴的距离,来造成旋转的假象。
        modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
        modelViewMatrix.Translate(1.0f, 0.0f, 0.0f);
        //
        
        //绑定对应纹理
        glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
        //8.指定合适的着色器(点光源纹理着色器)
        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(),
        transformPipeline.GetProjectionMatrix(), vLightPos, vWhite,0);
        moonBatch.Draw();
        modelViewMatrix.PopMatrix();
    
    
        //退出camera的矩阵
        modelViewMatrix.PopMatrix();
    
        //将在后台缓冲区进行渲染,然后在结束时交换到前台
        glutSwapBuffers();
        
        //重新渲染
        glutPostRedisplay();
    }
    

    完结撒花✿✿ヽ(°▽°)ノ✿


    强化练习:

    上面的案例还是比较简单,那么接下来,如果我们要实现以下的效果图,该如何去做呢。


    image.png

    实现:月球的周围出现其他的行星,而且出现了一个类似于水面反射的效果,

    大家思考下吧,下节课为大家做强化练习!!!!!!

    相关文章

      网友评论

          本文标题:九:OpenGL纹理(下):宇宙星球

          本文链接:https://www.haomeiwen.com/subject/frfcvktx.html