从使用.obj文件中的VBO绘制多维数据集时遇到问题。
这是.obj:
# cube.obj
#
g cube
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0
f 1//2 7//2 5//2
f 1//2 3//2 7//2
f 1//6 4//6 3//6
f 1//6 2//6 4//6
f 3//3 8//3 7//3
f 3//3 4//3 8//3
f 5//5 7//5 8//5
f 5//5 8//5 6//5
f 1//4 5//4 6//4
f 1//4 6//4 2//4
f 2//1 6//1 8//1
f 2//1 8//1 4//1
要绘制它,我首先使用glmReadOBJ函数读取objet。接下来,我提取生成的模型中包含的信息(使用" trianglulate"函数)以便能够创建VBO对象然后绘制它,这是我的工作:
void triangulate(GLfloat* vertices, GLfloat* normals, GLMmodel *model)
{
int i, j;
int it = 0;
GLuint *tempN, *tempV;
for (int i = 0; i < model->numtriangles; i++)
{
tempV = model->triangles[i].vindices;
tempN = model->triangles[i].nindices;
for (int j = 0; j < 3; j++)
{
vertices[it] = model->vertices[tempV[j] - 1];
normals[it] = model->normals[tempN[j] - 1];
it++;
}
}
}
void glmInitVBO(GLMmodel* model, int* vboId)
{
GLfloat *vertices = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
GLfloat *normals = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
triangulate(vertices, normals, model);
glGenBuffersARB(1, vboId);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices) + sizeof(normals), 0, GL_STATIC_DRAW_ARB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices),vertices); // copy vertices starting from 0 offest
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals), normals); // copy normals after vertices
}
void glmDrawVBO(GLMmodel* model, int* vboId)
{
GLfloat *vertices = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
GLfloat *normals = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
triangulate(vertices, normals, model);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, *vboId);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, (void*)sizeof(vertices));
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
在我的主要内容中,我调用glmReadOBJ,然后调用glmInitVBO,最后调用glmDrawVBO,但没有任何反应:窗口保持黑色,没有绘制任何内容。 我不知道自己做错了什么,多次尝试了很多东西,但我最终得到的只是一个黑色的窗户......
感谢您的帮助!
答案 0 :(得分:2)
我看到的主要问题与您的OpenGL使用无关,但只是对sizeof
运算符如何工作的误解。例如,在此代码段中(其余代码中有更多类似的情况):
GLfloat *vertices = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
GLfloat *normals = (GLfloat*)malloc(model->numtriangles * 3 * sizeof(GLfloat));
...
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices) + sizeof(normals), 0, GL_STATIC_DRAW_ARB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices),vertices); // copy vertices starting from 0 offest
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals), normals); // copy normals after vertices
vertices
和normal
被声明为指针变量。因此,当以32位模式构建时,它们的大小为32位(4字节),而当以64位模式构建时,它们的大小为64位(8字节)。所以4/8是在变量上使用sizeof
运算符时得到的值。
您需要传递给glBufferData()
和glBufferSubData()
函数的是您分配的数据的实际大小,而不是指针的大小。例如:
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, model->numtriangles * 3 * sizeof(GLfloat), vertices);
另一个问题是glmInitVBO()
中的此次调用:
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
其中vboId
被声明为指向包含VBO id的int
值的指针。但是,glBindBuffer()
将id作为参数,而不是指向id的指针。所以电话应该是:
glBindBufferARB(GL_ARRAY_BUFFER_ARB, *vboId);
BTW,这些函数自版本1.1以来一直是标准OpenGL的一部分。确实不需要使用扩展版本。