PDA

View Full Version : Vertex Array slowdown (vs. Immediate Mode)



Corrail
06-04-2005, 12:52 AM
Hello!

I have got a problem using vertex arrays because they give me a slowdown (200FPS -> 12FPS). Here my Rendering Code:

Immediate Mode

glBegin(GL_TRIANGLES);
for (int i = 0; i < mesh->num_triangles; i++)
{
glVertexAttrib2fvARB(texcoord_index, mesh->buf_texc[mesh->triangles[i].v0].data_pointer());
glVertexAttrib3fvARB(normal_index, mesh->buf_norm[mesh->triangles[i].v0].data_pointer());
glVertexAttrib3fvARB(tangent_index, mesh->buf_tang[mesh->triangles[i].v0].data_pointer());
glVertexAttrib3fvARB(binormal_index, mesh->buf_bino[mesh->triangles[i].v0].data_pointer());
glVertex3fv(mesh->buf_vert[mesh->triangles[i].v0].data_pointer());

glVertexAttrib2fvARB(texcoord_index, mesh->buf_texc[mesh->triangles[i].v1].data_pointer());
glVertexAttrib3fvARB(normal_index, mesh->buf_norm[mesh->triangles[i].v1].data_pointer());
glVertexAttrib3fvARB(tangent_index, mesh->buf_tang[mesh->triangles[i].v1].data_pointer());
glVertexAttrib3fvARB(binormal_index, mesh->buf_bino[mesh->triangles[i].v1].data_pointer());
glVertex3fv(mesh->buf_vert[mesh->triangles[i].v1].data_pointer());

glVertexAttrib2fvARB(texcoord_index, mesh->buf_texc[mesh->triangles[i].v2].data_pointer());
glVertexAttrib3fvARB(normal_index, mesh->buf_norm[mesh->triangles[i].v2].data_pointer());
glVertexAttrib3fvARB(tangent_index, mesh->buf_tang[mesh->triangles[i].v2].data_pointer());
glVertexAttrib3fvARB(binormal_index, mesh->buf_bino[mesh->triangles[i].v2].data_pointer());
glVertex3fv(mesh->buf_vert[mesh->triangles[i].v2].data_pointer());
}
glEnd();Vertex Arrays

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glVertexAttribPointerARB(texcoord_index, 2, GL_FLOAT, GL_FALSE, 0, (float*)mesh->buf_texc);
glEnableVertexAttribArrayARB(texcoord_index);

glVertexAttribPointerARB(normal_index, 3, GL_FLOAT, GL_FALSE, 0, (float*)mesh->buf_norm);
glEnableVertexAttribArrayARB(normal_index);

glVertexAttribPointerARB(tangent_index, 3, GL_FLOAT, GL_FALSE, 0, (float*)mesh->buf_tang);
glEnableVertexAttribArrayARB(tangent_index);

glVertexAttribPointerARB(binormal_index, 3, GL_FLOAT, GL_FALSE, 0, (float*)mesh->buf_bino);
glEnableVertexAttribArrayARB(binormal_index);

glVertexPointer(3, GL_FLOAT, 0, (float*)mesh->buf_vert);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawElements(GL_TRIANGLES, mesh->num_triangles*3, GL_UNSIGNED_INT, mesh->buf_ind);Does anyone has an idea?
Thanks

jide
06-04-2005, 01:56 AM
Sorry for my lack of knowledge, but what's this line intended for ?


glVertexAttrib2fvARB(...);I couldn't find any information about VertexAttrib. If someone could point me to any documentation about it, it will be fine.

To try to answer the question: actually I don't know. This seems a partial code, isn't it ? So, maybe with much code, someone will be able to give an interresting explanation of why this doesn't work as you expected.
Too, I've never used VertexAttrib with vertex arrays, neither with VBO.

To have a better comparison between vertex arrays and immediate mode, try not to use any VBO neither VertexAttrib and tell if the performances are the same like with them.

Hope that could help.

EDIT:

Well, after some researches, VertexAttrib are to be used for vertex shaders. You didn't seem to do any shader here. So, if I'm not wrong, you should not use VertexAttrib at all.
Do some searches for making any Vertex Array and try what I said above.

Trahern
06-04-2005, 03:04 AM
Originally posted by jide:

Well, after some researches, VertexAttrib are to be used for vertex shaders. You didn't seem to do any shader here. So, if I'm not wrong, you should not use VertexAttrib at all.
Do some searches for making any Vertex Array and try what I said above.Well I think that he is using shaders for bumpmapping..this is just a part of the program.

zeckensack
06-04-2005, 03:55 AM
Originally posted by Corrail:
Does anyone has an idea?
ThanksTry interleaving your arrays.
struct Vertex
{
float texcoord[2];
float normal[3];
float tangent[3];
float binormal[3];
float position[3];
};Pulling (large blocks of) data from five different memory locations isn't terribly efficient.

How complex is your testing mesh (vertex count)?

Corrail
06-04-2005, 05:53 AM
The problem with interleaved arrays is that they are not as flexible as I'd like them to be.

Vertex count is 645, 936 triangles

But I noticed something very strange.

Here my Vertex Shader:

attribute vec3 a2v_Normal;
attribute vec3 a2v_Tangent;
attribute vec3 a2v_Binormal;
attribute vec2 a2v_Texcoord;

varying vec3 v2f_LightVec;
varying vec3 v2f_ViewVec;
varying vec2 v2f_Texcoord;

void main()
{
// Vertex transformation
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

// Calculating TBN
vec3 Tangent = gl_NormalMatrix * a2v_Tangent;
vec3 Binormal = gl_NormalMatrix * a2v_Binormal;
vec3 Normal = gl_NormalMatrix * a2v_Normal;

// Calculating Light vector in ModelView Space
vec3 Vertex_Model = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 LightVec = vec3(gl_LightSource[0].position) - Vertex_Model;

//v2f_LightVec = vec3(1.0, 0.0, 0.0);
//v2f_ViewVec = vec3(1.0, 0.0, 0.0);

v2f_LightVec.x = dot(LightVec, Tangent);
v2f_LightVec.y = dot(LightVec, Binormal);
v2f_LightVec.z = dot(LightVec, Normal);

// Calculating View vector in ModelView Space
v2f_ViewVec.x = dot(-Vertex_Model, Tangent);
v2f_ViewVec.y = dot(-Vertex_Model, Binormal);
v2f_ViewVec.z = dot(-Vertex_Model, Normal);

// Passing texture coordinates to fragment shader
v2f_Texcoord = a2v_Texcoord;
}When I comment out all Tangent/Normal/Binormal stuff like:


attribute vec3 a2v_Normal;
//attribute vec3 a2v_Tangent;
//attribute vec3 a2v_Binormal;
//attribute vec2 a2v_Texcoord;

varying vec3 v2f_LightVec;
varying vec3 v2f_ViewVec;
varying vec2 v2f_Texcoord;

void main()
{
// Vertex transformation
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

// Calculating TBN
//vec3 Tangent = gl_NormalMatrix * a2v_Tangent;
//vec3 Binormal = gl_NormalMatrix * a2v_Binormal;
//vec3 Normal = gl_NormalMatrix * a2v_Normal;

// Calculating Light vector in ModelView Space
vec3 Vertex_Model = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 LightVec = vec3(gl_LightSource[0].position) - Vertex_Model;

v2f_LightVec = vec3(1.0, 0.0, 0.0);
v2f_ViewVec = vec3(1.0, 0.0, 0.0);

/*v2f_LightVec.x = dot(LightVec, Tangent);
v2f_LightVec.y = dot(LightVec, Binormal);
v2f_LightVec.z = dot(LightVec, Normal);

// Calculating View vector in ModelView Space
v2f_ViewVec.x = dot(-Vertex_Model, Tangent);
v2f_ViewVec.y = dot(-Vertex_Model, Binormal);
v2f_ViewVec.z = dot(-Vertex_Model, Normal);*/

// Passing texture coordinates to fragment shader
v2f_Texcoord = a2v_Texcoord;
}it works without problems.

Trahern
06-04-2005, 06:20 AM
Originally posted by Corrail:
When I comment out all Tangent/Normal/Binormal
it works without problems.I think thats becouse when you comment them out then these attributes are not send to the shader.

Have you tried sending data for example via texCoords?

i.e. to send normals its common to use glNormalPointer
and then you can bind tangent/binormals to some free texture units by glTexCoordPointer(..)

martin_marinov
06-05-2005, 04:21 AM
You are using GLSLang for you vertex shaders, right? We (me and my co-workers) recently submitted a paper for PG'05 about rendering of multiresolution deformations computed on the GPU, and using the latest NVIDIA drivers on both Win32 and Linux platforms with GeForce 5 & 6, GLSLang was incredibly slow compared to the same program written with ARB_vertex_program. Sometimes the GLSLang program was about 9-10 times slower than the ARB program.
Although in your case you are getting slowdown when using vertex arrays vs. intermediate mode, I'm sharing our experience only to suggest that the reason for the strange performance results might be related to the infant stage of GLSlang implementation in the current OpenGL drivers. Also you could try interleaved arrays, this might result in a better performance if your shader is data transfer dependent.

Regards

Trahern
06-05-2005, 06:03 AM
I really doubt that interleaved arrays can solve his problem. Of course he can get better performance but the problem has to be somewhere else. It rather seems that that he is dropping back to software rendering ( as he wrote he is sending only 900 tris + using quite simple shaders ).