美文网首页
OpenGL纹理下的球体世界

OpenGL纹理下的球体世界

作者: 枫紫_6174 | 来源:发表于2020-07-21 12:58 被阅读0次

    一.先看看整体效果

    球体下的世界

    二.绘制流程

                    在OpenGl综合案例(地板,大小球,公转,自转,移动)文章中,我们绘制了大小球,公转,自转,今天我们往上面添加纹理(图片)

    1.镜面效果

                    镜面效果其实就是把上面的翻转过来,通过纹理颜色混合达到的效果,具体流程如下:

    RenderScene流程

    特别说明:纹理调整着色器

                                                     纹理调整着色器(将一个基本色乘以一个取自纹理的单元nTextureUnit的纹理)

                                                     参数1:GLT_SHADER_TEXTURE_MODULATE

                                                     参数2:模型视图投影矩阵

                                                     参数3:颜色

                                                     参数4:纹理单元(第0层的纹理单元)

        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,transformPipeline.GetModelViewProjectionMatrix(),vFloorColor, 0);

    封装函数绘制流程

    LoadTGATexture封装函数即参数说明:

    boolLoadTGATexture(constchar*szFileName,GLenumminFilter,GLenummagFilter,GLenumwrapMode)

    {

        GLbyte*pBits;

        intnWidth, nHeight, nComponents;

        GLenumeFormat;

        //1.读取纹理数据

        pBits =gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);

        if(pBits ==NULL)

            return false;

        //2、设置纹理参数

        //参数1:纹理维度

        //参数2:为S/T坐标设置模式

        //参数3:wrapMode,环绕模式

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);

        //参数1:纹理维度

        //参数2:线性过滤

        //参数3:wrapMode,环绕模式

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);

        //3.载入纹理

        //参数1:纹理维度

        //参数2:mip贴图层次

        //参数3:纹理单元存储的颜色成分(从读取像素图是获得)-将内部参数nComponents改为了通用压缩纹理格式GL_COMPRESSED_RGB

        //参数4:加载纹理宽

        //参数5:加载纹理高

        //参数6:加载纹理的深度

        //参数7:像素数据的数据类型(GL_UNSIGNED_BYTE,每个颜色分量都是一个8位无符号整数)

        //参数8:指向纹理图像数据的指针

        glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0,

                     eFormat,GL_UNSIGNED_BYTE, pBits);

        //使用完毕释放pBits

        free(pBits);

        //只有minFilter 等于以下四种模式,才可以生成Mip贴图

        //GL_NEAREST_MIPMAP_NEAREST具有非常好的性能,并且闪烁现象非常弱

        //GL_LINEAR_MIPMAP_NEAREST常常用于对游戏进行加速,它使用了高质量的线性过滤器

        //GL_LINEAR_MIPMAP_LINEAR 和GL_NEAREST_MIPMAP_LINEAR 过滤器在Mip层之间执行了一些额外的插值,以消除他们之间的过滤痕迹。

        //GL_LINEAR_MIPMAP_LINEAR 三线性Mip贴图。纹理过滤的黄金准则,具有最高的精度。

        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);

        return true;

    }

    自定义函数说明:

    void drawSomething(GLfloat yRot)

    {

        //1.定义光源位置&漫反射颜色

        staticGLfloatvWhite[] = {1.0f,1.0f,1.0f,1.0f};

        staticGLfloatvLightPos[] = {0.0f,3.0f,0.0f,1.0f};

        //2.绘制悬浮小球球

        glBindTexture(GL_TEXTURE_2D, uiTextures[2]);

        for(inti =0; i

            modelViewMatrix.PushMatrix();

            modelViewMatrix.MultMatrix(spheres[i]);

            shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,

                                         modelViewMatrix.GetMatrix(),

                                         transformPipeline.GetProjectionMatrix(),

                                         vLightPos,

                                         vWhite,

                                         0);

            sphereBatch.Draw();

            modelViewMatrix.PopMatrix();

        }

        //3.绘制大球球

        modelViewMatrix.Translate(0.0f, 0.2f, -2.5f);

        modelViewMatrix.PushMatrix();

        modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);

        glBindTexture(GL_TEXTURE_2D, uiTextures[1]);

        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,

                                     modelViewMatrix.GetMatrix(),

                                     transformPipeline.GetProjectionMatrix(),

                                     vLightPos,

                                     vWhite,

                                     0);

        torusBatch.Draw();

        modelViewMatrix.PopMatrix();

        //4.绘制公转小球球(公转自转)

        modelViewMatrix.PushMatrix();

        modelViewMatrix.Rotate(yRot * -2.0f,0.0f,1.0f,0.0f);

        modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);

        glBindTexture(GL_TEXTURE_2D, uiTextures[2]);

        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,

                                     modelViewMatrix.GetMatrix(),

                                     transformPipeline.GetProjectionMatrix(),

                                     vLightPos,

                                     vWhite,

                                     0);

        sphereBatch.Draw();

        modelViewMatrix.PopMatrix();

    }

                    最后附上压栈出栈理解:(仅限个人理解)modelViewMatrix.PushMatrix()&&modelViewMatrix.PopMatrix()成对出现,在观察者看到的世界中,使用OpenGL绘制图形,它是一个绘制完成后再绘制另外一个,压栈和出栈可以理解成告诉OpenGL在对应的这个区间,使用其设置的参数绘制图形,最外层的压栈出栈就是告诉OpenGL,绘制其他所有的图形都必须在这个压栈出栈区间(你可以理解成当我们没有睁开眼睛时,看不见任何物体,当我们睁开眼的时候,说看到的物体在这个区间绘制)


    push/pop理解

    绑定纹理理解:

    绑定纹理总结

    说明:(仅限个人理解)SetupRC只是初始化我们的纹理,在RenderScene告诉shaderManager每一个图形要用的对应的纹理,删除了SetupRC的绑定,则不能显示纹理,删除了RenderScene的绑定,则拿到的是上一个或者不确定的纹理

    附上案例:链接: https://pan.baidu.com/s/1uSR6ltwqlXRegBJXJbQfzg 提取码: bka4

    相关文章

      网友评论

          本文标题:OpenGL纹理下的球体世界

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