如何使用顶点数组对象?
How to use Vertex Array Object?
我正在尝试模拟在墙壁之间弹跳的立方体。为此,我构建了 2 个顶点数组对象,其中一个代表立方体,另一个代表墙。首先,我创建了墙。我正在使用 glDrawElements 调用绘制墙壁,因为我使用索引(元素)缓冲区来创建它。我还创建了一个立方体模型,但我没有为它使用索引缓冲区,所以据我所知,我将使用 glDrawArrays 调用来绘制它。我的墙壁显示得很好,但我不知道如何绘制立方体(在这一步,我什至没有尝试为立方体设置动画,我只是想绘制它)这我的代码是这样的:
#include "Cube.h"
#include <cstring>
GLuint vao[2];
void init()
{
cube();
GLuint program = InitShader( "vshader.glsl", "fshader.glsl" );
glUseProgram( program );
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glGenVertexArrays(2, vao);
glBindVertexArray(vao[0]);
GLuint cube_buffer;
glGenBuffers(1, &cube_buffer);
glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePoints), cubePoints, GL_STATIC_DRAW);
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
const float mid_value = 0.0f;
const float far_value = 0.35f;
const float near_value = 1.0f;
const float positions[60] = {
/// positions /// colors
mid_value, -near_value, 1.0, 0.0, 0.0, /// 0
near_value, -near_value, 1.0, 0.0, 0.0, /// 1
near_value, mid_value, 0.0, 1.0, 0.0, /// 2
near_value, near_value, 0.0, 1.0, 0.0, /// 3
mid_value, near_value, 1.0, 1.0, 0.0, /// 4
-near_value, near_value, 1.0, 1.0, 0.0, /// 5
-near_value, mid_value, 0.0, 0.0, 1.0, /// 6
-near_value, -near_value, 0.0, 0.0, 1.0, /// 7
far_value, -far_value, 1.0, 0.0, 0.0, /// 8
far_value, far_value, 0.0, 1.0, 0.0, /// 9
-far_value, far_value, 1.0, 1.0, 0.0, /// 10
-far_value, -far_value, 0.0, 0.0, 1.0 /// 11
};
unsigned int indices[36] = {
7,11,0,
0,8,1,
1,8,2,
2,9,3,
3,9,4,
4,10,5,
5,10,6,
6,11,7,
11,0,8,
8,2,9,
9,4,10,
10,6,11,
};
glBindVertexArray(vao[1]);
GLuint room_buffer;
glGenBuffers(1, &room_buffer);
glBindBuffer(GL_ARRAY_BUFFER, room_buffer);
glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)0); /// positions
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(2* sizeof(float))); /// colors
GLuint index_buffer;
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(unsigned int), indices, GL_STATIC_DRAW);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);
// glDrawArrays(...); --> how to use this, or should I really use this here?
glutSwapBuffers();
}
void idle() {
glutPostRedisplay();
}
void reshape(int width, int height) {
glViewport(0, 0, width, height);
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize( 600, 600 );
glutCreateWindow( "Bouncing Cube" );
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutMainLoop();
}
在此代码中,cubePoints 由另一个翻译单元中的 cube() 方法填充。我不确定如何在屏幕上绘制立方体,以及如何在此处使用 glDrawArrays?我应该绑定或取消绑定任何东西来绘制它吗?我觉得我没有正确使用顶点数组对象。下面是我的墙的样子:
我只是想让立方体出现在白色矩形所在的远端。是否可以使用 glDrawElements 调用 glDrawArrays?
您必须在“绘制”调用之前绑定顶点数组对象。绘图指令使用存储在当前绑定的顶点数组对象中的数据:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao[0]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(vao[1]);
glDrawArrays(...);
glutSwapBuffers();
}
我正在尝试模拟在墙壁之间弹跳的立方体。为此,我构建了 2 个顶点数组对象,其中一个代表立方体,另一个代表墙。首先,我创建了墙。我正在使用 glDrawElements 调用绘制墙壁,因为我使用索引(元素)缓冲区来创建它。我还创建了一个立方体模型,但我没有为它使用索引缓冲区,所以据我所知,我将使用 glDrawArrays 调用来绘制它。我的墙壁显示得很好,但我不知道如何绘制立方体(在这一步,我什至没有尝试为立方体设置动画,我只是想绘制它)这我的代码是这样的:
#include "Cube.h"
#include <cstring>
GLuint vao[2];
void init()
{
cube();
GLuint program = InitShader( "vshader.glsl", "fshader.glsl" );
glUseProgram( program );
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glGenVertexArrays(2, vao);
glBindVertexArray(vao[0]);
GLuint cube_buffer;
glGenBuffers(1, &cube_buffer);
glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePoints), cubePoints, GL_STATIC_DRAW);
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
const float mid_value = 0.0f;
const float far_value = 0.35f;
const float near_value = 1.0f;
const float positions[60] = {
/// positions /// colors
mid_value, -near_value, 1.0, 0.0, 0.0, /// 0
near_value, -near_value, 1.0, 0.0, 0.0, /// 1
near_value, mid_value, 0.0, 1.0, 0.0, /// 2
near_value, near_value, 0.0, 1.0, 0.0, /// 3
mid_value, near_value, 1.0, 1.0, 0.0, /// 4
-near_value, near_value, 1.0, 1.0, 0.0, /// 5
-near_value, mid_value, 0.0, 0.0, 1.0, /// 6
-near_value, -near_value, 0.0, 0.0, 1.0, /// 7
far_value, -far_value, 1.0, 0.0, 0.0, /// 8
far_value, far_value, 0.0, 1.0, 0.0, /// 9
-far_value, far_value, 1.0, 1.0, 0.0, /// 10
-far_value, -far_value, 0.0, 0.0, 1.0 /// 11
};
unsigned int indices[36] = {
7,11,0,
0,8,1,
1,8,2,
2,9,3,
3,9,4,
4,10,5,
5,10,6,
6,11,7,
11,0,8,
8,2,9,
9,4,10,
10,6,11,
};
glBindVertexArray(vao[1]);
GLuint room_buffer;
glGenBuffers(1, &room_buffer);
glBindBuffer(GL_ARRAY_BUFFER, room_buffer);
glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)0); /// positions
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(2* sizeof(float))); /// colors
GLuint index_buffer;
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(unsigned int), indices, GL_STATIC_DRAW);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);
// glDrawArrays(...); --> how to use this, or should I really use this here?
glutSwapBuffers();
}
void idle() {
glutPostRedisplay();
}
void reshape(int width, int height) {
glViewport(0, 0, width, height);
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize( 600, 600 );
glutCreateWindow( "Bouncing Cube" );
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutMainLoop();
}
在此代码中,cubePoints 由另一个翻译单元中的 cube() 方法填充。我不确定如何在屏幕上绘制立方体,以及如何在此处使用 glDrawArrays?我应该绑定或取消绑定任何东西来绘制它吗?我觉得我没有正确使用顶点数组对象。下面是我的墙的样子:
我只是想让立方体出现在白色矩形所在的远端。是否可以使用 glDrawElements 调用 glDrawArrays?
您必须在“绘制”调用之前绑定顶点数组对象。绘图指令使用存储在当前绑定的顶点数组对象中的数据:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao[0]);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(vao[1]);
glDrawArrays(...);
glutSwapBuffers();
}