# Time based rendering placement problems (updated)

This topic is 4398 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Yeah I know that the title is kind of confusing, but I didn't really know what else to have it as. Anyway, the problem is that the code that I have to do time based rendering so I restrict the fps of the engine is currently in my SceneManager class. When I need to render, I simply call SceneManager::render() and that traverses the scene graph tree and calls 'render' for everything. So, the code to restrict the engine fps needs to be in SceneManager::render(). I recently realised that if I call SceneManager::render() more than once every frame, I get problems. For instance if I need to render twice for shadows, or to draw reflections, or something like that. It's a little bit of a story, so here goes: This is the code that restricts the fps of the engine:
/**
* Render all objects in the scene graph.
*/
void CSceneGraph::render()
{

while( (m_time += m_hiResTimer.getElapsedSeconds()) < m_minTimeBetweenFrames );

//if( (m_time += m_hiResTimer.getElapsedSeconds()) < m_minTimeBetweenFrames )
//	return;

util::list<ISceneGraphNode*>::iterator i;

// pre render
for(i = m_nodeList.begin() ; i != m_nodeList.end(); i++)
(*i)->preRender( m_time );

// render
for(i = m_nodeList.begin() ; i != m_nodeList.end(); i++)
(*i)->render();

// post render
for(i = m_nodeList.begin() ; i != m_nodeList.end(); i++)
(*i)->postRender( m_time );

// reset time to 0.0f because we have just drawn a frame
m_time = 0.0f;

}


I currently have to use the while statement, otherwise I get serious flickering and no restriction of the fps. I think I know why this is. Whenever VideoDriver::endScene is called, it swaps the buffers for the window, and obviously if no rendering is done then nothing gets drawn to the back buffer and a blank buffer gets swapped to the screen, causing the flickering. I think. So, for both these reasons, (blank buffer swap, and calling SceneManager::render more than once a frame) I need to move the fps code to the video driver, so I can prevent the buffer being swapped when nothing has been drawn to it. Should I just have a pointer to the scene graph inside the video driver, move the fps code to the video driver and instead of calling 'render' on the scene graph object, do it on the video driver object? How have other people done this bit? Or did you all do the smart thing and have a better design than I did? [Edited by - Endar on May 23, 2006 4:17:16 AM]

##### Share on other sites
Time restriction does not below in a scene graph.

When you call "render" on a scene graph, it should traverse the graph, and render all the items to the indicated target, using the current state of the objects. It should not change the state of the objects, or check the time, or anything like that. When it comes to object state, the scene graph should be absolutely dumb (only the user changes the objects).

If calling Render() twice in a row in your scene graph causes an empty frame to be rendered, you have a bug in your scene graph.

If you need to limit the frame rate, you should first try turning on vSync in your code -- D3DPRESENTINTERVAL_xxx has some options for you. This will remove all tearing. Only after that should you start throttling in the application -- and, in that case, in the high-level code. I e, your code might look something like:

  forever() {    toSleep = nextTime - time();    Sleep(toSleep);    nextTime = time() + desiredFrameTime;    ReadInput();    ProcessPhysics(desiredFrameTime);    RenderScene();  }

Note that Sleep() may be a little bit jittery on some systems; you may have better results with something like MsgWaitForMultipleObjectsEx() with a timeout.

##### Share on other sites
Quote:
 Original post by hplus0603If you need to limit the frame rate, you should first try turning on vSync in your code -- D3DPRESENTINTERVAL_xxx has some options for you.

Do you know the equivalent for OGL? Oh, well I don't think it matters as I'm not currently using full screen, I'm just doing it windowed.

##### Share on other sites
Okay, I thought this would work, but I'm having problems with the code and it's better to post here than start up a new thread.

void IVideoDriver::render(){	// If the total time since the last frame is less than the time between frames for the desired fps	// ie. If to restrict to the desired fps, we don't have to draw yet	if( (m_time += m_hiResTimer.getElapsedSeconds()) < m_minTimeBetweenFrames )		return;	// if we get here, then we should be rendering a frame			// if we have a scene manager	if( m_sceneManager )		m_sceneManager->render( m_time );		// render the scene graph	// reset the time	m_time = 0.0f;	// indicate we should be rendering	m_renderFrame = true;}/** * Does housekeeping for the end of rendering a frame. */virtual void IVideoDriver::endScene(){	// if we should be rendering a frame	if( m_renderFrame ){		m_fpsCounter.endFrame();	// register the end of a frame, so, calculate the FPS		m_renderFrame = false;	// it's the beginning of a new frame	}}/** * Does OGL housekeeping for the end of rendering a frame. * Flushes the pipeline, swap buffers, counts fps. */void COpenGLDriver::endScene(){	// If the time since the last frame is greater than the min time between frames	// ie. If we should be rendering	if( m_renderFrame ){		glFlush();			// flush the pipeline		SwapBuffers(m_hdc);	// render the scene to the window		// do the FPS calculating, etc		IVideoDriver::endScene();	}}

Note:: COpenGLDriver inherits from IVideoDriver.

If I use the code was is, the FPS counter says the fps is ~50. But when I do some rotation on the cube, which is the only thing is the scene, it rotates way too fast for 50 fps.

If I comment out the first if statement, and don't add to 'm_time' at all, I get about ~87.

This is really confusing.

bump

##### Share on other sites
You are only restricting the rendering frame rate by putting checks in a render() function, not the physics frame rate. Your high-level message loop is the place to restrict speed, not a rendering function.

And you don't need to bump after 7 hours.

##### Share on other sites
Quote:
 Original post by Bob JanovaYou are only restricting the rendering frame rate by putting checks in a render() function, not the physics frame rate. Your high-level message loop is the place to restrict speed, not a rendering function.

At the moment, I'm only trying to restrict the rendering speed (I currently have no physics).

Why is the high-level message loop the place to restrict speed? Can't I have each system restricting it's own speed to whatever it needs or wants?

Quote:
 Original post by Bob JanovaAnd you don't need to bump after 7 hours.

Uh, 3:45am I wrote the post, and bumped it at 10:55pm.

##### Share on other sites
Okay, you don't need to bump after X hours, where X < 24 and your page is still on the first screen :P.

Quote:
 At the moment, I'm only trying to restrict the rendering speed (I currently have no physics).

Uh, where does rotating this model happen, then? The rate at which that occurs will be related to your input framerate, which I presume is not called from within render(). You don't restrict the framerate of your message loop at all by returning from render() (to do that you need to wait).

Quote:
 Why is the high-level message loop the place to restrict speed? Can't I have each system restricting it's own speed to whatever it needs or wants?

Well, yes, it's just more complicated. By restricting frame rate at the highest level you ensure all your game modules run at the same speed. If you want to restrict each component separately then that's fine, but don't expect your input and rendering to happen at the same frame rate!

##### Share on other sites
Quote:
 Original post by Bob JanovaUh, where does rotating this model happen, then? The rate at which that occurs will be related to your input framerate, which I presume is not called from within render(). You don't restrict the framerate of your message loop at all by returning from render() (to do that you need to wait).

I thought that eventually I'd be able to do something like this:
while( running ){	processInput();	render();	physicsUpdate();	sleep();}

And for the rendering and physics, or at least the rendering calc the seconds (fractions obviously) between each render to get a specific fps, and if we've not hit it yet, then just don't render and go on to the physics. Kind of the same with the physics (kind of, I know nothing about physics yet).

Or was this what you were telling me and it's just not entering my thick, thick head?

##### Share on other sites
Okay, so in that case what is the problem with the cube rotating faster than 50 fps :P ? If you're just not rendering then you'd expect the other parts of the game (input, physics) to go faster. Sounds like your solution is working just like you wanted it to 8).

1. 1
2. 2
3. 3
4. 4
Rutin
17
5. 5

• 11
• 30
• 12
• 12
• 11
• ### Forum Statistics

• Total Topics
631408
• Total Posts
2999922
×