Jump to content

  • Log In with Google      Sign In   
  • Create Account

Odd frame rate fluctuation when using glm::rotate.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 MarkS   Prime Members   -  Reputation: 882

Like
1Likes
Like

Posted 19 April 2013 - 02:22 PM

I wrote a simple instancing demo for a member here. The demo just creates a cube composed of 512 instances of a cube and the view rotates around this by updating the MVP matrix with glm::rotate. I noticed that the framerate was fluctuating in an almost sinusoidal fashion and this led me to the rotate function. The frame rate goes from a high of around .75 ms/frame to a low of around 1.5 ms/frame. This isn't too bad, but what I find curious, and my main question is, why is this not constant? I tested it and it seems that the frame rate spikes when the angle is 180° and drops to the low point at 0°.

 

Is this normal? I took a look at the source for glm::rotate, but couldn't find anything wrong. This leads me to believe that I am doing something wrong.

 

Here is the source:

 
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
BOOL done;
gl_win_app app_instance;
RECT bounds;
 
float angle;
float aspect;
float fov;
 
GLuint mvp_matrix_loc;
GLuint texture_loc;
GLuint instance_matrix_loc;
GLuint loc_1,loc_2,loc_3,loc_4;
 
glm::mat4 projection;
glm::mat4 view;
glm::mat4 mvp;
 
fov = 60.0f;
 
SetupConsole();
 
app_instance.InitializeApp("GL Instance Test");
 
app_instance.RegisterAppClass(hInstance);
app_instance.CreateAppWindow("GL Instance Test",WS_EX_APPWINDOW,WS_CAPTION | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,10,10,1000,1000,false);
app_instance.ShowAppWindow(true);
app_instance.SetAppWindowForeground();
app_instance.SetAppWindowFocus();
 
glClearColor(1.0f,1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
 
done = false;
 
GetClientRect(app_instance.h_wnd,&bounds);
bounds.bottom += GetSystemMetrics(SM_CYCAPTION) + (GetSystemMetrics(SM_CYFRAME) * 3) + (GetSystemMetrics(SM_CYBORDER) * 3);
bounds.right += (GetSystemMetrics(SM_CXFRAME) * 3) + (GetSystemMetrics(SM_CXBORDER) * 3);
 
aspect = float(bounds.right) / float(bounds.bottom);
 
projection = glm::perspective(fov,aspect,0.1f,1000.0f);
view = glm::lookAt(glm::vec3(0.0,0.0,25.0),glm::vec3(0.0,0.0,-25.0),glm::vec3(0,1,0));
 
shader = LoadShaders("data/instance.vs","data/instance.fs");
 
limestone.LoadTexture("data/limestone.tga");
 
CreateInstanceMatrices();
LoadCube();
 
glBindTexture(GL_TEXTURE_2D,limestone.GetTextureID());
glActiveTexture(GL_TEXTURE0);
glUniform1i(limestone.GetTextureID(),0);
 
mvp_matrix_loc = glGetUniformLocation(shader,"MVP");
texture_loc = glGetUniformLocation(shader,"texture_sampler");
 
instance_matrix_loc = glGetAttribLocation(shader,"instance_matrix");
loc_1 = instance_matrix_loc + 0;
loc_2 = instance_matrix_loc + 1;
loc_3 = instance_matrix_loc + 2;
loc_4 = instance_matrix_loc + 3;
 
glUseProgram(shader);
 
angle = 0.0f;
 
while(!done)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT){
done = true;
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}else{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
mvp = projection * view * glm::rotate(glm::mat4(),angle,glm::vec3(0.0,1.0,1.0));
angle += 0.025f;
if(angle > 360.0f)
angle = 0.0f;
 
glBindBuffer(GL_ARRAY_BUFFER,matrix_vbo);
 
glEnableVertexAttribArray(loc_1);
glEnableVertexAttribArray(loc_2);
glEnableVertexAttribArray(loc_3);
glEnableVertexAttribArray(loc_4); 
 
glVertexAttribPointer(loc_1,4,GL_FLOAT,GL_FALSE,sizeof(GLfloat) * 4 * 4,(void*)(0));
glVertexAttribPointer(loc_2,4,GL_FLOAT,GL_FALSE,sizeof(GLfloat) * 4 * 4,(void*)(sizeof(float) * 4));
glVertexAttribPointer(loc_3,4,GL_FLOAT,GL_FALSE,sizeof(GLfloat) * 4 * 4,(void*)(sizeof(float) * 8));
glVertexAttribPointer(loc_4,4,GL_FLOAT,GL_FALSE,sizeof(GLfloat) * 4 * 4,(void*)(sizeof(float) * 12)); 
 
glVertexAttribDivisor(loc_1,1);
glVertexAttribDivisor(loc_2,1);
glVertexAttribDivisor(loc_3,1);
glVertexAttribDivisor(loc_4,1);
 
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,20,BUFFER_OFFSET(0));
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,20,BUFFER_OFFSET(12));
 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbuffer);
 
glUniformMatrix4fv(mvp_matrix_loc,1,GL_FALSE,glm::value_ptr(mvp));
 
glDrawElementsInstanced(GL_TRIANGLES,index_array.size(),GL_UNSIGNED_INT,BUFFER_OFFSET(0),matrices.size());
 
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
 
app_instance.gl_context.SwapBuffers();
}
}
 
glUseProgram(0);
 
// Cleanup VBO and shader
glDeleteBuffers(1,&vertexbuffer);
glDeleteBuffers(1,&matrix_vbo);
glDeleteBuffers(1,&elementbuffer);
 
glDeleteProgram(shader);
 
FreeConsole();
 
app_instance.ReleaseApp();
 
return(msg.wParam);
}


Sponsor:

#2 MarkS   Prime Members   -  Reputation: 882

Like
0Likes
Like

Posted 22 April 2013 - 04:32 PM

Nothing?unsure.png



#3 mhagain   Crossbones+   -  Reputation: 7979

Like
0Likes
Like

Posted 24 April 2013 - 03:18 AM

Since you're only calling glm::rotate once per frame, it's extremely unlikely that it's overhead is even remotely near sufficient to cause this kind of performance drop.

 

Examine what's happening on-screen during the slower parts and compare to the faster parts.  Are more objects going in and out of the view frustum?  Are objects being occluded that otherwise were not?  Are big objects towards the end of your vertex buffer coming close to the viewpoint?  These would be realistic causes of such a performance drop, and would be entirely in the realm of expected behaviour.


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#4 MarkS   Prime Members   -  Reputation: 882

Like
0Likes
Like

Posted 24 April 2013 - 03:55 PM

All of the objects are in view and the issue disappears if I replace glm::rotate with glm::mat4(1.0f). All of the objects are the same size and vertex counts. The thing is, this is done using instancing. The largest buffer is the matrix buffer. The actual vertex buffer only has 12 vertices.

#5 marcClintDion   Members   -  Reputation: 431

Like
1Likes
Like

Posted 04 June 2013 - 05:24 AM

If your program bottleneck is in the fragment shader then the framerate will drop and climb as the models rotate unless they are spheres.  How burdened the fragment processor is depends on how many pixels are visible.  For a flat plane that is sideways at the center of the screen, the visible fragment count will be close to zero, your program will run faster if it happens to be fragment processor bound.  When it is completely facing the screen more pixels are visible and your framerate will drop.  Try scaling the models down to see if the framerate increases.


Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, because you know that the testing of your faith produces perseverance. Let perseverance finish its work so that you may be mature and complete, not lacking anything.


#6 Ashaman73   Crossbones+   -  Reputation: 7525

Like
0Likes
Like

Posted 04 June 2013 - 05:56 AM

It is hard to tell without a video or some screenshots. But I would guess, that by rotating the objects you could encounter view dependent (early-)z-buffer effects, aka  pixel overdraw.

 

A simple example: You draw your cubes in such an order, that they will be drawn from front to back. In this case the z-buffer will reach a stable state quite quickly and a lot of pixels will be rejected. Now you rotate your camera by 180° and the draw order changed from back to front. The early-z-buffer rejection effects will not be as effective as before resulting an high rate of pixel overdraw and therefor a potential performance loss.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS