Exemplo n.º 1
0
// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
	GameInfo *info = 0;

	auto iter = info_.find(gamePath);
	if (iter != info_.end()) {
		info = iter->second;
		if ((info->wantFlags & wantFlags) != wantFlags) {
			// Need to start over. We'll just add a new work item.
			goto again;
		}
		if (thin3d && info->iconDataLoaded) {
			SetupTexture(info, info->iconTextureData, thin3d, info->iconTexture, info->timeIconWasLoaded);
			info->iconDataLoaded = false;
		}
		if (thin3d && info->pic0DataLoaded) {
			SetupTexture(info, info->pic0TextureData, thin3d, info->pic0Texture, info->timePic0WasLoaded);
			info->pic0DataLoaded = false;
		}
		if (thin3d && info->pic1DataLoaded) {
			SetupTexture(info, info->pic1TextureData, thin3d, info->pic1Texture, info->timePic1WasLoaded);
			info->pic1DataLoaded = false;
		}
		iter->second->lastAccessedTime = time_now_d();
		return iter->second;
	}

again:

	if (!info) {
		info = new GameInfo();
	}

	{
		lock_guard lock(info->lock);
		if (info->IsWorking()) {
			// Uh oh, it's currently in process.  It could mark pending = false with the wrong wantFlags.
			// Let's wait it out, then queue.
			WaitUntilDone(info);
		}
		info->wantFlags |= wantFlags;
		info->pending = true;
	}

	GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info);
	gameInfoWQ_->Add(item);

	info_[gamePath] = info;
	return info;
}
Exemplo n.º 2
0
void RenderThread::Init()
{
    for (int y = 0; y < GS_RESOLUTION_MAX_HEIGHT; ++y)
    {
        for (int x = 0; x < GS_RESOLUTION_MAX_WIDTH; ++x)
        {
            int pixel = (y * GS_RESOLUTION_MAX_WIDTH) + x;
            m_pFrameBuffer[pixel].red = m_pFrameBuffer[pixel].green =
                    m_pFrameBuffer[pixel].blue = 0x00;
            m_pFrameBuffer[pixel].alpha = 0xFF;
        }
    }

#ifndef __APPLE__
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        /* Problem: glewInit failed, something is seriously wrong. */
        Log("GLEW Error: %s\n", glewGetErrorString(err));
    }
    Log("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
#endif

    SetupTexture((GLvoid*) m_pFrameBuffer);
}
Exemplo n.º 3
0
void init(int argc, char **argv) {
	initWindow(&argc, argv);
	
	// 초기화
	glClearColor(0.5, 0.9, 1.0, 1.0);
	CreateTexture();
	SetupTexture();
}
Exemplo n.º 4
0
void Texture::LoadFromBuffer(char *buffer, unsigned int bufferLength)
{
    FileManager *fm = FileManager::CreateManager();
    GLubyte *textureData = fm->CreateBitmapData(buffer, bufferLength, &_texWidth, &_texHeight);
    
    _name = SetupTexture(textureData);
    _disposed = false;
}
Exemplo n.º 5
0
static void Render() {
  // LONG lines = ReadLineCounter();
  SetupLines(frameCount * 16);
  SetupTexture(colors[active], frameCount);
  // Log("twister: %ld\n", ReadLineCounter() - lines);

  WaitVBlank();
  CopListActivate(cp[active]);
  active ^= 1;
}
Exemplo n.º 6
0
Texture::Texture(string filename)
{
    
    FileManager *fm = FileManager::CreateManager();
    GLubyte *textureData = fm->CreateBitmapData(filename, &_texWidth, &_texHeight);
    
    _name = SetupTexture(textureData);
    _textureFilename = filename;
    _fromFile = true;
}
Exemplo n.º 7
0
void RenderQuad()
{
	SetupTexture();
	
	// Set stream source
	g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex) );
	g_pd3dDevice->SetFVF(VertexFVF) ;
	g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) ;

}
Exemplo n.º 8
0
// Runs on the main thread.
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
	GameInfo *info = 0;

	auto iter = info_.find(gamePath);
	if (iter != info_.end()) {
		info = iter->second;
		if ((info->wantFlags & wantFlags) != wantFlags) {
			// Need to start over. We'll just add a new work item.
			goto again;
		}
		if (thin3d && info->iconDataLoaded) {
			SetupTexture(info, info->iconTextureData, thin3d, info->iconTexture, info->timeIconWasLoaded);
			info->iconDataLoaded = false;
		}
		if (thin3d && info->pic0DataLoaded) {
			SetupTexture(info, info->pic0TextureData, thin3d, info->pic0Texture, info->timePic0WasLoaded);
			info->pic0DataLoaded = false;
		}
		if (thin3d && info->pic1DataLoaded) {
			SetupTexture(info, info->pic1TextureData, thin3d, info->pic1Texture, info->timePic1WasLoaded);
			info->pic1DataLoaded = false;
		}
		iter->second->lastAccessedTime = time_now_d();
		return iter->second;
	}

again:

	if (!info) {
		info = new GameInfo();
	}
	{
		lock_guard lock(info->lock);
		info->wantFlags |= wantFlags;
	}

	GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info);
	gameInfoWQ_->Add(item);

	info_[gamePath] = info;
	return info;
}
Exemplo n.º 9
0
void RenderThread::Init()
{
    m_bFirstFrame = true;

    for (int y = 0; y < GAMEBOY_HEIGHT; ++y)
    {
        for (int x = 0; x < GAMEBOY_WIDTH; ++x)
        {
            int pixel = (y * GAMEBOY_WIDTH) + x;
            m_pFrameBuffer[pixel].red = m_pFrameBuffer[pixel].green =
                    m_pFrameBuffer[pixel].blue = 0x00;
            m_pFrameBuffer[pixel].alpha = 0xFF;
        }
    }

#ifndef __APPLE__
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        /* Problem: glewInit failed, something is seriously wrong. */
        Log("GLEW Error: %s\n", glewGetErrorString(err));
    }
    Log("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
#endif

    glGenFramebuffers(1, &m_AccumulationFramebuffer);
    glGenTextures(1, &m_AccumulationTexture);
    glGenTextures(1, &m_GBTexture);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_GBTexture);
    SetupTexture((GLvoid*) m_pFrameBuffer);

    glBindFramebuffer(GL_FRAMEBUFFER, m_AccumulationFramebuffer);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_AccumulationTexture);
    SetupTexture(NULL);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
            m_AccumulationTexture, 0);
}
Exemplo n.º 10
0
int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(512, 512);
	glutCreateWindow("My Texture");

	glClearColor(1.0, 0.0, 0.0, 1.0);

	CreateTexture(); // create 2d image array
	SetupTexture(); // setup openGL texture

	glutDisplayFunc(myDisplay);
	glutIdleFunc(myDisplay);
	glutMainLoop();

	return 0;
}
Exemplo n.º 11
0
void glInternalFlush(u32 target) {
	u32 i;
	u32 param_base = REGS32(0x8020) & 0x007FFFFF;
	u32 background = (REGS32(0x808C) & 0x00FFFFF8) >> 1;
	u32 address = (param_base + background) & 0x007FFFFF;

	flushPrim();
	NewStripList();

	BACKGROUND((u32*)&VRAM[address]);

	flushPrim();
	NewStripList();

	glClearColor((float)REGS[0x8042] / 255.0f,
				 (float)REGS[0x8041] / 255.0f,
				 (float)REGS[0x8040] / 255.0f,
				 (float)REGS[0x8043] / 255.0f);
	glDepthMask(GL_TRUE);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (cfg.ListSorting) {
		qsort((void*)objList, objCount, sizeof(OBJECT), comp_func);
//		qsort((void*)objList,objCount,sizeof(OBJECT),listtypesort_func);
//		qsort((void*)objList,objCount,sizeof(OBJECT),transsort_func);
//		qsort((void*)objList,objCount,sizeof(OBJECT),punchsort_func);
	}

	glPushMatrix();

	switch (target) {
	case RENDER_TARGET_FRAMEBUFFER:
		glViewport(0, 0, 640, 480);
		glTranslatef(0.0f, 0.0f, -(float)RENDER_VIEW_DISTANCE);
		break;
	case RENDER_TARGET_TEXTURE:
	{
		glViewport(0, 0, 640, (REGS16(0x806E) - REGS16(0x806c) + 1));
		glScalef(1.0f, -1.0f, 1.0f);
		glTranslatef(0.0f, -480.0f, -(float)RENDER_VIEW_DISTANCE);
		break;
	}
	}

//	DEMUL_printf(">render scene (objCount=%d)\n",objCount);

	for (i = 0; i < objCount; i++) {
		OBJECT *obj = &objList[i];
		vCount = obj->vCount;

		if (vCount) {
			polygon = obj->polygon;

//			DEMUL_printf(">object %3d, dist = %6f, listtype = %d, pcw = %08X, isp = %08X, tsp = %08X, tcw = %08X\n",i,obj->midZ, obj->polygon.pcw.listtype, obj->polygon.pcw.all, obj->polygon.isp.all, obj->polygon.tsp.all, obj->polygon.tcw.all);

			if (polygon.tsp.usealpha && cfg.AlphaZWriteDisable)
				polygon.isp.zwritedis = 1;

			SetupShadeMode();
			SetupCullMode();
			SetupZBuffer();
			if (cfg.Wireframe) {
				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			} else {
				SetupAlphaTest();
				SetupAlphaBlend();
				SetupTexture();
				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
			}

			glDrawElements(GL_TRIANGLES, vCount, GL_UNSIGNED_INT, &pIndex[obj->vIndex]);
		}
	}
	glPopMatrix();

//	ProfileFinish(0);

	IRQ(0x0002);

	switch (target) {
	case RENDER_TARGET_FRAMEBUFFER:
		SwapBuffers(hdc);
		break;
	case RENDER_TARGET_TEXTURE:
	{
		u32 tw = REGS32(0x804C) << 2;
		u32 th = 512;
		glReadBuffer(GL_BACK);
		glBindTexture(GL_TEXTURE_2D, backbufname);
		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, tw, th, 0);
		isFramebufferRendered = 1;
		TextureAddress = REGS32(0x8060) & 0x007FFFFF;
		break;
	}
	}

//	DEMUL_printf(">render end\n");
//	DEMUL_printf(">frame summary (maxz=%f,minz=%f)\n",maxz,minz);

	maxz = -10000000.0f;
	minz = 10000000.0f;
	objCount = 0;
	vIndex = 0;
	vCount = 0;
	vVertex = 0;
}
Exemplo n.º 12
0
void CGSH_Direct3D9::SetRenderingContext(uint64 primReg)
{
	auto prim = make_convertible<PRMODE>(primReg);

	unsigned int context = prim.nContext;

	uint64 testReg = m_nReg[GS_REG_TEST_1 + context];
	uint64 frameReg = m_nReg[GS_REG_FRAME_1 + context];
	uint64 alphaReg = m_nReg[GS_REG_ALPHA_1 + context];
	uint64 zbufReg = m_nReg[GS_REG_ZBUF_1 + context];
	uint64 tex0Reg = m_nReg[GS_REG_TEX0_1 + context];
	uint64 tex1Reg = m_nReg[GS_REG_TEX1_1 + context];
	uint64 clampReg = m_nReg[GS_REG_CLAMP_1 + context];
	uint64 scissorReg = m_nReg[GS_REG_SCISSOR_1 + context];

	if(!m_renderState.isValid ||
		(m_renderState.primReg != primReg))
	{
		m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, ((prim.nAlpha != 0) && m_alphaBlendingEnabled) ? TRUE : FALSE);
	}

	if(!m_renderState.isValid ||
		(m_renderState.alphaReg != alphaReg))
	{
		SetupBlendingFunction(alphaReg);
	}

	if(!m_renderState.isValid ||
		(m_renderState.testReg != testReg))
	{
		SetupTestFunctions(testReg);
	}

	if(!m_renderState.isValid ||
		(m_renderState.zbufReg != zbufReg) ||
		(m_renderState.frameReg != frameReg))
	{
		SetupDepthBuffer(zbufReg, frameReg);
	}

	if(!m_renderState.isValid ||
		(m_renderState.frameReg != frameReg) ||
		(m_renderState.scissorReg != scissorReg))
	{
		SetupFramebuffer(frameReg, scissorReg);
	}

	if(!m_renderState.isValid ||
		(m_renderState.tex0Reg != tex0Reg) ||
		(m_renderState.tex1Reg != tex1Reg) ||
		(m_renderState.clampReg != clampReg))
	{
		SetupTexture(tex0Reg, tex1Reg, clampReg);
	}

	m_renderState.isValid = true;
	m_renderState.primReg = primReg;
	m_renderState.alphaReg = alphaReg;
	m_renderState.testReg = testReg;
	m_renderState.zbufReg = zbufReg;
	m_renderState.frameReg = frameReg;
	m_renderState.tex0Reg = tex0Reg;
	m_renderState.tex1Reg = tex1Reg;
	m_renderState.clampReg = clampReg;
	m_renderState.scissorReg = scissorReg;

	auto offset = make_convertible<XYOFFSET>(m_nReg[GS_REG_XYOFFSET_1 + context]);
	m_nPrimOfsX = offset.GetX();
	m_nPrimOfsY = offset.GetY();
	
	if(GetCrtIsInterlaced() && GetCrtIsFrameMode())
	{
		if(m_nCSR & CSR_FIELD)
		{
			m_nPrimOfsY += 0.5;
		}
	}
}
Exemplo n.º 13
0
//====================================================================================
//	PCache_FlushMiscPolys
//====================================================================================
BOOL PCache_FlushMiscPolys(void)
{
	int32				i;
	Misc_Poly			*pPoly;

	if (!MiscCache.NumPolys)
		return TRUE;

	if (!THandle_CheckCache())
		return GE_FALSE;

	// Set the render states
	if (AppInfo.CanDoMultiTexture)
	{
		AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
		AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
		D3DSetTexture(1, NULL);		// Reset texture stage 1
	}
	
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	  AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
	  D3DBlendFunc (D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
	  D3DBlendEnable(TRUE);

	// Sort the polys by handle
	SortMiscPolysByHandle();

	for (i=0; i< MiscCache.NumPolys; i++)
	{
		pPoly = MiscCache.SortedPolys[i];

		if (pPoly->Flags & DRV_RENDER_NO_ZMASK)		// We are assuming that this is not going to change all that much
			D3DZEnable(FALSE);
		else
			D3DZEnable(TRUE);

		if (pPoly->Flags & DRV_RENDER_NO_ZWRITE)	// We are assuming that this is not going to change all that much
			D3DZWriteEnable(FALSE);	
		else
			D3DZWriteEnable(TRUE);
									  
		if (pPoly->Flags & DRV_RENDER_CLAMP_UV)
			D3DTexWrap(0, FALSE);
		else
			D3DTexWrap(0, TRUE);

		if (!SetupTexture(0, pPoly->THandle, pPoly->MipLevel))
			return GE_FALSE;

		if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
			AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , FALSE);

		D3DTexturedPoly(&MiscCache.Verts[pPoly->FirstVert], pPoly->NumVerts);

		if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
			AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , TRUE);
	}

	// Turn z stuff back on...
	D3DZWriteEnable (TRUE);
	D3DZEnable(TRUE);
	
	MiscCache.NumPolys = 0;
	MiscCache.NumVerts = 0;

#ifdef SUPER_FLUSH
	AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FLUSHBATCH, 0);
	AppInfo.lpD3DDevice->EndScene();
	AppInfo.lpD3DDevice->BeginScene();
#endif

	return TRUE;
}
Exemplo n.º 14
0
//====================================================================================
//	RenderWorldPolys
//====================================================================================
static BOOL RenderWorldPolys(int32 RenderMode)
{
	World_Poly			*pPoly;
	int32				i;

	if(!AppInfo.RenderingIsOK)
	{
		return	TRUE;
	}
	switch (RenderMode)
	{	
		case RENDER_WORLD_POLYS_NORMAL:
		{
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );

			// Set the default state for the normal poly render mode for the world
			D3DBlendEnable(TRUE);
			D3DBlendFunc (D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
			
			// Get the first poly in the sorted list
			SortWorldPolysByHandle();
			
			for (i=0; i< WorldCache.NumPolys; i++)
			{
				pPoly = WorldCache.SortedPolys[i];

				if (pPoly->Flags & DRV_RENDER_CLAMP_UV)
					D3DTexWrap(0, FALSE);
				else
					D3DTexWrap(0, TRUE);

				if (!SetupTexture(0, pPoly->THandle, pPoly->MipLevel))
					return GE_FALSE;

				World_PolyPrepVerts(pPoly, PREP_WORLD_VERTS_NORMAL, 0, 0);

				D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);
			}
			
			break;
		}
		
		case RENDER_WORLD_POLYS_LMAP:
		{
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);

			D3DTexWrap(0, FALSE);

			D3DBlendEnable(TRUE);
			D3DBlendFunc (D3DBLEND_DESTCOLOR, D3DBLEND_ZERO);

			pPoly = WorldCache.Polys;
			BOOL	Dynamic = 0;

			for (i=0; i< WorldCache.NumPolys; i++, pPoly++)
			{

				if (!pPoly->LInfo)
					continue;

				// Call the engine to set this sucker up, because it's visible...
				D3DDRV.SetupLightmap(pPoly->LInfo, &Dynamic);

				if (!SetupLMap(0, pPoly->LInfo, 0, Dynamic))
					return GE_FALSE;

				World_PolyPrepVerts(pPoly, PREP_WORLD_VERTS_LMAP, 0, 0);

				D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);
				
				if (pPoly->LInfo->RGBLight[1])
				{
					AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, FALSE);

					D3DBlendFunc (D3DBLEND_ONE, D3DBLEND_ONE);				// Change to a fog state

					// For some reason, some cards can't upload data to the same texture twice, and have it take.
					// So we force Fog maps to use a different slot than the lightmap was using...
					pPoly->LInfo->THandle->MipData[0].Slot = NULL;

					if (!SetupLMap(0, pPoly->LInfo, 1, 1))	// Dynamic is 1, because fog is always dynamic
						return GE_FALSE;

					D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);
		
					D3DBlendFunc (D3DBLEND_DESTCOLOR, D3DBLEND_ZERO);		// Restore state

					if (AppInfo.FogEnable)
						AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , TRUE);
				}
			}
			break;
		}

		case RENDER_WORLD_POLYS_SINGLE_PASS:
		{
			// Setup texture stage states
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
									 
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); 
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE );
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
			//AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2 );
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );

			// Setup frame buffer blend modes
			D3DBlendEnable(TRUE);
			D3DBlendFunc (D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);

			// Set the default state for the normal poly render mode for the world
			D3DTexWrap(TSTAGE_0, TRUE);
			D3DTexWrap(TSTAGE_1, FALSE);

			// Sort the list for front back operation to get the least number of world texture misses
			SortWorldPolysByHandle();
			
			// Reset non lightmaps faces to 0
			WorldCache.NumPolys2 = 0;

			for (i=0; i< WorldCache.NumPolys; i++)
			{
				BOOL	Dynamic = 0;

				pPoly = WorldCache.SortedPolys[i];

				if (!pPoly->LInfo)
				{
					// Put gouraud only polys in a seperate list, and render last
					WorldCache.SortedPolys2[WorldCache.NumPolys2++] = pPoly;
					continue;
				}

				if (pPoly->Flags & DRV_RENDER_CLAMP_UV)
					D3DTexWrap(TSTAGE_0, FALSE);
				else
					D3DTexWrap(TSTAGE_0, TRUE);

				if (!SetupTexture(TSTAGE_0, pPoly->THandle, pPoly->MipLevel))
					return GE_FALSE;				

				// Call the engine to set this sucker up, because it's visible...
				D3DDRV.SetupLightmap(pPoly->LInfo, &Dynamic);

				if (!SetupLMap(TSTAGE_1, pPoly->LInfo, 0, Dynamic))
					return GE_FALSE;
					
				// Prep the verts for a lightmap and texture map
				World_PolyPrepVerts(pPoly, PREP_WORLD_VERTS_SINGLE_PASS, TSTAGE_0, TSTAGE_1);

				if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
						AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , FALSE);

				// Draw the texture
				D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);

				if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
						AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , TRUE);

				// Render any fog maps
				if (pPoly->LInfo->RGBLight[1])
				{
					D3DBlendFunc (D3DBLEND_ONE, D3DBLEND_ONE);				// Change to a fog state

				#if (TSTAGE_0 == 0)
					AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
					AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
				#else
					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
				#endif

					// For some reason, some cards can't upload data to the same texture twice, and have it take.
					// So we force Fog maps to use a different slot other than what the lightmap was using...
					pPoly->LInfo->THandle->MipData[0].Slot = NULL;

					if (!SetupLMap(TSTAGE_1, pPoly->LInfo, 1, 1))	// Dynamic is 1, because fog is always dynamic
						return GE_FALSE;

					D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);
	
					// Restore states to the last state before f*g map
				#if (TSTAGE_0 == 0)
					AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
					AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
	
					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE );
				#else
					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE );
					AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2 );
				#endif

					D3DBlendFunc (D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
				}
				
				
			}
			
			// Setup for any non-lightmaped faces faces, turn tmu1 off
		#if (TSTAGE_0 == 0)
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
			AppInfo.lpD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		#else
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
			AppInfo.lpD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
		#endif

			// Render all the faces without lightmaps
			for (i=0; i< WorldCache.NumPolys2; i++)
			{
				BOOL	Dynamic = 0;

				pPoly = WorldCache.SortedPolys2[i];

				if (pPoly->Flags & DRV_RENDER_CLAMP_UV)
					D3DTexWrap(TSTAGE_0, FALSE);
				else
					D3DTexWrap(TSTAGE_0, TRUE);

				if (!SetupTexture(TSTAGE_0, pPoly->THandle, pPoly->MipLevel))
					return GE_FALSE;				

				// Prep verts as if there was no lightmap
				World_PolyPrepVerts(pPoly, PREP_WORLD_VERTS_NORMAL, TSTAGE_0, TSTAGE_1);

				if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
						AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , FALSE);

				// Draw the texture
				D3DTexturedPoly(&WorldCache.Verts[pPoly->FirstVert], pPoly->NumVerts);

				if ( (pPoly->Flags & DRV_RENDER_POLY_NO_FOG) && AppInfo.FogEnable) // poly fog
					AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE , TRUE);
			}

			break;						 
		}

		default:
			return FALSE;
	}


	return TRUE;
}