glDrawArrays时的OpenGL异常

时间:2017-08-31 08:03:05

标签: c++ opengl graphics glsl shader

我试图在一个文件中渲染一个三角形,这样我就能理解openGL是如何工作的,所以我可以在创建引擎时使用它作为例子。在我创建着色器和VAO之前,该程序正常工作。例外情况说:“调用glDrawArrays()函数时,”内存位置的访问冲突:0x000000“。我的猜测是我搞砸了VAO。它也可能是着色器。提前感谢您的时间!

这是我的代码

#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include <string>
#include <fstream>

const std::string FILENAME = "src\\shaders\\basic";

static void error_callback(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void resize_callback(GLFWwindow* window, int width, int height);

static std::string LoadShader(const std::string& filename);
static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage);
static GLuint CreateShader(const std::string& text, GLenum shaderType);


int main()
{
    //Initalize GLFW
    if (!glfwInit())
    {
        //TODO: Failed to initialize GLFW
    }

    //Create window and store it to a handler
    GLFWwindow* window = glfwCreateWindow(1024, 768, "GL Noob Project", NULL, NULL);
    if (!window) 
    {
        //TODO: Failed to create window
    }

    glfwMakeContextCurrent(window); //Set the OpenGL context to our window
    glfwSwapInterval(1); //Set the buffer swap interval to 1

    //Initialize GLEW
    if (glewInit() != GLEW_OK) {
        //TODO Failed to initialize glew
    }

    //Set callbacks
    glfwSetErrorCallback(error_callback);
    glfwSetKeyCallback(window, key_callback);
    glfwSetFramebufferSizeCallback(window, resize_callback);

    //Shaders
    GLuint program;
    GLuint v_shader;
    GLuint f_shader;

    program = glCreateProgram();
    v_shader = CreateShader(LoadShader(FILENAME + ".vs"), GL_VERTEX_SHADER);
    f_shader = CreateShader(LoadShader(FILENAME + ".fs"), GL_FRAGMENT_SHADER);

    glBindAttribLocation(program, 0, "position");

    glAttachShader(program, v_shader);
    glAttachShader(program, f_shader);

    glLinkProgram(program);
    CheckShaderError(program, GL_LINK_STATUS, true, "Shader Error");

    glValidateProgram(program);
    CheckShaderError(program, GL_VALIDATE_STATUS, true, "Shader Error");

    glUseProgram(program);

    //CREATE VAO
    static const GLfloat data[] = { 0.0, 0.0, 0.0,
                                0.0, 0.0, 0.0,
                                0.0, 0.0, 0.0 };
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, sizeof(data), GL_FLOAT, GL_FALSE, 0, 0);

    while (!glfwWindowShouldClose(window)) //While there is no close flag
    { 
        //DRAW
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);


        glfwSwapBuffers(window); //Swap front and back buffer
        glfwPollEvents(); //Get events
    }

    glDetachShader(program, v_shader);
    glDeleteShader(v_shader);
    glDetachShader(program, f_shader);
    glDeleteShader(f_shader);
    glDeleteProgram(program);
    glfwDestroyWindow(window); //Destroy window
    glfwTerminate(); //Terminate GLFW

    return 0;
} 

//CALLBACK FUNCTIONS

//Error callback
static void error_callback(int error, const char* description) {
    std::cerr << "Error: " << description << std::endl;
}
//Key callback
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    glfwSetWindowShouldClose(window, GLFW_TRUE);
}

static void resize_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}


//SHADER FUNCTIONS
static std::string LoadShader(const std::string& filename) {
    std::ifstream file;
    file.open(filename.c_str());

    std::string output;
    std::string line;

    if (file.is_open())
    {
        while (file.good())
        {
            getline(file, line);
            output.append(line + "\n");
        }
    }
    else {
        std::cerr << "Unable to load shader from file: "<< filename << std::endl;
    }

    return output;
}



static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
{
    GLint success = 0;
    GLchar error[1024] = { 0 };

    if (isProgram)
        glGetProgramiv(shader, flag, &success);
    else
        glGetShaderiv(shader, flag, &success);

    if (success == GL_FALSE)
    {
        if (isProgram)
            glGetProgramInfoLog(shader, sizeof(error), NULL, error);
        else
            glGetShaderInfoLog(shader, sizeof(error), NULL, error);

        std::cerr << errorMessage << ": " << error << std::endl;
    }
}

static GLuint CreateShader(const std::string& text, GLenum shaderType)
{
    GLuint shader = glCreateShader(shaderType);
    if (shader == 0) std::cerr << "Error: shader creation failed" << std::endl;
    const GLchar* shaderSourceString = text.c_str();
    const GLint shaderSourceStringLength = text.length();
    glShaderSource(shader, 1, &shaderSourceString, &shaderSourceStringLength);
    glCompileShader(shader);
    CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error: shader compilation Failed");
    return shader;
}   

这里是着色器文件(我的猜测是我在这里搞砸了一些东西)

顶点着色器:

#version 330 core

layout(location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(position, 1.0);
}

Fragment Shader:

#version 330 core
out vec4 color;

void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
}

0 个答案:

没有答案