zoukankan      html  css  js  c++  java
  • OpenGL 八

    案例中涉及到的点对应 《OpenGL七》

    案例一、隧道

    效果

    Demo链接

    1)四面:

    2)主要代码:

      1 // 初始化设置
      2 void SetupRC() {
      3     
      4     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);// 黑色
      5     shaderManager.InitializeStockShaders();
      6     
      7     
      8     GLbyte *pBytes;
      9     GLint iWidth, iHeight, iComponents;
     10     GLenum eFormat;
     11     
     12     // 生成纹理标记
     13     /* 分配纹理对象 glGenTextures
     14     参数1:纹理对象的数量
     15     参数2:纹理对象标识数组
     16     */
     17     glGenTextures(TEXTURE_COUNT, textures);
     18     
     19     
     20     // 设置纹理
     21     for (GLint i = 0; i < TEXTURE_COUNT; i++) {
     22         
     23         // 绑定纹理对象
     24         /*绑定纹理对象 glBindTexture
     25         参数1:纹理模式,GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D
     26         参数2:需要绑定的纹理对象id
     27         */
     28         glBindTexture(GL_TEXTURE_2D, textures[i]);
     29 
     30         
     31         // 加载 读取 tga 文件数据
     32         /* 加载 tga 文件
     33         参数1:纹理文件名称
     34         参数2:文件宽度变量地址
     35         参数3:文件高度变量地址
     36         参数4:文件组件变量地址
     37         参数5:文件格式变量地址
     38          
     39         返回值:pBytes,指向图像数据的指针
     40         */
     41         pBytes = gltReadTGABits(textureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat);
     42 
     43         
     44         // 设置纹理参数
     45         // 设置放大缩小 过滤方式 GL_TEXTURE_MAG_FILTER(放大过滤器,GL_NEAREST(最邻近过滤);GL_TEXTURE_MIN_FILTER(缩小过滤器,GL_NEAREST(最邻近过滤)
     46         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     47         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     48 
     49         // 设置环绕方式
     50         // GL_TEXTURE_WRAP_S(2D:s、t轴环绕),GL_CLAMP_TO_EDGE --> 环绕模式强制对范围之外的纹理坐标沿着合法的纹理单元的最后一行或一列进行采样
     51         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     52         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     53 
     54         
     55         // 载入纹理
     56         /* 载入纹理 glTexImage2D
     57         参数1:纹理维度,GL_TEXTURE_2D
     58         参数2:mip贴图层次
     59         参数3:纹理单元存储的颜色成分(从读取像素图中获得)
     60         参数4:加载纹理宽度
     61         参数5:加载纹理的高度
     62         参数6:为纹理贴图指定一个边界宽度 0
     63         参数7、8:像素数据的数据类型, GL_UNSIGNED_BYTE无符号整型
     64         参数9:指向纹理图像数据的指针
     65         */
     66         glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
     67         //        glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
     68 
     69         
     70         //  生成纹理对象 glGenerateMipmap
     71         /* 为纹理对象生成一组完整的 mipmap
     72         参数1:纹理维度,GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_2D
     73         */
     74         glGenerateMipmap(GL_TEXTURE_2D);
     75 
     76         // 释放原始纹理数据,不再需要纹理原始数据了
     77         free(pBytes);
     78     }
     79     
     80     
     81     // 设置隧道的上下左右4个面
     82     GLfloat z;// 深度,隧道的深度
     83     
     84     // 地板 -- 图 ‘地板’
     85     /*
     86     GLTools库中的容器类,GBatch -->  void GLBatch::Begin(GLenum primitive,GLuint nVerts,GLuint nTextureUnits = 0);
     87     参数1:图元枚举值
     88     参数2:顶点数
     89     参数3:纹理数 --> 1组或者2组纹理坐标
     90     */
     91     floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
     92     for(z = 60.0f; z >= 0.0f; z -=10.0f) {
     93         
     94         // 纹理坐标与顶点的对应
     95         floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);// 纹理坐标
     96         floorBatch.Vertex3f(-10.0f, -10.0f, z);// 顶点
     97         
     98         floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
     99         floorBatch.Vertex3f(10.0f, -10.0f, z);
    100         
    101         floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    102         floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
    103         
    104         floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    105         floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
    106     }
    107     floorBatch.End();
    108     
    109     // 天花板 -- 图 ‘天花板’
    110     ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    111     for(z = 60.0f; z >= 0.0f; z -=10.0f) {
    112         
    113         ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    114         ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
    115         
    116         ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    117         ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
    118         
    119         ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    120         ceilingBatch.Vertex3f(-10.0f, 10.0f, z);
    121         
    122         ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    123         ceilingBatch.Vertex3f(10.0f, 10.0f, z);
    124     }
    125     ceilingBatch.End();
    126     
    127     // 左侧墙面 -- 图 ‘左墙’
    128     leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    129     for(z = 60.0f; z >= 0.0f; z -=10.0f) {
    130         
    131         leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    132         leftWallBatch.Vertex3f(-10.0f, -10.0f, z);
    133         
    134         leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    135         leftWallBatch.Vertex3f(-10.0f, 10.0f, z);
    136         
    137         leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    138         leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
    139         
    140         leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    141         leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
    142     }
    143     leftWallBatch.End();
    144     
    145     // 右侧墙面 -- 图 ‘右墙‘
    146     rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
    147     for(z = 60.0f; z >= 0.0f; z -=10.0f) {
    148         
    149         rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    150         rightWallBatch.Vertex3f(10.0f, -10.0f, z);
    151         
    152         rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    153         rightWallBatch.Vertex3f(10.0f, 10.0f, z);
    154         
    155         rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    156         rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
    157         
    158         rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    159         rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
    160     }
    161     rightWallBatch.End();
    162 }
    163 
    164 // 渲染
    165 void RenderScene(void) {
    166     
    167     glClear(GL_COLOR_BUFFER_BIT);
    168 
    169     // 压栈
    170     modelViewMatix.PushMatrix();
    171     // z轴上平移
    172     modelViewMatix.Translate(0.0f, 0.0f, viewZ);
    173     
    174     // 纹理替换矩阵着色器
    175     /*
    176      参数1:GLT_SHADER_TEXTURE_REPLACE(着色器标签)
    177      参数2:模型视图投影矩阵
    178      参数3:纹理层
    179      */
    180     shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(),0);
    181     
    182     // 绑定纹理
    183     /*
    184      --> 为何又绑定一次???
    185      --> 为防止纹理 ID 绑定错误,状态机机制,在共同开发过程中,可能出现绑定的纹理出现变化
    186      */
    187     // 地板
    188     glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);
    189     floorBatch.Draw();
    190     // 天花板
    191     glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);
    192     ceilingBatch.Draw();
    193     // 左右墙
    194     glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);
    195     leftWallBatch.Draw();
    196     rightWallBatch.Draw();
    197     
    198     // 出栈
    199     modelViewMatix.PopMatrix();
    200     
    201     // 交换缓冲区
    202     glutSwapBuffers();
    203 }
    204 
    205 // 视口  窗口大小改变时接受新的宽度和高度,其中0,0代表窗口中视口的左下角坐标,w,h代表像素
    206 void ChangeSize(int w,int h) {
    207     // 防止h变为0
    208     if(h == 0)
    209         h = 1;
    210     
    211     // 设置视口窗口尺寸
    212     glViewport(0, 0, w, h);
    213     
    214     // setPerspective 函数的参数是一个从顶点方向看去的视场角度(用角度值表示)
    215     // 设置透视模式,初始化其透视矩阵
    216     viewFrustum.SetPerspective(80.0f, GLfloat(w)/GLfloat(h), 1.0f, 120.0f);
    217     
    218     //4.把 透视矩阵 加载到 透视矩阵对阵中
    219     projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    220     
    221     //5.初始化渲染管线
    222     transformPipeline.SetMatrixStacks(modelViewMatix, projectionMatrix);
    223 }

    案例二、球体转动 添加纹理

    效果

    Demo链接

    主要代码

      1 // 绘制球体视图
      2 void drawSpheres (GLfloat yRot) {
      3     
      4     // 设置点光源位置
      5     static GLfloat vLightPos[] = {0.0f, 3.0f, 0.0f, 1.0f};
      6     // 漫反射颜色 白色
      7     static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
      8     
      9     
     10     // 绘制 小球们
     11     // 绑定纹理
     12     glBindTexture(GL_TEXTURE_2D, textures[2]);// 小球上贴的纹理
     13     for (int i = 0; i < SPHERE_NUM; i++) {
     14         
     15         modelViewMatix.PushMatrix();
     16         modelViewMatix.MultMatrix(spheres[i]);// 小球位置
     17         modelViewMatix.Rotate(yRot, 0, 1, 0);
     18         // GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF:纹理点光源着色器;vLightPos:光源位置;vBigSphereColor:绘制颜色
     19         shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
     20                                      modelViewMatix.GetMatrix(),
     21                                      transformPipeline.GetProjectionMatrix(),
     22                                      vLightPos,
     23                                      vWhite,
     24                                      0);
     25         sphereBatch.Draw();
     26         
     27         modelViewMatix.PopMatrix();
     28     }
     29     
     30     
     31     // 绘制大球
     32     modelViewMatix.Translate(0, 0.2f, -2.5f);// y轴上靠近镜面一点 Z轴距离再远一些
     33     //
     34     modelViewMatix.PushMatrix();
     35     // 大球沿Y轴  旋转弧度:yRot 自传
     36     modelViewMatix.Rotate(yRot, 0, 1, 0);
     37     // 绑定纹理
     38     glBindTexture(GL_TEXTURE_2D, textures[1]);
     39     shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
     40                                  modelViewMatix.GetMatrix(),
     41                                  transformPipeline.GetProjectionMatrix(),
     42                                  vLightPos,
     43                                  vWhite,
     44                                  0);
     45     bigSphereBatch.Draw();
     46     modelViewMatix.PopMatrix();
     47     
     48     
     49     // 绘制沿大球转的小球
     50     modelViewMatix.PushMatrix();
     51     modelViewMatix.Rotate(yRot * -2, 0, 1, 0);
     52     modelViewMatix.Translate(0.8f, 0.0f, 0.0f);// 小球在X方向上偏移一定位置 不然会看不见小球
     53     glBindTexture(GL_TEXTURE_2D, textures[2]);
     54     shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
     55                                  modelViewMatix.GetMatrix(),
     56                                  transformPipeline.GetProjectionMatrix(),
     57                                  vLightPos,
     58                                  vWhite,
     59                                  0);
     60     sphereBatch.Draw();
     61     modelViewMatix.PopMatrix();
     62     
     63 }
     64 
     65 // 设置纹理
     66 bool LoadTGATexture(const char *textureName, GLenum minFilter, GLenum magFilter, GLenum wrapModel) {
     67     
     68     GLbyte *pBits;
     69     int nWidth, nHeight, nComponents;
     70     GLenum eFormat;
     71     
     72     // 读取纹理
     73     pBits = gltReadTGABits(textureName, &nWidth, &nHeight, &nComponents, &eFormat);
     74     if (!pBits) {
     75         return false;
     76     }
     77     
     78     //  设置过滤方式
     79     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
     80     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
     81     
     82     // 设置环绕方式
     83     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapModel);
     84     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapModel);
     85     
     86     // 载入纹理
     87     glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
     88     
     89     //  使用完毕释放pbit
     90     free(pBits);
     91     
     92     
     93     // 只有minFilter 等于以下四种模式,才可以生成Mip贴图
     94     // GL_NEAREST_MIPMAP_NEAREST具有非常好的性能,并且闪烁现象非常弱
     95     // GL_LINEAR_MIPMAP_NEAREST常常用于对游戏进行加速,它使用了高质量的线性过滤器
     96     // GL_LINEAR_MIPMAP_LINEAR 和GL_NEAREST_MIPMAP_LINEAR 过滤器在Mip层之间执行了一些额外的插值,以消除他们之间的过滤痕迹。
     97     // GL_LINEAR_MIPMAP_LINEAR 三线性Mip贴图。纹理过滤的黄金准则,具有最高的精度。
     98     if (minFilter == GL_LINEAR_MIPMAP_LINEAR ||
     99         minFilter == GL_LINEAR_MIPMAP_NEAREST ||
    100         minFilter == GL_NEAREST_MIPMAP_LINEAR ||
    101         minFilter == GL_NEAREST_MIPMAP_NEAREST) {
    102         
    103         // 加载mip 纹理生成所有的mip 层
    104         // 参数:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
    105         glGenerateMipmap(GL_TEXTURE_2D);
    106     }
    107     
    108     return true;
    109 }
    110 
    111 // 初始化 设置
    112 void SetupRC() {
    113     
    114     // 设置清屏颜色到颜色缓存区
    115     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    116     
    117     // 初始化着色器管理器
    118     shaderManager.InitializeStockShaders();
    119     
    120     // 开启深度测试 背面剔除
    121     glEnable(GL_DEPTH_TEST);
    122     glEnable(GL_CULL_FACE);
    123 
    124     // 设置大球
    125     gltMakeSphere(bigSphereBatch, 0.4f, 40, 80);
    126     
    127     // 设置小球
    128     gltMakeSphere(sphereBatch, 0.1f, 26, 13);
    129     
    130     // 地板 纹理 --> 4个顶点对应纹理图的4个坐标
    131     GLfloat texSize = 10.0f;
    132     floorTriangleBatch.Begin(GL_TRIANGLE_FAN, 4,1);
    133     floorTriangleBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    134     floorTriangleBatch.Vertex3f(-20.f, -0.41f, 20.0f);
    135     
    136     floorTriangleBatch.MultiTexCoord2f(0, texSize, 0.0f);
    137     floorTriangleBatch.Vertex3f(20.0f, -0.41f, 20.f);
    138     
    139     floorTriangleBatch.MultiTexCoord2f(0, texSize, texSize);
    140     floorTriangleBatch.Vertex3f(20.0f, -0.41f, -20.0f);
    141     
    142     floorTriangleBatch.MultiTexCoord2f(0, 0.0f, texSize);
    143     floorTriangleBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
    144     floorTriangleBatch.End();
    145     
    146     
    147     // 小球们的位置 随机小球顶点坐标数据
    148     for (int i = 0; i < SPHERE_NUM; i++) {
    149         
    150         // y轴不变,X,Z产生随机值
    151         GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
    152         GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
    153         
    154         // 在y方向,将球体设置为0.0的位置,这使得它们看起来是飘浮在眼睛的高度
    155         // 对spheres数组中的每一个顶点,设置顶点数据
    156         spheres[i].SetOrigin(x, 0.0f, z);
    157     }
    158     
    159     
    160     // 设置纹理
    161     // 生成纹理标记
    162     glGenTextures(3, textures);
    163     
    164     // 绑定纹理 设置纹理参数
    165     glBindTexture(GL_TEXTURE_2D, textures[0]);
    166     LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
    167     
    168     // GL_CLAMP_TO_EDGE 纹理坐标约束在0~1,超出部分边缘重复(边缘拉伸效果)
    169     glBindTexture(GL_TEXTURE_2D, textures[1]);
    170     LoadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR,
    171                    GL_LINEAR, GL_CLAMP_TO_EDGE);
    172     
    173     glBindTexture(GL_TEXTURE_2D, textures[2]);
    174     LoadTGATexture("moonlike.tga", GL_LINEAR_MIPMAP_LINEAR,
    175                    GL_LINEAR, GL_CLAMP_TO_EDGE);
    176 }
    177 
    178 
    179 
    180 // 渲染
    181 void RenderScene(void) {
    182     
    183     // 清除窗口 颜色、深度缓冲区
    184     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    185     
    186     // 地板颜色 --> 镜面透明效果 alpha设置一定透明度
    187     static GLfloat vFloorColor[] = {1.0, 1.0, 0.0, 0.7f};
    188     
    189     // 定时器时间 动画 --> 大球自传
    190     static CStopWatch rotTimer;
    191     float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
    192     
    193     
    194     // 压栈 --> copy 一份栈顶矩阵 --> 单元矩阵
    195     modelViewMatix.PushMatrix();
    196     
    197     
    198     // 观察者矩阵压栈
    199     /*
    200      观察者的移动要影响到所有绘制物体,所以要 先压栈
    201      */
    202     M3DMatrix44f cameraM;
    203     cameraFrame.GetCameraMatrix(cameraM);
    204     modelViewMatix.MultMatrix(cameraM);
    205     
    206     
    207     // 镜面内部分
    208     // 压栈 --> 原因:镜面部分绘制后要继续绘制地板上面的视图
    209     modelViewMatix.PushMatrix();
    210     // 镜面内的小球门
    211     // 绘制镜面内部分(镜面内的小球门)
    212     
    213     // 沿Y轴翻转
    214     modelViewMatix.Scale(1.0f, -1.0f, 1.0f);
    215     // 视图距离地板面设定一定间隔 -- 避免粘在一起 就不像镜面了
    216     modelViewMatix.Translate(0, 0.8, 0);
    217     
    218     // 此时绘制镜面部分为顺时针旋转,将顺时针旋转设为正面 --> 正背面 观察者只能看到正面
    219     glFrontFace(GL_CW);
    220     // 绘制视图
    221     drawSpheres(yRot);
    222     
    223     // 恢复逆时针转为正面
    224     glFrontFace(GL_CCW);
    225     //
    226     modelViewMatix.PopMatrix();
    227     
    228     
    229     // 绘制镜面
    230     // 开启混合
    231     glEnable(GL_BLEND);
    232     // 指定混合方程式
    233     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    234     //  绑定地面(镜面)纹理
    235     glBindTexture(GL_TEXTURE_2D, textures[0]);
    236     /* 纹理调整着色器 --> 将一个基本色乘以一个取自纹理的单元nTextureUnit的纹理
    237      参数1:GLT_SHADER_TEXTURE_MODULATE
    238      参数2:模型视图投影矩阵
    239      参数3:颜色
    240      参数4:纹理单元(第0层的纹理单元)
    241      */
    242     shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
    243                                  transformPipeline.GetModelViewProjectionMatrix(),
    244                                  vFloorColor,
    245                                  0);
    246     floorTriangleBatch.Draw();
    247     // 取消混合
    248     glDisable(GL_BLEND);
    249     
    250     
    251     // 绘制镜面外的球
    252     drawSpheres(yRot);
    253     
    254     modelViewMatix.PopMatrix();
    255     
    256     
    257     //
    258     glutSwapBuffers();
    259     
    260     //
    261     glutPostRedisplay();
    262 }
  • 相关阅读:
    JAVA_OA管理系统(三):Spring参数注入
    JAVA_OA管理系统(二):SpringMVC笔记基础篇01注入方法
    java_OA管理系统(一):Servlet总结案例仿网络聊天室
    探秘Java中String、StringBuilder以及StringBuffer
    详解Java中的注解
    详解Java中的注解
    JSP中文乱码问题(get,post篇)
    JSP中文乱码问题(get,post篇)
    98%的人没解出的德国面试逻辑题(离散数学篇)!?
    哈希函数
  • 原文地址:https://www.cnblogs.com/zhangzhang-y/p/13365725.html
Copyright © 2011-2022 走看看