问题描述
我正在学习 opengl 并尝试使用 glDrawEmelents 绘制索引圆,但由于某种原因它不起作用。但是,当我使用 glDrawElements 绘制三角形时(请参阅注释代码),它可以很好地绘制三角形。我认为这与我的元素/索引有关,但我不知道。
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MInor_VERSION,1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("GL Window",SDL_WINDOWPOS_UNDEFINED,500,SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
glewExperimental = true;
GLenum error = glewInit();
if (error != GLEW_OK)
return -1;
if (context == NULL)
return -1;
SDL_Event event;
gluint vShader = 0;
gluint fShader = 0;
static const GLchar* fragText[] = {
"#version 450 core \n"
"\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = vec4(0.5,0.8,1.0,0.7);\n"
"}\n"
};
static const GLchar* vertText[] = {
"#version 450 core \n"
"layout (location = 0) in vec4 position;\n"
"void main(void)\n"
"{\n"
" gl_Position = position;\n"
"}\n"
};
vShader = glCreateShader(GL_VERTEX_SHADER);
fShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vShader,1,vertText,NULL);
glCompileShader(vShader);
GLint status;
glGetShaderiv(vShader,GL_COMPILE_STATUS,&status);
if (status != GL_TRUE) {
printf("v bust");
return -1;
}
glShaderSource(fShader,fragText,NULL);
glCompileShader(fShader);
if (status != GL_TRUE) {
printf("f bust");
return -1;
}
gluint programID = glCreateProgram();
glAttachShader(programID,vShader);
glAttachShader(programID,fShader);
glLinkProgram(programID);
glm::vec4 circLeverts[33];
int size = (sizeof(circLeverts) / sizeof(glm::vec4));
circLeverts[0] = glm::vec4(0,1.0f);
for (int i = 1; i < size; i++) {
float heading = 360.f * ((float)i / (float)(size));
circLeverts[i] = glm::vec4(0.5f * glm::cos(heading),0.5f * glm::sin(heading),1);
printf("%d:(%f,%f,%f)\n",i,circLeverts[i].x,circLeverts[i].y,circLeverts[i].z,circLeverts[i].w);
printf("heading:%f\n",heading);
}
int circleIndices[96];
size = (sizeof(circleIndices) / sizeof(int));
for (int i = 0; i < size; i++) {
circleIndices[i] = 0;
circleIndices[i + 1] = 1;// i % 32;
circleIndices[i + 2] = 2;// (i + 1) % 32;
}
/* draw triangle
glm::vec4 circLeverts[3];
circLeverts[0] = glm::vec4(0,.5f,1);
circLeverts[1] = glm::vec4(0.5f,-.5f,1);
circLeverts[2] = glm::vec4(-0.5f,-0.5f,1);
glushort circleIndices[3];
circleIndices[0] = 0;
circleIndices[1] = 1;
circleIndices[2] = 2;
*/
gluint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(circLeverts),circLeverts,GL_STATIC_DRAW);
glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,NULL);
glEnabLevertexAttribArray(0);
gluint ibo;
glGenBuffers(1,&ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(circleIndices),circleIndices,GL_STATIC_DRAW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC1_ALPHA);
while (true) {
SDL_PollEvent(&event);
if (event.type == SDL_QUIT) {
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
glViewport(0,500);
glClearColor(0,1);
glClear(GL_COLOR_BUFFER_BIT);
gluseProgram(programID);
//glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT,0);
glDrawElements(GL_TRIANGLES,96,0);
//glDrawArrays(GL_POINTS,32);
SDL_GL_SwapWindow(window);
}
它也可以很好地绘制点。
解决方法
glDrawElements
的 type 参数必须与索引的数据类型相对应。GL_UNSIGNED_INT
对应于 GLuint
。如果数据类型为 GLushort
,则类型参数必须为 GL_UNSIGNED_USHORT
。