Opengl 3.3并没有任何吸引力。使用GLSL 330 Core

时间:2015-03-29 23:31:07

标签: c++ opengl shader

我正在关注this site的指南并停止了第2课。起初我尝试了自己的代码但是在它没有工作之后我只是从网站上获取了代码。除了glClearColor之外,它仍然没有画任何东西。

我做了什么:

  1. 检查编译和链接。工作正常
  2. 检查错误。不确定我是否做得对,但似乎一切都没问题(我得到1280错误,但我已经读过GLEW会导致它并且可以忽略它)。
  3. glUseProgram移至主循环但未获得任何结果。
  4. 更改颜色并尝试修改着色器。仍然没有
  5. 我将发布我目前的代码(网站上的原始代码):

    的main.cpp

    #include <stdio.h>
    #include <stdlib.h>
    #include <glew.h>
    #include <glfw3.h>
    #include <glm/glm.hpp>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    
    
    int max(int i, int j)
    {
        if (i > j) return i;
        return j;
    }
    
    
    GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
    
        // Create the shaders
        GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    
        // Read the Vertex Shader code from the file
        std::string VertexShaderCode;
        std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
        if (VertexShaderStream.is_open())
        {
            std::string Line = "";
            while (getline(VertexShaderStream, Line))
                VertexShaderCode += "\n" + Line;
            VertexShaderStream.close();
        }
    
        // Read the Fragment Shader code from the file
        std::string FragmentShaderCode;
        std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
        if (FragmentShaderStream.is_open()){
            std::string Line = "";
            while (getline(FragmentShaderStream, Line))
                FragmentShaderCode += "\n" + Line;
            FragmentShaderStream.close();
        }
    
        GLint Result = GL_FALSE;
        int InfoLogLength;
    
        // Compile Vertex Shader
        printf("Compiling shader : %s\n", vertex_file_path);
        char const * VertexSourcePointer = VertexShaderCode.c_str();
        glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
        glCompileShader(VertexShaderID);
    
        // Check Vertex Shader
        glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> VertexShaderErrorMessage(InfoLogLength);
        glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
    
        // Compile Fragment Shader
        printf("Compiling shader : %s\n", fragment_file_path);
        char const * FragmentSourcePointer = FragmentShaderCode.c_str();
        glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
        glCompileShader(FragmentShaderID);
    
        // Check Fragment Shader
        glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
    
        // Link the program
        fprintf(stdout, "Linking program\n\n");
        GLuint ProgramID = glCreateProgram();
        glAttachShader(ProgramID, VertexShaderID);
        glAttachShader(ProgramID, FragmentShaderID);
        glLinkProgram(ProgramID);
    
    
        // Check the program
        glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
        glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> ProgramErrorMessage(max(InfoLogLength, int(1)));
        std::cout << "Checking program\n";
    
        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
        fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
        glDeleteShader(VertexShaderID);
        glDeleteShader(FragmentShaderID);
        std::cout << "END";
    
        return ProgramID;
    }
    
    
    int main(void)
    {
        if (!glfwInit())
        {
            std::cout << "Cannot init glfw";
            return -1;
        }
    
        //glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL 
    
    
    
        // Open a window and create its OpenGL context 
        GLFWwindow* window; // (In the accompanying source code, this variable is global) 
        window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
        if (window == NULL){
            fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window); // Initialize GLEW 
        glewExperimental = GL_TRUE; // Needed in core profile 
        if (glewInit() != GLEW_OK) {
            fprintf(stderr, "Failed to initialize GLEW\n");
            return -1;
        }
    
        // Ensure we can capture the escape key being pressed below
        glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    
    
        // This will identify our vertex buffer
        GLuint vertexbuffer;
    
        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &vertexbuffer);
    
        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    
        // Give our vertices to OpenGL.
        static const GLfloat g_vertex_buffer_data[] = {
            -1.0f, -1.0f, 0.0f,
            1.0f, -1.0f, 0.0f,
            0.0f, 1.0f, 0.0f
        };
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    
        glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
        GLuint programID = LoadShaders("res\\vertex.glsl", "res\\fragment.glsl");
    
        do{
    
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glUseProgram(programID);
    
            glEnableVertexAttribArray(0);
            glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
            glVertexAttribPointer(
                0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                3,                  // size
                GL_FLOAT,           // type
                GL_FALSE,           // normalized?
                0,                  // stride
                (void*)0            // array buffer offset
                );
    
            // Draw the triangle !
            glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
    
            glDisableVertexAttribArray(0);
    
            // Swap buffers
            glfwSwapBuffers(window);
            glfwPollEvents();
    
    
        } // Check if the ESC key was pressed or the window was closed
        while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);
    
        return 0;
    }
    

    fragment.glsl

    #version 330 core
    out vec3 color;
    
    void main(){
        color = vec3(1,1,0);
    }
    

    vertex.glsl

    #version 330 core
    
    layout(location = 0) in vec3 vertexPosition_modelspace;
    void main(){
    gl_Position.xyz = vertexPosition_modelspace;
        gl_Position.w = 1.0;
     }
    

1 个答案:

答案 0 :(得分:5)

OpenGL核心配置文件需要使用顶点阵列对象(VAO)。这是规范的“弃用和删除的功能”:

  

客户端顶点和索引数组 - 所有顶点数组属性和元素数组索引指针必须引用缓冲区对象。默认的顶点数组对象(名称为零)也不推荐使用。在没有绑定缓冲区对象或没有绑定顶点数组对象时调用VertexAttribPointer将生成INVALID_OPERATION错误,在没有绑定顶点数组对象时调用任何数组绘制命令。

您正在使用的教程建议在初始化过程中使用此代码:

GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

这足以让教程代码正常工作。为了在更复杂的应用程序中高效地使用VAO,您可能希望为每个对象创建VAO。然后,这将跟踪对象的完整顶点设置状态,并允许您在绘制之前使用单个glBindVertexArray()调用设置状态。