Skip to main content
GameDev.net gamedev.net
🔒 Locked

ROAM 2.0 - example implementation step 3

Started by kudi Sep 8, 2004 at 7:29 AM 0 replies 2.7k views
Original Post
kudi
kudi
is there any body who has tried out the roam 2.0 algorithm? i have a question about the rendering code of the implementation example step 3.

//the high-level rendering function to being ROAM rendering
void Terrain::ROAM::Render( void ) {
	//reset the debug counters
	m_vertsPerFrame= 0;
	m_trisPerFrame = 0;

	//turn on textured drawing (with the grid texture for now)
	glBindTexture( GL_TEXTURE_2D, m_texture.GetID( ) );
	glEnable( GL_TEXTURE_2D );

	glColor3f( 1.0f, 1.0f, 1.0f );

	//recurse on the two base triangles
	glBegin( GL_TRIANGLES );
		RenderChild( m_pLevel1Dmnd[2][1], 2, 0 );
		RenderChild( m_pLevel1Dmnd[1][2], 0, 0 );
	glEnd( );

	//end texturing
	glDisable( GL_TEXTURE_2D );
}

//recursive rendering function
void Terrain::ROAM::RenderChild( ROAMDiamond *pDmnd, int i, int cull ) {
    ROAMDiamond *centerDmnd;	//center, split-edge diamond
    float *dmndCenter;			//center vertex
	float dist;

	//get selected child create if not there, indicate recent use
	centerDmnd= GetChild( pDmnd, i );
	dmndCenter= centerDmnd->m_vert;

	//check the triangle's bounding sphere against the view frustum
	if( cull != CULL_ALLIN ) {
		float r, rad;
		int j, m;
 
		rad= centerDmnd->m_bound;

		//perform culling against the view frustum
		for( j= 0, m= 1; j < 6; j++, m<<= 1 ) {
			if( !( cull & m ) ) {
				r= m_frustum[j][0]*dmndCenter[0] +
				   m_frustum[j][1]*dmndCenter[1] +
				   m_frustum[j][2]*dmndCenter[2] +
				   m_frustum[j][3];

				//check for frustum inclusion
				if( r*r > rad ) {
					//check to see if the triangle is actually within the viewing frustum
					if( r < 0.0f ) {
						Unlock( centerDmnd );
						return;
					}
					
					//triangle is within view
					cull|= m;
				}
			}
		} 
	}

    //distance calculation
    dist= SQR( ( dmndCenter[0] - m_camX ) ) +
		  SQR( ( dmndCenter[1] - m_camY ) ) +
		  SQR( ( dmndCenter[2] - m_camZ ) );

	//recurse down to the next level if possible
	if( centerDmnd->m_level < m_maxLevel && centerDmnd->m_error > dist*0.000001f ) {
		if( centerDmnd->m_pParent[0] == pDmnd ) {
			RenderChild( centerDmnd, 0, cull );
			RenderChild( centerDmnd, 1, cull );
		} else {
			RenderChild( centerDmnd, 2, cull );
			RenderChild( centerDmnd, 3, cull );
		}
	} else {
		ROAMDiamond *pPrevDmnd, *pNextDmnd; //diamonds of other two triangle vertices

		//determine all tri's verts
		if( centerDmnd->m_pParent[0] == pDmnd ) {
			pPrevDmnd= centerDmnd->m_pParent[2];
			pNextDmnd= centerDmnd->m_pParent[3];
		} else {
			pPrevDmnd= centerDmnd->m_pParent[3];
			pNextDmnd= centerDmnd->m_pParent[2];
		}

		//draw the tri with simple per-tri texture the shows the grid
		glTexCoord2f( pPrevDmnd->m_vert[0]/m_size, pPrevDmnd->m_vert[2]/m_size ); glVertex3fv( pPrevDmnd->m_vert );
		glTexCoord2f( pDmnd->m_vert[0]/m_size,	   pDmnd->m_vert[2]/m_size );	  glVertex3fv( pDmnd->m_vert );
		glTexCoord2f( pNextDmnd->m_vert[0]/m_size, pNextDmnd->m_vert[2]/m_size ); glVertex3fv( pNextDmnd->m_vert );

		m_vertsPerFrame+= 3;
		m_trisPerFrame++;
	}

	//undo locking from GetChild()
	Unlock( centerDmnd );
}

i am wondering how this can be done in a single pass. if i understand correctly, each diamond needs two parents if you want to split it. so there is something like the force split in roam. so when i force to split a diamond which has already been drawn, i would get an error. so how does it still function?
The problem of Object Oriented Programming:Everybody tells you how to use his classes, but nobody how not to do it !
Eelco
Eelco
its the idea to first do splitting/merging operations and THEN draw everything?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.