
【OpenGL】纹理数组案例
发布日期:2021-05-10 02:21:08
浏览次数:3
分类:技术文章
本文共 9219 字,大约阅读时间需要 30 分钟。
在第三章节Smoother示例程序基础上,加多了一个月亮的渲染,它会用29个纹理图经过一定时间切换图片,进行循环播放动画一样。属于第七章内容——高级纹理
// TextureArrays.cpp// OpenGL SuperBible// Demonstrates Passing a TextureArray to a shader// Program by Richard S. Wright Jr.#pragma comment(lib, "gltools.lib")#include// OpenGL toolkit#include #include #ifdef __APPLE__#include #else#define FREEGLUT_STATIC#include #endifGLShaderManager shaderManager;GLFrustum viewFrustum;GLBatch smallStarBatch;GLBatch mediumStarBatch;GLBatch largeStarBatch;GLBatch mountainRangeBatch;GLBatch moonBatch;GLuint starTexture;GLuint starFieldShader; // The point sprite shaderGLint locMVP; // The location of the ModelViewProjection matrix uniformGLint locStarTexture; // The location of the texture uniformGLuint moonTexture;GLuint moonShader;GLint locMoonMVP;GLint locMoonTexture;GLint locMoonTime;GLint locTimeStamp; // The location of the time stamp// Array of small stars#define SMALL_STARS 100#define MEDIUM_STARS 40#define LARGE_STARS 15#define SCREEN_X 800#define SCREEN_Y 600// Load a TGA as a 2D Texture. Completely initialize the statebool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode){ GLbyte *pBits; int nWidth, nHeight, nComponents; GLenum eFormat; // Read the texture bits pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat); if (pBits == 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); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits); free(pBits); if (minFilter == GL_LINEAR_MIPMAP_LINEAR || minFilter == GL_LINEAR_MIPMAP_NEAREST || minFilter == GL_NEAREST_MIPMAP_LINEAR || minFilter == GL_NEAREST_MIPMAP_NEAREST) glGenerateMipmap(GL_TEXTURE_2D); return true;}///// Called to draw scenevoid RenderScene(void){ static CStopWatch timer; // Clear the window glClear(GL_COLOR_BUFFER_BIT); // Everything is white GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glBindTexture(GL_TEXTURE_2D, starTexture); glUseProgram(starFieldShader); glUniformMatrix4fv(locMVP, 1, GL_FALSE, viewFrustum.GetProjectionMatrix()); glUniform1i(locStarTexture, 0); // Draw small stars glPointSize(4.0f); smallStarBatch.Draw(); // Draw medium sized stars glPointSize(8.0f); mediumStarBatch.Draw(); // Draw largest stars glPointSize(12.0f); largeStarBatch.Draw(); // Draw distant horizon shaderManager.UseStockShader(GLT_SHADER_FLAT, viewFrustum.GetProjectionMatrix(), vWhite); glLineWidth(3.5); mountainRangeBatch.Draw(); // Draw the "moon" glBindTexture(GL_TEXTURE_2D_ARRAY, moonTexture); glUseProgram(moonShader); glUniformMatrix4fv(locMoonMVP, 1, GL_FALSE, viewFrustum.GetProjectionMatrix()); glUniform1i(locMoonTexture, 0); // fTime goes from 0.0 to 28.0 and recycles float fTime = timer.GetElapsedSeconds(); fTime = fmod(fTime, 28.0f); glUniform1f(locTimeStamp, fTime); moonBatch.Draw(); // Swap buffers glutSwapBuffers(); glutPostRedisplay();}// This function does any needed initialization on the rendering// context. void SetupRC(){ M3DVector3f vVerts[SMALL_STARS]; // SMALL_STARS is the largest batch we are going to need int i; glEnable(GL_POINT_SPRITE); shaderManager.InitializeStockShaders(); // A number of shipping drivers are not conformant to the current OpenGL // spec and require this. NVidia... in particular. The OpenGL specification // states that this is always "on", in fact you can't enable or disable it // anymore. Adding this lines "fixes" this on non-conformant drivers, but // be aware, if you have a pure core (and working correctly) GL context, //you should not do this glEnable(GL_POINT_SPRITE); // Populate star list smallStarBatch.Begin(GL_POINTS, SMALL_STARS); for (i = 0; i < SMALL_STARS; i++) { vVerts[i][0] = (GLfloat)(rand() % SCREEN_X); vVerts[i][1] = (GLfloat)(rand() % (SCREEN_Y - 100)) + 100.0f; vVerts[i][2] = 0.0f; } smallStarBatch.CopyVertexData3f(vVerts); smallStarBatch.End(); // Populate star list mediumStarBatch.Begin(GL_POINTS, MEDIUM_STARS); for (i = 0; i < MEDIUM_STARS; i++) { vVerts[i][0] = (GLfloat)(rand() % SCREEN_X); vVerts[i][1] = (GLfloat)(rand() % (SCREEN_Y - 100)) + 100.0f; vVerts[i][2] = 0.0f; } mediumStarBatch.CopyVertexData3f(vVerts); mediumStarBatch.End(); // Populate star list largeStarBatch.Begin(GL_POINTS, LARGE_STARS); for (i = 0; i < LARGE_STARS; i++) { vVerts[i][0] = (GLfloat)(rand() % SCREEN_X); vVerts[i][1] = (GLfloat)(rand() % (SCREEN_Y - 100)) + 100.0f; vVerts[i][2] = 0.0f; } largeStarBatch.CopyVertexData3f(vVerts); largeStarBatch.End(); M3DVector3f vMountains[12] = { 0.0f, 25.0f, 0.0f, 50.0f, 100.0f, 0.0f, 100.0f, 25.0f, 0.0f, 225.0f, 125.0f, 0.0f, 300.0f, 50.0f, 0.0f, 375.0f, 100.0f, 0.0f, 460.0f, 25.0f, 0.0f, 525.0f, 100.0f, 0.0f, 600.0f, 20.0f, 0.0f, 675.0f, 70.0f, 0.0f, 750.0f, 25.0f, 0.0f, 800.0f, 90.0f, 0.0f }; mountainRangeBatch.Begin(GL_LINE_STRIP, 12); mountainRangeBatch.CopyVertexData3f(vMountains); mountainRangeBatch.End(); // The Moon GLfloat x = 700.0f; // Location and radius of moon GLfloat y = 500.0f; GLfloat r = 50.0f; GLfloat angle = 0.0f; // Another looping variable moonBatch.Begin(GL_TRIANGLE_FAN, 4, 1); moonBatch.MultiTexCoord2f(0, 0.0f, 0.0f); moonBatch.Vertex3f(x - r, y - r, 0.0f); moonBatch.MultiTexCoord2f(0, 1.0f, 0.0f); moonBatch.Vertex3f(x + r, y - r, 0.0f); moonBatch.MultiTexCoord2f(0, 1.0f, 1.0f); moonBatch.Vertex3f(x + r, y + r, 0.0f); moonBatch.MultiTexCoord2f(0, 0.0f, 1.0f); moonBatch.Vertex3f(x - r, y + r, 0.0f); moonBatch.End(); // Black background glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Turn on line antialiasing, and give hint to do the best // job possible. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); starFieldShader = gltLoadShaderPairWithAttributes("StarField.vp", "StarField.fp", 1, GLT_ATTRIBUTE_VERTEX, "vVertex"); locMVP = glGetUniformLocation(starFieldShader, "mvpMatrix"); locStarTexture = glGetUniformLocation(starFieldShader, "starImage"); moonShader = gltLoadShaderPairWithAttributes("MoonShader.vp", "MoonShader.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "vTexCoords"); locMoonMVP = glGetUniformLocation(moonShader, "mvpMatrix"); locMoonTexture = glGetUniformLocation(moonShader, "moonImage"); locMoonTime = glGetUniformLocation(moonShader, "fTime"); glGenTextures(1, &starTexture); glBindTexture(GL_TEXTURE_2D, starTexture); LoadTGATexture("Star.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE); glGenTextures(1, &moonTexture); glBindTexture(GL_TEXTURE_2D_ARRAY, moonTexture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 64, 64, 30, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); for (int i = 0; i < 29; i++) { char cFile[32]; sprintf_s(cFile, "moon%02d.tga", i); //'sprintf' unsafe, replace with 'sprintf_s' GLbyte *pBits; int nWidth, nHeight, nComponents; GLenum eFormat; // Read the texture bits pBits = gltReadTGABits(cFile, &nWidth, &nHeight, &nComponents, &eFormat); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, nWidth, nHeight, 1, GL_BGRA, GL_UNSIGNED_BYTE, pBits); free(pBits); }}void ChangeSize(int w, int h){ // Prevent a divide by zero if (h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); // Establish clipping volume (left, right, bottom, top, near, far) viewFrustum.SetOrthographic(0.0f, SCREEN_X, 0.0f, SCREEN_Y, -1.0f, 1.0f);}int main(int argc, char* argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutCreateWindow("Texture Arrays"); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC(); glutMainLoop(); return 0;}
// MoonShader// Vertex Shader// Richard S. Wright Jr.// OpenGL SuperBible#version 130in vec4 vVertex;in vec4 vTexCoords;uniform mat4 mvpMatrix;uniform float fTime;smooth out vec3 vMoonCoords;void main(void) { vMoonCoords.st = vTexCoords.st; vMoonCoords.p = fTime; gl_Position = mvpMatrix * vVertex; }
// MoonShader// Fragment Shader// Richard S. Wright Jr.// OpenGL SuperBible#version 130// Another NVidia Driver non-conformance bug// You should not have to put this here for a 3.3 driver.#extension GL_EXT_gpu_shader4: enableout vec4 vFragColor;uniform sampler2DArray moonImage;smooth in vec3 vMoonCoords;void main(void) { vFragColor = texture2DArray(moonImage, vMoonCoords.stp); }
转载地址:https://blog.csdn.net/qq_39574690/article/details/115585138 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2023年12月09日 06时02分37秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
周立功CAN通讯(txt格式) 报文解析
2019-03-28
Python+OpenCV教程3:打开摄像头
2019-03-28
Python的Serial串口通讯协议
2019-03-28
使用pyserial进行串口传输(实时绘图)
2019-03-28
用Python串口实时显示数据并绘图pyqtgraph(详细教程)
2019-03-28
Tkinter处理STM32串口发送的数据(self)
2019-03-28
Tkinter绘制简单的动画碰撞(动画显示)
2019-03-28
Python播放MP3音频文件
2019-03-28
python程序运行时间 Time
2019-03-28
详解 n 维向量、n 维数组 和 矩阵的维度(转载)
2019-03-28
matplotlib的animation模块动态显示数据
2019-03-28
CSDN文章发布方法
2019-03-28
数字逻辑电路期末复习与常见问题
2019-03-28
数据库系统概论期末复习
2019-03-28
电子学会机器人等级考试有什么用?
2019-03-28
无需编程的BEAM昆虫积木机器人~适合小孩子的益智DIY小制作
2019-03-28
带你轻松玩转神奇Micro:bit开发板的Max:Bot机器人!
2019-03-28
【备忘】MATLAB连接SQL教程
2019-03-28