OpenGL立方体贴图(5)
1立方体,需要将空间坐标转换为人眼坐标,所以需要一系列的矩阵运算;需要用到glm;请自行安装
2 本次直接使用RGB贴图
3立方体贴图中的每一个纹理图(正方体贴图),RGB图片也要是正方形的
4 介绍一个中文OpenGL学习网站 http://learnopengl.com
5 立方体贴相当于在不同的坐标位置(这里用到了Z轴),分别做一个正方形贴图;正方形的顶点顺序一定要按照坐标轴的逆时针方向画三角形的顶点(图有点乱,但是是为了展示每个面的坐标轴,以及每个三角形的顶点方向;)
6 顶点着色器中,顶点位置,要转换成你的人眼坐标系的位置;涉及到MVP矩阵,用于旋转,平移,投影映射的矩阵
7 立方体六个面,六张图,每张图有自己的纹理采样器;这里并没有使用cubemap;而是直接用的六张2D纹理,你熟悉了这个立方体贴图,cubemap也就同理;
8本例中建立顶点数组的时候,顶点坐标的的中心是(0,0,0);也就是这个正方体本质是以坐标中心为中心的一个立方体;
9 注意,绑定一个纹理ID,就给他设置好平滑过滤方式,并且将数据加载到显存,不要生成完全部的2D纹理ID,再去glTexImage2D加载6张图片,都不知道要把图片给哪个纹理ID了;
10 采样器的序号要与激活的纹理序号对应
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tesarr[0]);
glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);
11 MVP
模型,视图,投影
glm::mat4 model = glm::mat4(1.0f); 定义一个4*4 的单位矩阵
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(70.0f), glm::vec3(.0f, 1.0f, 1.0f));//沿着某个向量方向旋转,以这个向量为中心轴线
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));//沿着某个方向平移
projection = glm::perspective((float)30.0f, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 10.0f);//设置视角等
glm::radians() 角度制转弧度制,可应用于glm::rotate()中。 glm::translate() 返回一个平移矩阵,第一个参数是目标矩阵,第二个参数是平移的方向向量。 glm::rotate() 返回一个将点绕某个轴逆时针旋转一定弧度的旋转矩阵,第一个参数是目标矩阵,第二个参数是弧度,第三个参数是旋转轴。 glm::scale() 返回一个缩放矩阵,第一个参数是目标矩阵,第二个参数是在各坐标轴上的缩放系数。 glm::ortho(float left, float right, float bottom, float top, float zNear, float zFar); 正交投影矩阵。前四个参数分别是视口的左、右、上、下坐标。第五和第六个参数则定义了近平面和远平面的距离。 glm::perspective(float fovy, float aspect, float zNear, float zFar); 透视投影矩阵。第一个参数为视锥上下面之间的夹角,第二个参数为视口宽高比,第三、四个参数分别为近平面和远平面的深度。 glm::value_ptr() 传入一个矩阵,返回一个数组,从左到右按列优先。 glm::normalize(vector) 向量的单位化(保持其方向不变,将其长度化为1). --------------------------------------------------------------------- 链接:https://www.jianshu.com/p/7bbe387109ea 来源:简书
12 代码:参考 OpenGL立方体纹理贴图_LV小猪精的博客-CSDN博客
// Win32GL1.cpp : 定义应用程序的入口点。 #include "stdafx.h" #include <glad/glad.h> #include <GLFW/glfw3.h> #include<string> #include<fstream> #include<sstream> #include<iostream> #include<stdio.h> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include <learnopengl/shader_m.h> const unsigned int SCR_WIDTH = 700; const unsigned int SCR_HEIGHT = 900; unsigned int VBO[6] ; unsigned int VAO[6] ; unsigned int texturePIC = 0; int shaderProgram = 0; unsigned int tesarr[6] = {99}; void LoadPicture() { glGenTextures(6, tesarr); //------------------------------每一块的纹理ID绑定与数据加载,要写在一起-------------------------------- glBindTexture(GL_TEXTURE_2D, tesarr[0]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //stbi是一个图片载入的开源组件,文件名,宽高,通道数,你期望的通道数 int W, H, desired_channels ; unsigned char* data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); //------------------------------------------------------------- //图2 glBindTexture(GL_TEXTURE_2D, tesarr[1]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); //3 glBindTexture(GL_TEXTURE_2D, tesarr[2]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); //4 glBindTexture(GL_TEXTURE_2D, tesarr[3]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); //5 glBindTexture(GL_TEXTURE_2D, tesarr[4]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); //6 glBindTexture(GL_TEXTURE_2D, tesarr[5]); //为bind的纹理设置环绕,过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); data = stbi_load("./front.jpg", &W, &H, &desired_channels, 0); if (data) { //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //生成mipmap数组 glGenerateMipmap(GL_TEXTURE_2D); } stbi_image_free(data); glUseProgram(shaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tesarr[0]); glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tesarr[1]); glUniform1i(glGetUniformLocation(shaderProgram, "texture2"), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, tesarr[2]); glUniform1i(glGetUniformLocation(shaderProgram, "texture3"), 2); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, tesarr[3]); glUniform1i(glGetUniformLocation(shaderProgram, "texture4"), 3); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, tesarr[4]); glUniform1i(glGetUniformLocation(shaderProgram, "texture5"), 4); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, tesarr[5]); glUniform1i(glGetUniformLocation(shaderProgram, "texture6"), 5); glUseProgram(shaderProgram); } void render() { // glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); //沿着某轴旋转 model = glm::rotate(model, glm::radians(70.0f), glm::vec3(.0f, 1.0f, 1.0f)); //沿着Z轴平移 view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); //设置视角 projection = glm::perspective((float)30.0f, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 10.0f); // retrieve the matrix uniform locations unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model"); unsigned int viewLoc = glGetUniformLocation(shaderProgram, "view"); // pass them to the shaders (3 different ways) glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &projection[0][0]); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 1); glBindVertexArray(VAO[0]); glDrawArrays(GL_TRIANGLES,0,6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 2); glBindVertexArray(VAO[1]); glDrawArrays(GL_TRIANGLES, 0, 6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 3); glBindVertexArray(VAO[2]); glDrawArrays(GL_TRIANGLES, 0, 6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 4); glBindVertexArray(VAO[3]); glDrawArrays(GL_TRIANGLES, 0, 6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"),5); glBindVertexArray(VAO[4]); glDrawArrays(GL_TRIANGLES, 0, 6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 6); glBindVertexArray(VAO[5]); glDrawArrays(GL_TRIANGLES, 0, 6);//6个面,每个面画两个三角形(6个点);6*6 glGetError(); } void initmodule() { //注意:画正面逆时针012-230;三角形顺序一定不能乱 // //第一个面的 顶点和纹理 后面 float vertices0[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f }; //前面 float vertices1[] = { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f }; //左面 float vertices2[] = { -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f }; //右面 float vertices3[] = { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f }; //下面 float vertices4[] = { -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f }; //上面 float vertices5[] = { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; //做VAO VBo glGenVertexArrays(6,VAO); glGenBuffers(6, VBO); glBindVertexArray(VAO[0]); glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices0), vertices0, GL_STATIC_DRAW); //设置第0个锚点,3个点,不需要归一化,跨度5个float可以读下一个点 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(VAO[1]); glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(VAO[2]); glBindBuffer(GL_ARRAY_BUFFER, VBO[2]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(VAO[3]); glBindBuffer(GL_ARRAY_BUFFER, VBO[3]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices3), vertices3, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(VAO[4]); glBindBuffer(GL_ARRAY_BUFFER, VBO[4]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices4), vertices4, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(VAO[5]); glBindBuffer(GL_ARRAY_BUFFER, VBO[5]); //创建显存空间 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices5), vertices5, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); //设置纹理图片 //加载纹理图片,生成纹理 LoadPicture(); } void initshader(const char* verpath,const char* fragpath) { //编译shader,并记录shaderID std::string VerCode(""); std::string fregCode(""); //读文件 std::ifstream vShaderFile; std::ifstream fShaderFile; vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { vShaderFile.open(verpath); fShaderFile.open(fragpath); std::stringstream vsstream, fsstream; vsstream << vShaderFile.rdbuf(); fsstream << fShaderFile.rdbuf(); VerCode = vsstream.str(); fregCode = fsstream.str(); } catch (const std::exception&) { std::cout << "read file error" << std::endl; } const char* vshader = VerCode.c_str(); const char* fshader = fregCode.c_str(); //shader 编译连接 unsigned int vertexID = 0, fragID = 0; char infoLog[512];//存储错误信息 int successflag = 0; vertexID = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexID,1,&vshader,NULL ); glCompileShader(vertexID); //获取编译是否成功 glGetShaderiv(vertexID,GL_COMPILE_STATUS,&successflag); if (!successflag) { glGetShaderInfoLog(vertexID,512,NULL,infoLog); std::string errstr(infoLog); std::cout << "v shader err"<<infoLog; } //frag fragID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragID, 1, &fshader, NULL); glCompileShader(fragID); //获取编译是否成功 glGetShaderiv(fragID, GL_COMPILE_STATUS, &successflag); if (!successflag) { glGetShaderInfoLog(fragID, 512, NULL, infoLog); std::string errstr(infoLog); std::cout << "f shader err"<<infoLog; } //链接 shaderProgram = glCreateProgram(); glAttachShader(shaderProgram,vertexID); glAttachShader(shaderProgram,fragID); //glBindAttribLocation(shaderProgram, 0, "aPos"); //glBindAttribLocation(shaderProgram, 1, "aTexCoord"); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram,GL_LINK_STATUS,&successflag); if (!successflag) { glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog); std::string errstr(infoLog); std::cout << "link error"; } //编译完成后,可以把中间的步骤程序删除 glDeleteShader(vertexID); glDeleteShader(fragID); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { //将窗口设置为关闭,跳出循环 glfwSetWindowShouldClose(window, true); } } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } int main() { //glfw初始化 glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //glfw创建窗口 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { printf("创建窗口失败"); //终止 glfwTerminate(); return -1; } //显示窗口 glfwMakeContextCurrent(window); //设置回调,当窗口大小调整后将调用该回调函数 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // glad初始化 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("加载失败"); return -1; } glEnable(GL_DEPTH_TEST); initshader("./vertexShader.glsl", "./fragmentShader.glsl");//先编译着色器 initmodule(); // 使用循环达到循环渲染效果 while (!glfwWindowShouldClose(window)) { //自定义输入事件 processInput(window); glClearColor(0.0f,0.3f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); render(); //交互缓冲区,否则显示空白 glfwSwapBuffers(window); //输入输出事件,否则无法对窗口进行交互 glfwPollEvents(); } glDeleteVertexArrays(6, VAO); glDeleteBuffers(6, VBO); //终止渲染 关闭并清理glfw本地资源 glfwTerminate(); return 0; }
#version 330 core out vec4 FragColor; in vec2 TexCoord; uniform int mixValue; // texture samplers uniform sampler2D texture1; uniform sampler2D texture2; uniform sampler2D texture3; uniform sampler2D texture4; uniform sampler2D texture5; uniform sampler2D texture6; void main() { if(mixValue==1) FragColor = texture(texture1, TexCoord); else if(mixValue==2) FragColor = texture(texture2, TexCoord); else if(mixValue==3) FragColor = texture(texture3, TexCoord); else if(mixValue==4) FragColor = texture(texture4, TexCoord); else if(mixValue==5) FragColor = texture(texture5, TexCoord); else FragColor = texture(texture6, TexCoord); }
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { //将物体的空间坐标,转换到人眼坐标,位置数据*MVP gl_Position = projection * view * model * vec4(aPos, 1.0); TexCoord = vec2(aTexCoord.x, aTexCoord.y); }
13结果:
14 如果你不想自己编译着色器代码,可以去learnOpenGL下载shader_m.h 这里边会给你集成好编译的相关事宜;GitHub上有learnOpenGL的源代码,内部有一些可以节省你工作量的高度集成的接口;相机,shader之类的;本例子中严格来说并没有用到#include<learnopengl/shader_m.h>;
15 如果你的顶点,或者三角形的顺序是错的会怎么样?
16 不开深度测试会怎么样?
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~