zoukankan      html  css  js  c++  java
  • 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 << "
    " << infoLog << "
     -- --------------------------------------------------- -- " << 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 << "
    " << infoLog << "
     -- --------------------------------------------------- -- " << std::endl;
    142         }
    143     }
    144 }
    shader_s.cpp

    自己把相关的类定义写道头文件中就可以了。

    4,运行结果

  • 相关阅读:
    redis单机主从搭建
    zabbix监控rds
    zabbix_server表面启动成功,但是没有进程
    sysbench压测mysql
    使用gnuplot对tpcc-mysql压测结果生成图表
    tpcc-mysql的使用
    tpcc-mysql安装
    鼠标点击烟花爆炸效果
    css3背景自动变色代码
    js实现文本输入框的特效
  • 原文地址:https://www.cnblogs.com/icyhusky/p/10738530.html
Copyright © 2011-2022 走看看