OpenGL 3D旋轉的木箱


學習自:

https://learnopengl-cn.github.io/01%20Getting%20started/08%20Coordinate%20Systems/#3d

0,首先添加glm庫文件

相關方法可以參照我指定的那篇隨便

1,頂點着色器shader.vs

#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()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0f);
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

 

2,片段着色器shader.fs

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

// texture samplers
uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    // linearly interpolate between both textures (80% container, 20% awesomeface)
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

3,主程序

  1 #include <glad/glad.h>
  2 #include <GLFW/glfw3.h>
  3   
  4 #include <glm/glm.hpp>
  5 #include <glm/gtc/matrix_transform.hpp>
  6 #include <glm/gtc/type_ptr.hpp>
  7 
  8 #include "stb_image.h"
  9 #include "shader_s.h"
 10 #include <iostream>
 11 
 12 void framebuffer_size_callback(GLFWwindow* window, int width, int height);
 13 void processInput(GLFWwindow *window);
 14 
 15 // settings
 16 const unsigned int SCR_WIDTH = 800;
 17 const unsigned int SCR_HEIGHT = 600;
 18 
 19 int main()
 20 {
 21     // glfw: initialize and configure
 22     // ------------------------------
 23     glfwInit();
 24     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 25     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 26     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 27 
 28 #ifdef __APPLE__
 29     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
 30 #endif
 31 
 32     // glfw window creation
 33     // --------------------
 34     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
 35     if (window == NULL)
 36     {
 37         std::cout << "Failed to create GLFW window" << std::endl;
 38         glfwTerminate();
 39         return -1;
 40     }
 41     glfwMakeContextCurrent(window);
 42     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 43 
 44     // glad: load all OpenGL function pointers
 45     // ---------------------------------------
 46     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
 47     {
 48         std::cout << "Failed to initialize GLAD" << std::endl;
 49         return -1;
 50     }
 51 
 52     // configure global opengl state
 53     // -----------------------------
 54     glEnable(GL_DEPTH_TEST);
 55 
 56     // build and compile our shader zprogram
 57     // ------------------------------------
 58     Shader ourShader("../res/textures/texture.vs", "../res/textures/texture.fs");
 59 
 60     // set up vertex data (and buffer(s)) and configure vertex attributes
 61     // ------------------------------------------------------------------
 62     /*
 63     float vertices[] = {
 64         // 位置信息          // 顏色信息           // 紋理 coords
 65          0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // 右上
 66          0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // 右下
 67         -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // 左下
 68         -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // 左上
 69     };
 70     unsigned int indices[] = {
 71         0, 1, 3, // 第一個三角形
 72         1, 2, 3  // 第二個三角形
 73     };
 74     */
 75     float vertices[] = {
 76     -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
 77      0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
 78      0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
 79      0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
 80     -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
 81     -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
 82 
 83     -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
 84      0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
 85      0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
 86      0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
 87     -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
 88     -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
 89 
 90     -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
 91     -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
 92     -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
 93     -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
 94     -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
 95     -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
 96 
 97      0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
 98      0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
 99      0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
100      0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
101      0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
102      0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
103 
104     -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
105      0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
106      0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
107      0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
108     -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
109     -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
110 
111     -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
112      0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
113      0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
114      0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
115     -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
116     -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
117     };
118     
119     unsigned int VBO, VAO;
120     glGenVertexArrays(1, &VAO);
121     glGenBuffers(1, &VBO);
122 
123     glBindVertexArray(VAO);
124 
125     glBindBuffer(GL_ARRAY_BUFFER, VBO);
126     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
127 
128     // position attribute
129     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
130     glEnableVertexAttribArray(0);
131     // texture coord attribute
132     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
133     glEnableVertexAttribArray(1);
134 
135     //    加載並創建紋理
136     // -------------------------
137     unsigned int texture1, texture2;
138     //    第一張紋理
139 
140     glGenTextures(1, &texture1);
141     glBindTexture(GL_TEXTURE_2D, texture1);
142     //    為當前綁定的紋理對象設置環繞、過濾方式
143     //    將紋理包裝設置為GL_REPEAT(默認包裝方法)
144     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    
145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
146     //    設置紋理過濾參數
147     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
148     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
149     // 加載並生成紋理
150     int width, height, nrChannels;
151     stbi_set_flip_vertically_on_load(true); //告訴stb_image.h在y軸上翻轉加載的紋理。
152 
153     unsigned char *data = stbi_load("../res/textures/container.jpg", &width, &height, &nrChannels, 0);
154     if (data)
155     {
156         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
157         glGenerateMipmap(GL_TEXTURE_2D);
158     }
159     else
160     {
161         std::cout << "Failed to load texture" << std::endl;
162     }
163     stbi_image_free(data);
164 
165 
166     // texture 2
167     glGenTextures(1, &texture2);
168     glBindTexture(GL_TEXTURE_2D, texture2);
169     // set the texture wrapping parameters
170     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    // set texture wrapping to GL_REPEAT (default wrapping method)
171     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
172     // set texture filtering parameters
173     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
175     // load image, create texture and generate mipmaps
176     data = stbi_load("../res/textures/awesomeface.png", &width, &height, &nrChannels, 0);
177     if (data)
178     {
179         //請注意,awesomeface.png具有透明度,因此具有alpha通道,
180         //因此請務必告訴OpenGL數據類型為GL_RGBA        
181         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
182         glGenerateMipmap(GL_TEXTURE_2D);
183     }
184     else
185     {
186         std::cout << "Failed to load texture" << std::endl;
187     }
188     stbi_image_free(data);
189 
190     //告訴每個采樣器的opengl它屬於哪個紋理單元(只需要做一次)    
191     ourShader.use(); //激活着色器
192     // either set it manually like so:
193     glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
194     // or set it via the texture class
195     ourShader.setInt("texture2", 1);
196 
197 
198 
199     // render loop
200     // -----------
201     while (!glfwWindowShouldClose(window))
202     {
203         // input
204        // -----
205         processInput(window);
206 
207         // render
208         // ------
209         glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
210         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!
211 
212         // bind textures on corresponding texture units
213         glActiveTexture(GL_TEXTURE0);
214         glBindTexture(GL_TEXTURE_2D, texture1);
215         glActiveTexture(GL_TEXTURE1);
216         glBindTexture(GL_TEXTURE_2D, texture2);
217 
218         // activate shader
219         ourShader.use();
220 
221         // create transformations
222         glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
223         glm::mat4 view = glm::mat4(1.0f);
224         glm::mat4 projection = glm::mat4(1.0f);
225         model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f));
226         view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
227         projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
228         // retrieve the matrix uniform locations
229         unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
230         unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view");
231         // pass them to the shaders (3 different ways)
232         glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
233         glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
234         // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
235         ourShader.setMat4("projection", projection);
236 
237         // render box
238         glBindVertexArray(VAO);
239         glDrawArrays(GL_TRIANGLES, 0, 36);
240 
241 
242         // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
243         // -------------------------------------------------------------------------------
244         glfwSwapBuffers(window);
245         glfwPollEvents();
246     }
247 
248     // optional: de-allocate all resources once they've outlived their purpose:
249     // ------------------------------------------------------------------------
250     glDeleteVertexArrays(1, &VAO);
251     glDeleteBuffers(1, &VBO);
252     //glDeleteBuffers(1, &EBO);
253 
254     // glfw: terminate, clearing all previously allocated GLFW resources.
255     // ------------------------------------------------------------------
256     glfwTerminate();
257     return 0;
258 }
259 
260 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
261 // ---------------------------------------------------------------------------------------------------------
262 void processInput(GLFWwindow *window)
263 {
264     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
265         glfwSetWindowShouldClose(window, true);
266 }
267 
268 // glfw: whenever the window size changed (by OS or user resize) this callback function executes
269 // ---------------------------------------------------------------------------------------------
270 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
271 {
272     // make sure the viewport matches the new window dimensions; note that width and 
273     // height will be significantly larger than specified on retina displays.
274     glViewport(0, 0, width, height);
275 }
TestShader.cpp

注意一點的是,我們的着色器類,在這里要添加幾個方法,我去百度了一下,找到了常用的一些方法,把各個類型的的set函數都加進來了。

  1 #include "shader_s.h"
  2 
  3 Shader::Shader(const GLchar * vertexPath, const GLchar * fragmentPath)
  4 {
  5     // 1. 從文件路徑中獲取頂點/片段着色器
  6     std::string vertexCode;
  7     std::string fragmentCode;
  8     std::ifstream vShaderFile;
  9     std::ifstream fShaderFile;
 10     // 保證ifstream對象可以拋出異常:
 11     vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 12     fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 13     try
 14     {
 15         // 打開文件
 16         vShaderFile.open(vertexPath);
 17         fShaderFile.open(fragmentPath);
 18         std::stringstream vShaderStream, fShaderStream;
 19         // 讀取文件的緩沖內容到數據流中
 20         vShaderStream << vShaderFile.rdbuf();
 21         fShaderStream << fShaderFile.rdbuf();
 22         // 關閉文件處理器
 23         vShaderFile.close();
 24         fShaderFile.close();
 25         // 轉換數據流到string
 26         vertexCode = vShaderStream.str();
 27         fragmentCode = fShaderStream.str();
 28     }
 29     catch (std::ifstream::failure e)
 30     {
 31         std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
 32     }
 33     const char* vShaderCode = vertexCode.c_str();
 34     const char * fShaderCode = fragmentCode.c_str();
 35     // 2. 編譯着色器
 36     unsigned int vertex, fragment;
 37     // 頂點着色器    vs
 38     vertex = glCreateShader(GL_VERTEX_SHADER);
 39     glShaderSource(vertex, 1, &vShaderCode, NULL);
 40     glCompileShader(vertex);
 41     checkCompileErrors(vertex, "VERTEX");
 42     // 片段着色器    fs
 43     fragment = glCreateShader(GL_FRAGMENT_SHADER);
 44     glShaderSource(fragment, 1, &fShaderCode, NULL);
 45     glCompileShader(fragment);
 46     checkCompileErrors(fragment, "FRAGMENT");
 47     // 着色器程序
 48     ID = glCreateProgram();
 49     glAttachShader(ID, vertex);
 50     glAttachShader(ID, fragment);
 51     glLinkProgram(ID);
 52     checkCompileErrors(ID, "PROGRAM");
 53     // 刪除着色器,它們已經鏈接到我們的程序中了,已經不再需要了    glDeleteShader(vertex);
 54     glDeleteShader(fragment);
 55 }
 56 
 57 void Shader::use()
 58 {
 59     glUseProgram(ID);
 60 }
 61 
 62 void Shader::setBool(const std::string & name, bool value) const
 63 {
 64     glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
 65 }
 66 
 67 void Shader::setInt(const std::string & name, int value) const
 68 {
 69     glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
 70 }
 71 
 72 void Shader::setFloat(const std::string & name, float value) const
 73 {
 74     glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
 75 }
 76 
 77 void Shader::setVec2(const std::string & name, const glm::vec2 & value) const
 78 {
 79     glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
 80 }
 81 
 82 void Shader::setVec2(const std::string & name, float x, float y) const
 83 {
 84     glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
 85 }
 86 
 87 void Shader::setVec3(const std::string & name, const glm::vec3 & value) const
 88 {
 89     glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
 90 }
 91 
 92 void Shader::setVec3(const std::string & name, float x, float y, float z) const
 93 {
 94     glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
 95 }
 96 
 97 void Shader::setVec4(const std::string & name, const glm::vec4 & value) const
 98 {
 99     glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
100 }
101 
102 void Shader::setVec4(const std::string & name, float x, float y, float z, float w)
103 {
104     glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
105 }
106 
107 void Shader::setMat2(const std::string & name, const glm::mat2 & mat) const
108 {
109     glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
110 }
111 
112 void Shader::setMat3(const std::string & name, const glm::mat3 & mat) const
113 {
114     glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
115 }
116 
117 void Shader::setMat4(const std::string & name, const glm::mat4 & mat) const
118 {
119     glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
120 }
121 
122 void Shader::checkCompileErrors(unsigned int shader, std::string type)
123 {
124     int success;
125     char infoLog[1024];
126     if (type != "PROGRAM")
127     {
128         glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
129         if (!success)
130         {
131             glGetShaderInfoLog(shader, 1024, NULL, infoLog);
132             std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
133         }
134     }
135     else
136     {
137         glGetProgramiv(shader, GL_LINK_STATUS, &success);
138         if (!success)
139         {
140             glGetProgramInfoLog(shader, 1024, NULL, infoLog);
141             std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
142         }
143     }
144 }
shader_s.cpp

自己把相關的類定義寫道頭文件中就可以了。

4,運行結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM