Beispiel #1
0
void Renderer::Render()
{
	GeometryPass();
	LightPass();
}
//the "main" of the renderer
void GLRenderer::render(float dt) {
	
	camera_t *viewer, *lastviewer=NULL;
	
	LightPass lightpasses[128];
	int lightpass_count=0;
	unsigned int num_lights = lightList.size();
	unsigned int maxLightsPass = gfx_GLSLQuality.integer>1 ? 4 : MIN(gfx_maxlightsperpass.integer, glMaxLights);
	
	renderer_meshculled=0;
	renderer_octculled=0;
	
	//// SORT SORTED LIST ////
	sortedRenderList.sort(dist_sort);  //depth sorting
	sortedStaticRenderList.sort(dist_sort);  //depth sorting
	
	if(gfx_sortAll.integer)
		unsortedRenderList.sort(rev_dist_sort);

	//// ADD IN OCTREE ////
	//octree list items always have to be near the start of the list
	for(std::list<GLRenderListItem*>::iterator itr = --octreeList.end();
				itr != octreeList.begin(); itr--) {
		unsortedRenderList.push_front((*itr)->getRef());
	}
	
	unsortedRenderList.push_front((*octreeList.begin())->getRef());
	
	//// PRERENDER ////
	for(std::list<GLRenderListItem*>::iterator itr = unsortedRenderList.begin();
				itr != unsortedRenderList.end(); itr++) {
			(*itr)->prerenderStage(dt);
	}
	
	for(std::list<GLRenderListItem*>::iterator itr = sortedRenderList.begin();
				itr != sortedRenderList.end(); itr++) {
			(*itr)->prerenderStage(dt);
	}
	
	//// ADD LIGHTING PASSES ////
	if(num_lights > maxLightsPass && gfx_multipassLighting.integer) {
		for(unsigned int i=maxLightsPass; i<num_lights && lightpass_count<128; i+=maxLightsPass) {
			lightpasses[lightpass_count] = LightPass();
			lightpasses[lightpass_count].setLightStart(i);
			addPass(&lightpasses[lightpass_count++]);
		}
	}
	
	if(vid_multisample.integer)
		GL_Enable(GL_MULTISAMPLE_ARB);
	
	//// PERFORM ALL RENDER PASSES ////
	for(std::list<Pass *>::iterator itr=passes.begin();itr!=passes.end();itr++) {
		currentPass = *itr;
		
#ifdef DEBUG
		if(gfx_shadowDebug.integer&& !currentPass->isShadowPass())
			break;
#endif
		
		//DEBUG ONLY:
		if(gfx_flush.integer)
			glClear(GL_COLOR_BUFFER_BIT);
		
		GL_ResetColor();
		
		//setup the pass
		currentPass->setup(this);
		
		if(currentPass->canRender()) {
			viewer = currentPass->getViewer();
			
			if(lastviewer != viewer) {
				resetPass();
				lastviewer = viewer;
			}
			
			if(gfx_GLSLQuality.integer > 1 && !currentPass->isShadowPass()) {
				GL_SwitchTexUnit(GL_TEXTURE1_ARB);
				shadowTarget->bindTexture(0);
				GL_BuildShadowTextureMatrix(viewer);
			}
			
			//render the lights for this pass
			unsigned int currentLight = 0;
			for(std::list<GLRenderListLightItem*>::iterator itr = lightList.begin();
						itr != lightList.end(); itr++) {
				if(currentLight >= currentPass->getLightStart()+maxLightsPass)
					break;
				if((int)currentLight >= currentPass->getLightStart())
					(*itr)->renderPass(this);
				currentLight++;
			}
			
			//determine visibility and render
			//unsorted items are drawn first
			std::for_each(unsortedRenderList.begin(), unsortedRenderList.end(), RenderIfVisible(this));
			if(!(viewer->flags & CAM_NO_WORLDOBJECTS))
				std::for_each(unsortedStaticRenderList.begin(), unsortedStaticRenderList.end(), RenderIfVisible(this));
			
			//sorted items are drawn next (translucent & additive stuff)
			if(!(viewer->flags & CAM_NO_WORLDOBJECTS))
				std::for_each(sortedStaticRenderList.begin(), sortedStaticRenderList.end(), RenderIfVisible(this));
			std::for_each(sortedRenderList.begin(), sortedRenderList.end(), RenderIfVisible(this));
			
			//effects last, as they always look better as overlays
			
			//for nice effects, do this
			if(gfx_niceEffects.integer && gfx_GLSLQuality.integer>=1 && gfx_postProcEnabled.integer) {
				GL_BeginPostProcessingEffects();
					
				std::for_each(effectsList.begin(), effectsList.end(), RenderIfVisible(this));
				
				GL_EndPostProcessingEffects();
			} else {
				std::for_each(effectsList.begin(), effectsList.end(), RenderIfVisible(this));
			}
			
			#ifdef DEBUG
			for(unsigned int i=0;i<bboxCount;i++) {
				vec3_t bmin, bmax;
				
				M_AddVec3(bboxes[i].min,bboxes[i].pos, bmin);
				M_AddVec3(bboxes[i].max,bboxes[i].pos, bmax);
				//Draw the box
				GL_DrawBox(bmin, bmax);
			}
			#endif
			
			if(gfx_GLSLQuality.integer > 1 && !currentPass->isShadowPass()) {
				GL_SwitchTexUnit(GL_TEXTURE1_ARB);
				shadowTarget->unbindTexture(0);
			}
			
			GL_RenderPath();
		}
		
		currentPass->finalize();
	}
	
	if(gfx_GLSLQuality.integer > 1 && gfx_postProcessing.integer && gfx_postProcEnabled.integer)
		GL_DoPostProcessing();
	
	if(vid_multisample.integer)
		GL_Disable(GL_MULTISAMPLE_ARB);
#ifdef DEBUG
	bboxCount=0;
#endif
	//// RESET ////
	//resetPass();
	
	std::for_each(unsortedRenderList.begin(), unsortedRenderList.end(), std::mem_fun(&GLRenderListItem::reset));

	std::for_each(sortedRenderList.begin(), sortedRenderList.end(), std::mem_fun(&GLRenderListItem::reset));
	
	std::for_each(effectsList.begin(), effectsList.end(), std::mem_fun(&GLRenderListItem::reset));
	
	//// CLEAR ////
	
	passes.clear();
	sortedRenderList.clear();
	unsortedRenderList.clear();
	effectsList.clear();
	lightList.clear();
	meshpool.clear();
	spritepool.clear();
	polypool.clear();
	lightpool.clear();
	
	//Console_DPrintf("Mesh Total: %d Culled: %d\n", renderer_meshcount, renderer_meshculled);
	//Console_DPrintf("Oct  Total: %d Culled: %d\n", oci, renderer_octculled);
	
	renderer_meshcount=0;
}