代码之家  ›  专栏  ›  技术社区  ›  questions

Opengl 3D立方体无法在Windows上正确渲染

  •  0
  • questions  · 技术社区  · 7 年前

    the rendered cube

    代码如下:

    着色器。h:

    #ifndef SHADER_H
    #define SHADER_H
    
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <iostream>
    
    #include <GL/glew.h>
    
    class Shader
    {
    public:
        GLuint Program;
        // Constructor generates the shader on the fly
        Shader(const GLchar *vertexPath, const GLchar *fragmentPath)
        {
            // 1. Retrieve the vertex/fragment source code from filePath
            std::string vertexCode;
            std::string fragmentCode;
            std::ifstream vShaderFile;
            std::ifstream fShaderFile;
            // ensures ifstream objects can throw exceptions:
            vShaderFile.exceptions(std::ifstream::badbit);
            fShaderFile.exceptions(std::ifstream::badbit);
            try
            {
                // Open files
                vShaderFile.open(vertexPath);
                fShaderFile.open(fragmentPath);
                std::stringstream vShaderStream, fShaderStream;
                // Read file's buffer contents into streams
                vShaderStream << vShaderFile.rdbuf();
                fShaderStream << fShaderFile.rdbuf();
                // close file handlers
                vShaderFile.close();
                fShaderFile.close();
                // Convert stream into string
                vertexCode = vShaderStream.str();
                fragmentCode = fShaderStream.str();
            }
            catch (std::ifstream::failure e)
            {
                std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
            }
            const GLchar *vShaderCode = vertexCode.c_str();
            const GLchar *fShaderCode = fragmentCode.c_str();
            // 2. Compile shaders
            GLuint vertex, fragment;
            GLint success;
            GLchar infoLog[512];
            // Vertex Shader
            vertex = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertex, 1, &vShaderCode, NULL);
            glCompileShader(vertex);
            // Print compile errors if any
            glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
            if (!success)
            {
                glGetShaderInfoLog(vertex, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
            }
            // Fragment Shader
            fragment = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragment, 1, &fShaderCode, NULL);
            glCompileShader(fragment);
            // Print compile errors if any
            glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
            if (!success)
            {
                glGetShaderInfoLog(fragment, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
            }
            // Shader Program
            this->Program = glCreateProgram();
            glAttachShader(this->Program, vertex);
            glAttachShader(this->Program, fragment);
            glLinkProgram(this->Program);
            // Print linking errors if any
            glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
            if (!success)
            {
                glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
            }
            // Delete the shaders as they're linked into our program now and no longer necessery
            glDeleteShader(vertex);
            glDeleteShader(fragment);
    
        }
        // Uses the current shader
        void Use()
        {
            glUseProgram(this->Program);
        }
    };
    
    #endif
    

    #version 330 core
    in vec2 TexCoord;
    
    out vec4 color;
    
    uniform sampler2D ourTexture1;
    
    void main()
    {
        color = texture(ourTexture1, TexCoord);
    }
    

    果心vs:

    #version 330 core
    layout (location = 0) in vec3 position;
    layout (location = 2) in vec2 texCoord;
    
    out vec2 TexCoord;
    
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    void main()
    {
        gl_Position = projection * view * model * vec4(position, 1.0f);
        TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
    }
    

    #include <iostream>
    
    // GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    
    // GLFW
    #include <GLFW/glfw3.h>
    
    // Other Libs
    #include "SOIL2/SOIL2.h"
    
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    
    // Other includes
    #include "Shader.h"
    
    // Window dimensions
    const GLuint WIDTH = 800, HEIGHT = 600;
    
    // The MAIN function, from here we start the application and run the game loop
    int main()
    {
        // Init GLFW
        glfwInit();
    
        // Set all the required options for GLFW
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
        // Create a GLFWwindow object that we can use for GLFW's functions
        GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
    
        int screenWidth, screenHeight;
        glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
    
        if (nullptr == window)
        {
            std::cout << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
    
            return EXIT_FAILURE;
        }
    
        glfwMakeContextCurrent(window);
    
        // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
        glewExperimental = GL_TRUE;
        // Initialize GLEW to setup the OpenGL Function pointers
        if (GLEW_OK != glewInit())
        {
            std::cout << "Failed to initialize GLEW" << std::endl;
            return EXIT_FAILURE;
        }
    
        // Define the viewport dimensions
        glViewport(0, 0, screenWidth, screenHeight);
    
        glEnable(GL_DEPTH_TEST);
        // enable alpha support
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//enables jpegs and alphas
    
        // Build and compile our shader program
        Shader ourShader("res/shaders/core.vs", "res/shaders/core.frag");
    
        // use with Perspective Projection
        GLfloat vertices[] = {
            //x     y       z      normalized texture coordinates 
            -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,
    
            -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,
    
            -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,
    
            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,
    
            -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,
    
            -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
        };
    
        GLuint VBO, VAO;//Vertex Buffer Object, Vertex Array Object
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
    
        // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        // Position attribute
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)0);
        glEnableVertexAttribArray(0);
        // TexCoord attribute
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat)));
        glEnableVertexAttribArray(2);
    
        glBindVertexArray(0); // Unbind VAO
    
        // Load and create a texture
        GLuint texture;
    
        int width, height;
    
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        // Set our texture parameters
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // Set texture filtering
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        // Load, create texture and generate mipmaps
        unsigned char *image = SOIL_load_image("res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
        glGenerateMipmap(GL_TEXTURE_2D);
        SOIL_free_image_data(image);
        glBindTexture(GL_TEXTURE_2D, 0);
    
    
        glm::mat4 projection;
        projection = glm::perspective(45.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 0.1f, 1000.0f); 
    
        // Game loop
        while (!glfwWindowShouldClose(window))
        {
            // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
            glfwPollEvents();
    
            // Render
            // Clear the colorbuffer
            glClearColor(0.9f, 0.5f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texture);
            glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture"), 0);
            ourShader.Use();
    
            glm::mat4 model;
            glm::mat4 view;
            model = glm::rotate(model, (GLfloat)glfwGetTime() * 1.0f, glm::vec3(0.5f, 1.0f, 0.0f));
            view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
    
            GLint modelLoc = glGetUniformLocation(ourShader.Program, "model");
            GLint viewLoc = glGetUniformLocation(ourShader.Program, "view");
            GLint projLoc = glGetUniformLocation(ourShader.Program, "projection");
    
            glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
            glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
            glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
    
            glBindVertexArray(VAO);
            glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);
    
            // Swap the screen buffers
            glfwSwapBuffers(window);
        }    
    
        // Properly de-allocate all resources once they've outlived their purpose
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    
        // Terminate GLFW, clearing any resources allocated by GLFW.
        glfwTerminate();
    
        return EXIT_SUCCESS;
    }
    
    2 回复  |  直到 5 年前
        1
  •  5
  •   Rabbid76    7 年前

    在片段着色器中,纹理采样器uniform的名称为 "ourTexture1"

    uniform sampler2D ourTexture1;
    

    但是,当您尝试获取纹理采样器统一的位置时,您使用了名称 "ourTexture"

    glGetUniformLocation(ourShader.Program, "ourTexture")
    


    第二个问题是,将纹理采样器设置为均匀 ourTexture1 在程序成为当前渲染状态的一部分之前。

    glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture"), 0);
    ourShader.Use();
    

    可以检索制服的位置( glGetUniformLocation )程序链接后的任何时间( glLinkProgram

    glLinkProgram( ourShader.Program );
    
    GLint modelLoc = glGetUniformLocation( ourShader.Program, "model" );
    GLint viewLoc  = glGetUniformLocation( ourShader.Program, "view" );
    GLint projLoc  = glGetUniformLocation( ourShader.Program, "projection" );
    GLint texLoc   = glGetUniformLocation( ourShader.Program, "ourTexture1" );
    

    glUniform glUseProgram ).

    glUseProgram( ourShader.Program );
    
    glUniformMatrix4fv( modelLoc, 1, GL_FALSE, glm::value_ptr(model) );
    glUniformMatrix4fv( viewLoc, 1, GL_FALSE, glm::value_ptr(view) );
    glUniformMatrix4fv( projLoc, 1, GL_FALSE, glm::value_ptr(projection) );
    glUniform1i( texLoc, 0 );
    
        2
  •  2
  •   user755921 user755921    7 年前

    在激活着色器之前,您正在着色器上设置统一,这似乎是错误的。