打开 GL ES 2.0 为啥我的 VBO 不工作?
Posted
技术标签:
【中文标题】打开 GL ES 2.0 为啥我的 VBO 不工作?【英文标题】:Open GL ES 2.0 Why is my VBO not working?打开 GL ES 2.0 为什么我的 VBO 不工作? 【发布时间】:2019-03-03 18:04:27 【问题描述】:嘿,我试图通过 vbo 在 OpenGL 中绘制一个带有 2 个三角形的简单四边形。 但是,我已经多次查看我的代码,但没有看到我缺少什么。 我不是 Open GL 专家,代码在没有任何缓冲区的情况下运行良好,但是当我切换到 VBO 时,我再也看不到任何东西了。 OpenGL 也不提供任何有用的错误。
Image::Image(Graphics * GFX)
glm::vec2 corners[2];
corners[0] = glm::vec2(0, 0);
corners[1] = glm::vec2(1, 1);
vertices = new GLfloat[30]
//Vertices XYZ TexCoord X,Y
corners[0].x, corners[0].y, 0.0f, 0,0,
corners[0].x, corners[1].y, 0.0f, 0,1,
corners[1].x, corners[0].y, 0.0f, 1,0,
corners[1].x,corners[1].y,0.0f, 1,1,
corners[0].x, corners[1].y,0.0f, 0,1,
corners[1].x, corners[0].y, 0.0f, 1,0
;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//Setting up some stuff
const char *vertexShaderSource =
"attribute vec4 vPosition; \n"
"attribute vec2 vTexCoord; \n"
"void main() \n"
" \n"
" gl_Position = vPosition; \n"
" \n";
const char *fragmentShaderSource =
"precision mediump float; \n"
"void main() \n"
" \n"
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"
" \n";
// Load and compile the vertex/fragment shaders
vertexShader = GFX->LoadShader(GL_VERTEX_SHADER, (const char*)vertexShaderSource);
fragmentShader = GFX->LoadShader(GL_FRAGMENT_SHADER, (const char*)fragmentShaderSource);
// Create the program object
programObject = glCreateProgram();
// now we have the V and F shaders attach them to the progam object
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
// Link the program
glLinkProgram(programObject);
// Check the link status
// Link the program
GLint AreTheylinked;
glGetProgramiv(programObject, GL_LINK_STATUS, &AreTheylinked);
if (!AreTheylinked)
GLint RetinfoLen = 0;
// check and report any errors
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &RetinfoLen);
if (RetinfoLen > 1)
GLchar* infoLog = (GLchar*)malloc(sizeof(char) * RetinfoLen);
glGetProgramInfoLog(programObject, RetinfoLen, NULL, infoLog);
fprintf(stderr, "Error linking program:\n%s\n", infoLog);
free(infoLog);
glDeleteProgram(programObject);
positionLocation = glGetAttribLocation(programObject, "vPosition");
textureCoordLocation = glGetAttribLocation(programObject, "vTexCoord");
if (glGetError() == GL_NO_ERROR)
else
printf("Init failed!\n");
//End setting up
Image::~Image()
void Image::Draw()
std::cout << "Calling Draw on Image" << std::endl;
glUseProgram(programObject);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLsizei stride = (5) * sizeof(GLfloat);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 6);
if (glGetError() != GL_NO_ERROR)
printf("UI Draw error\n");
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
以及我如何加载着色器:
GLuint Graphics::LoadShader(GLenum type, const char *shaderSrc)
// 1st create the shader object
GLuint TheShader = glCreateShader(type);
if (TheShader == 0) return FALSE; // can't allocate so stop.
// pass the shader source then compile it
glShaderSource(TheShader, 1, &shaderSrc, NULL);
glCompileShader(TheShader);
GLint IsItCompiled;
// After the compile we need to check the status and report any errors
glGetShaderiv(TheShader, GL_COMPILE_STATUS, &IsItCompiled);
if (!IsItCompiled)
GLint RetinfoLen = 0;
glGetShaderiv(TheShader, GL_INFO_LOG_LENGTH, &RetinfoLen);
if (RetinfoLen > 1)
// standard output for errors
char* infoLog = (char*)malloc(sizeof(char) * RetinfoLen);
glGetShaderInfoLog(TheShader, RetinfoLen, NULL, infoLog);
fprintf(stderr, "Error compiling this shader:\n%s\n", infoLog);
free(infoLog);
glDeleteShader(TheShader);
return FALSE;
return TheShader;
之前在没有缓冲区的情况下也可以正常工作,并且使用以下方法看到了一个白色方块:
glVertexAttribPointer(0, 6, GL_FLOAT, GL_FALSE, 0, vertices);
但现在我想通过 VBO 将纹理坐标添加到我的四边形,但没有任何显示。
Smoothy101
【问题讨论】:
【参考方案1】:您的缓冲区创建看起来不错 - 问题在于您的属性指针设置。您添加的纹理坐标已更改每个顶点的数据布局,但您尚未在代码中处理。
你需要这样的东西:
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(textureCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, 8);
...不是这个:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
【讨论】:
感谢您的快速回复!但是,这不意味着我需要在着色器中使用 textureCoorLocation 吗?由于我现在没有使用它,所以它设置为 -1 @solidpixel 啊,错过了 - 我看到了它的查询,但不是着色器没有使用它的事实 - 抱歉。您目前正在为glEnableAttribArray
和 glVertexAttribPointer
硬编码 0 - 这两个都应该是 positionLocation
。
glUseProgram(programObject); glEnable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, vbo); GLsizei stride = (5) * sizeof(GLfloat); glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, (void*)0); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES, 0, 6); if (glGetError() != GL_NO_ERROR) printf("UI Draw error\n"); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0);
这就是我现在拥有的,遗憾的是仍然没有白色四边形
只是检查一下,如果为 positionLocation
返回的位置是 0 以外的任何值,glEnableVertexAttribArray(0)
将不起作用。您应该在该调用中使用 positionLocation
。
不想这么说但还是没有运气glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
glEnableVertexAttribArray(positionLocation);
glDrawArrays(GL_TRIANGLES, 0, 6);
以上是关于打开 GL ES 2.0 为啥我的 VBO 不工作?的主要内容,如果未能解决你的问题,请参考以下文章