Example #1
0
		bool CRenderManager::update()
		{
			glColor3f(1.0f,1.0f,1.0f);

			// get camera
			CCamera *camera = CV_GAME_MANAGER->getControlManager()->getCamera();

			// transform view
			camera->transformView();			

			// Draw the map and items that fall into view frustum. 								

			// 1. extract approximate logical location of camera in the level map.
			vector2i center = CConversions::realToLogical(camera->getPosition());

			GLint centerX = center[0];
			GLint centerY = center[1];

			bool isFPS = CV_GAME_MANAGER->getControlManager()->isFPS();

			if (isFPS)
			{
				// fog only in FPS mode
				glEnable(GL_FOG);
			}

			/*
				In FPS mode we can't use height to determine visible offset. 
				We have to use some extent read from config (CV_CAMERA_FPS_EXTENT).
			*/
			GLint diff = (GLint)(isFPS?cameraFPSExtent:camera->getPosition()[1]*10.0f);

			// 2. create a bounding square making its center logical position calculate above.
			GLint minX = (centerX-diff>=0?centerX-diff:0);
			GLint minY = (centerY-diff>=0?centerY-diff:0);
			GLint maxX = (centerX+diff<(GLint)CV_LEVEL_MAP_SIZE?centerX+diff:CV_LEVEL_MAP_SIZE-1);
			GLint maxY = (centerY+diff<(GLint)CV_LEVEL_MAP_SIZE?centerY+diff:CV_LEVEL_MAP_SIZE-1);			

			// 3. go through all block that fall into this bounding square and check if they fall
			//    int out view frustum. If not then just exclude them.

			CBlock *block;

			GLint	blockVisible = 0,
					allVerticesCount = 0,
					creaturesVisible = 0,
					maxVertInput = 0,
					maxTexInput  = 0;

			tmpVboVertexBufferSize = 0;
			tmpVboTexCoordBufferSize = 0;

			vector3f	vertA,
						vertB,
						vertC;

			GLfloat **verts,
					*texCoords;

			CLevelManager			*lManager = CV_GAME_MANAGER->getLevelManager();
			CAnimatedTerrainManager	*atManager = CV_GAME_MANAGER->getAnimatedTerrainManager();
			CFrustum				*frustum = CV_GAME_MANAGER->getControlManager()->getViewFrustum();

			bool lavaWater = false;

			GLfloat delta = CV_GAME_MANAGER->getDeltaTime();	

			renderedBlocks.clear();

			for (GLint y=minY; y<=maxY; y++)
			{
				for (GLint x=minX; x<=maxX; x++)
				{
					block = lManager->getBlock(x,y);

					if (block)
					{
						//block->getBoundingBox()->draw(); // just for testing
						if (frustum->containsBBOX(block->getBoundingBox()))
						{
							blockVisible++;

							block->updateTexture(delta);

							lavaWater = (block->isLava() || block->isWater());

							if (lavaWater)
							{
								atManager->updateBlock(block);
							}

							renderedBlocks.push_back(block);

							// draw block objects
							if (block->getBlockObjects()->size()>0)
							{
								for (std::vector<CBlockObject*>::iterator rmIter = block->getBlockObjects()->begin(); rmIter != block->getBlockObjects()->end(); rmIter++)
								{
									CBlockObject *bObj = *rmIter;

									bObj->moveTo();
									glRotatef(bObj->getRotateY(),0.0f,1.0f,0.0f);
									bObj->drawModel(delta);
									glRotatef(-bObj->getRotateY(),0.0f,1.0f,0.0f);
									bObj->moveBack();
								}
							}

							bool isRoom = block->isRoom();

							if (isRoom)
							{
								std::vector<GLuint> *dls = block->getDisplayLists();
								if (dls->size()!=0)
								{			
									glEnable(GL_TEXTURE_2D);
									glBindTexture(GL_TEXTURE_2D,textureAtlasColor);
									glBegin(GL_QUADS);
									{
										for (std::vector<GLuint>::iterator dlIter = dls->begin(); dlIter != dls->end(); dlIter++)
										{
											glCallList(*dlIter);									
										}
									}
									glEnd();
									glDisable(GL_TEXTURE_2D);									
								}
							}							

							for (GLint f=CBlock::BFS_FRONT; f<=CBlock::BFS_CEILING; f++)
							{
								if ((!isFPS && f==CBlock::BFS_CEILING) || (isFPS && f==CBlock::BFS_TOP) || (isRoom && f!=CBlock::BFS_CEILING))
								{
									continue;
								}

								if (block->isFaceVisible((CBlock::BLOCK_FACE_SELECTOR)f))
								{		
									verts = block->getVertices();
									texCoords = block->getTextureCoordinates((CBlock::BLOCK_FACE_SELECTOR)f);

									if (lavaWater && f<=CBlock::BFS_RIGHT)
									{
										/* 
											Lava and water have only lowers row of wall sections drawn. 
											If they are drawn at all.
										*/
										maxVertInput = CV_FBLR_W_L_FACE_VERT_FLOATS;
										maxTexInput = CV_FBLR_W_L_FACE_TEX_FLOATS;
									}
									else
									{
										maxVertInput = f>=CBlock::BFS_TOP?CV_TBWLC_FACE_VERT_FLOATS:CV_FBLR_FACE_VERT_FLOATS;
										maxTexInput = f>=CBlock::BFS_TOP?CV_TBWLC_FACE_TEX_FLOATS:CV_FBLR_FACE_TEX_FLOATS;
									}

									if (tmpVboVertexBufferSize+maxVertInput>CV_MAX_VERTEX_BUFFER*3)
									{		
										vbo->setElementsCount(CVBO::IDT_vertex,tmpVboVertexBufferSize/3);
										vbo->setElementsCount(CVBO::IDT_texture0,tmpVboTexCoordBufferSize/2);
										vbo->setElementsCount(CVBO::IDT_texture1,tmpVboTexCoordBufferSize/2);
										vbo->draw();
										allVerticesCount+=tmpVboVertexBufferSize;
										tmpVboVertexBufferSize=0;
										tmpVboTexCoordBufferSize=0;						
									}

									memcpy(tmpVboVertexBuffer+tmpVboVertexBufferSize, verts[f], sizeof(GLfloat)*maxVertInput);
									tmpVboVertexBufferSize+=maxVertInput;

									memcpy(tmpVboTexCoordBuffer+tmpVboTexCoordBufferSize, texCoords, sizeof(GLfloat)*maxTexInput);						
									tmpVboTexCoordBufferSize+=maxTexInput;
																	
								}
							}
						}
					}
				}
			}

			if (tmpVboVertexBufferSize>0)
			{		
				vbo->setElementsCount(CVBO::IDT_vertex,tmpVboVertexBufferSize/3);
				vbo->setElementsCount(CVBO::IDT_texture0,tmpVboTexCoordBufferSize/2);
				vbo->setElementsCount(CVBO::IDT_texture1,tmpVboTexCoordBufferSize/2);
				vbo->draw();
				allVerticesCount+=tmpVboVertexBufferSize;
			}	

			// draw creatures
			CCreatureManager *cManager = CV_GAME_MANAGER->getCreatureManager();
			GLint cCount = cManager->getCreatureVector()->size();
			if (cCount>0)
			{		
				CCreature *creature = NULL;
				for (std::vector<CCreature*>::iterator cIter = cManager->getCreatureVector()->begin(); cIter != cManager->getCreatureVector()->end(); cIter++)
				{
					creature = (*cIter);

					if (creature)
					{
						sBoundingBox *cBBOX = creature->getModel()->getBoundingBox();
						cBBOX->translate(creature->getPosition());
						if (frustum->containsBBOX(cBBOX))
						{
							creature->draw(delta);
							creaturesVisible++;
						}
						cBBOX->translate(-creature->getPosition());
					}
				}
			}

			// draw transparent block objects
			for (std::vector<CBlock*>::iterator vbIter = renderedBlocks.begin(); vbIter != renderedBlocks.end(); vbIter++)
			{
				block = *vbIter;
				if (block->getBlockObjects()->size()>0)
				{
					for (std::vector<CBlockObject*>::iterator rmIter = block->getBlockObjects()->begin(); rmIter != block->getBlockObjects()->end(); rmIter++)
					{
						CBlockObject *bObj = *rmIter;

						bObj->moveTo();
						glRotatef(bObj->getRotateY(),0.0f,1.0f,0.0f);
						bObj->drawEffect();
						glRotatef(-bObj->getRotateY(),0.0f,1.0f,0.0f);
						bObj->moveBack();
					}
				}
			}

			glDisable(GL_FOG);
			
			if (!isFPS)
			{
				handlePickedObjects();
			}

			CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15*3),"Visible blocks: %d",blockVisible);
			CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15*2),"Visible creatures: %d",creaturesVisible);
			CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15),"Triangles drawn: %d",(allVerticesCount/4)*2);

			// render the lights representations. usefull for debugging
			CV_GAME_MANAGER->getLightingManager()->drawLightSources(frustum);
            
			return true;
		}