开发者社区> 问答> 正文

在openGL中关联顶点缓冲区和顶点属性

我应该在屏幕上绘制三角形的整个代码是:

#include <iostream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <string.h>


const GLint WIDTH=800, HEIGHT=600;
GLuint VAO, VBO, shader;

//Vertex Shader
/*static const char**/
const GLchar* vShader = "\n"
"\n"
"#version 330 \n"
"layout (location=0) in vec3 pos;\n"
"void main(){\n"
"gl_Position = vec4(pos.x,pos.y,pos.z,1.0);\n"
"\n"
"}\n"
"";

// fragment shader
const GLchar* fShader = "\n"
"#version 330 \n"
"out vec4 colour;\n"
"void main(){\n"
"colour = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n"
"\n"
"\n";

void CreateTriangle(){
    GLfloat vertices[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    };

    // vertex arrays
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    // vertex buffers
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);

        glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*9,vertices,GL_STATIC_DRAW);

        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0);
        glEnableVertexAttribArray(0);

     glBindBuffer(GL_ARRAY_BUFFER, 0);
     glBindVertexArray(0);
}

void AddShader(GLuint theProgram, const GLchar* shaderCode, GLenum shaderType){
    GLuint theShader = glCreateShader(shaderType);

    const GLchar* theCode[1];
    theCode[0] = shaderCode;

    GLint codeLength[1];
    codeLength[0] = strlen(shaderCode);

    glShaderSource(theShader, 1, theCode, codeLength);
    glCompileShader(theShader);

    GLint result=0;
    GLchar eLog[1024]={};

    glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
    if(!result){
        glGetShaderInfoLog(theShader,sizeof(eLog),NULL, eLog);
        std::cout<< "Error compiling"<<shaderType<<" "<<eLog <<std::endl;
        return;
    }

    glAttachShader(theProgram,theShader);

}

void CompileShader(){
    shader = glCreateProgram();

    if(!shader){
        std::cout<<"Error Creating Shader Program";
        return;
    }

    AddShader(shader, vShader,GL_VERTEX_SHADER);
    AddShader(shader, fShader,GL_FRAGMENT_SHADER);

    // getting error codes
    GLint result=0;
    GLchar eLog[1024]={0};

    // Creates the executables in the graphic card
    glLinkProgram(shader);

    // get information if program is linked properly
    glGetProgramiv(shader, GL_LINK_STATUS, &result);
    if(!result){
        glGetProgramInfoLog(shader,sizeof(eLog),NULL,eLog);
        std::cout<<"Error linking program"<<eLog<<std::endl;
        return;
    }

    glValidateProgram(shader);
    glGetProgramiv(shader,GL_VALIDATE_STATUS,&result);
    if(!result){
        glGetProgramInfoLog(shader, sizeof(eLog),NULL, eLog);
        std::cout<<"Error validating program"<<eLog<<std::endl;
        return;
    }

}

int main(void){
    if(!glfwInit()){
        std::cout << "glfw initialization failed" << std::endl;
        glfwTerminate();
        return 1;
    }

    // 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);

    GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "NEW WINDOW", NULL, NULL);

    if(!mainWindow){
        std::cout<< "Window creation failed" <<std::endl;
        glfwTerminate();
        return 1;
    }


    int bufferWidth, bufferHeight;
    glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);

    glfwMakeContextCurrent(mainWindow);

    if(glewInit() != GLEW_OK){
        std::cout << "GLEW Initialization failed" << std::endl;
        glfwDestroyWindow(mainWindow);
        glfwTerminate();
        return 1;
    }

    glViewport(0,0,bufferWidth, bufferHeight);

    CreateTriangle();
    CompileShader();

    while(!glfwWindowShouldClose(mainWindow)){
        glfwPollEvents();
        glUseProgram(shader);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindVertexArray(VAO);
                glDrawArrays(GL_TRIANGLES,0,3);
        glBindVertexArray(0);
        glUseProgram(0);
        glfwSwapBuffers(mainWindow);
        std::cout<<"something"<<std::endl;
    }

    return 0;

}

它本质上会绘制一个黑屏,并且没有任何错误,但是应该绘制一个红色三角形,因此我正在尝试调试此代码,并且代码中本质上有些部分我不理解

1)VBO(顶点缓冲对象)与VAO(顶点属性对象)有什么关系,我们基本上使用以下内容定义了它们CreateTriangles() function:

...

glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    // vertex buffers
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);

        glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*9,vertices,GL_STATIC_DRAW);

        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0);
        glEnableVertexAttribArray(0);

     glBindBuffer(GL_ARRAY_BUFFER, 0);
     glBindVertexArray(0);
 ...

请注意,我们已经取消了VAO和VBO的绑定,但是在while循环内进行绘图调用期间

展开
收起
祖安文状元 2020-01-16 17:42:14 462 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载