gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 05:07:45 27 4
gpt4 key购买 nike

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

#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() 函数中的以下内容来定义它们:

...
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 的绑定(bind),但在 while 循环内的绘图调用期间:

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

我们只重新绑定(bind)VAO而不是VBO,我认为这可能是错误的结果,但我不确定。

另外,教程说 VBO 绑定(bind)在 VAO 内部,但我在代码中没有看到任何链接或任何将 VBO 与 VAO 相关的内容,所以我真的很困惑我们如何将它们绑定(bind)在一起,以及为什么我们在绘图阶段只绑定(bind)回 VAO 而不是 VBO?

我使用的是 Linux 操作系统,并使用以下内容进行编译:

g++ -std=c++17 main.cpp -o main -lGL -lGLEW -lglfw && ./main

最佳答案

根据上面的评论,归功于@Rabbid76:

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

至于评论中所说的黑屏问题试试
更新 glew 版本和显卡驱动器。如果无法更新 glew,则只需设置 glExperimental=GL_TRUE

关于linux - 在 openGL 中关联顶点缓冲区和顶点属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59084464/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com