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

时间:2019-11-28 08:23:21

标签: linux opengl

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

df.withColumn("rank", F.rank().over(Window.partitionBy("A", "B").orderBy("C")))

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

1)VBO(顶点缓冲对象)与VAO(顶点属性对象)之间的关系,我们基本上使用#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; } 内部的以下内容来定义它们:

CreateTriangles() function

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

...
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,
我认为这可能是错误的结果,但我不确定。

此外,该教程说,VBO绑定在VAO内,但是我看不到代码中有任何链接或任何与VBO关联到VAO的东西,所以我真的对如何将它们绑定在一起感到困惑,并且为什么在绘图阶段只绑定VAO而不绑定VBO?任何帮助和提示将不胜感激。提前致谢。

我正在使用Linux OS,并使用以下代码进行编译:

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;
    }

1 个答案:

答案 0 :(得分:0)

从上面的评论中,感谢@ Rabbid76:

当调用glVertexAttribPointer时,当前VBO的名称引用存储在当前VAO中。当前的VAO由glBindVertexArray(VAO)绑定;并且当前的VBO由glBindBuffer(GL_ARRAY_BUFFER,VBO);绑定。 glVertexAttribPointer将VBO关联到VAO中的资源索引0。该关联存储在VAO的状态向量中。因此,在绘制调用之前绑定VAO(glBindVertexArray(VAO))就足够了。因此,仅绑定VAO就足够了。

至于有关黑屏的注释中所述的问题,请尝试
更新问题版本和图形卡驱动器。如果无法更新提示,则只需设置glExperimental=GL_TRUE