着色器程序:vertex
1 #version 330 core 2 3 in vec2 _texCoord; 4 out vec4 color; 5 6 uniform sampler2D tex; 7 8 void main() 9 { 10 vec2 tc = vec2(_texCoord.x, 1-_texCoord.y); 11 color = texture(tex, tc); 12 //color = vec4(1.0f, 0.0f, 0.0f, 1.0f); 13 }
着色器程序:fregment
1 #include "App.h" 2 #include "EventWorkSpace.h" 3 #include <SOIL/SOIL.h> 4 5 class TextureTest : public EventWorkSpace 6 { 7 public: 8 GLuint vao; 9 GLuint vbo; 10 GLuint ebo; 11 Program prog; 12 GLuint tex; 13 14 void loopInit() 15 { 16 //着色器程序编译 17 prog.addShader(Program::ShaderType::VERTEX_SHADER, "glsl/texture.vert.glsl"); 18 prog.addShader(Program::ShaderType::FREGMENT_SHADER, "glsl/texture.freg.glsl"); 19 prog.link(); 20 //-- 21 22 //定点属性设置 23 GLfloat vertices[] = { 24 // 定点位置 // 纹理坐标 25 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 上右 26 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 下右 27 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // 下左 28 -0.5f, 0.5f, 0.0f, 0.0f, 1.0f // 上左 29 }; 30 GLuint indices[] = { 31 0, 1, 3, // 第一个三角形 32 1, 2, 3 // 第二个三角形 33 }; 34 35 glGenVertexArrays(1, &vao); 36 glBindVertexArray(vao); 37 glGenBuffers(1, &vbo); 38 glGenBuffers(1, &ebo); 39 glBindBuffer(GL_ARRAY_BUFFER, vbo); 40 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 41 42 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 43 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 44 45 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr); 46 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *)(3 * sizeof(GLfloat))); 47 glEnableVertexAttribArray(0); 48 glEnableVertexAttribArray(1); 49 glBindVertexArray(0); 50 // -- 51 52 // 纹理生成 53 glGenTextures(1, &tex); 54 glBindTexture(GL_TEXTURE_2D, tex); 55 56 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 59 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 60 61 int width, height; 62 unsigned char *image = SOIL_load_image("resources/smile.png", &width, &height, 0, SOIL_LOAD_RGB); 63 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); 64 glGenerateMipmap(GL_TEXTURE_2D); 65 SOIL_free_image_data(image); 66 glBindTexture(GL_TEXTURE_2D, 0); 67 //-- 68 69 glClearColor(0.6f, 0.6f, 0.6f, 1.0f); 70 } 71 void loopContent() 72 { 73 glClear(GL_COLOR_BUFFER_BIT); 74 75 glBindTexture(GL_TEXTURE_2D, tex); 76 77 prog.use(); 78 glBindVertexArray(vao); 79 80 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); 81 82 glBindVertexArray(0); 83 } 84 85 86 }; 87 88 int main() 89 { 90 App::init(480, 480, "texture rectangle", false, "window.settings"); 91 App::run(&TextureTest()); 92 return 0; 93 }
main
效果如下:
上面是一个简单个渲染方块并贴图的程序。
OpenGL初始化相关的在loopInit()函数内, 渲染相关的在loopContent()函数内。
上例中, 并没有使用glActiveTexture, 也没有向着色器程序中uniform sampler2D tex变量写入数据, 而纹理也能正常正常显示是因为OpenGL默认使用了GL_TEXTURE0这个纹理单元。GLSL中的tex变量也默认为0。
但是当我们要显示多个纹理时, 就要用到不同的纹理单元了。
OpenGL至少保证有16个纹理单元供你使用,也就是说你可以激活从GL_TEXTURE0到GL_TEXTRUE15。它们都是按顺序定义的,所以我们也可以通过GL_TEXTURE0 + 8的方式获得GL_TEXTURE8,这在当我们需要循环一些纹理单元的时候会很有用。 --learnopengl-cn.github.io
所以使用多个纹理的版本如下:
时间: 2024-10-13 17:53:56