Lightmaps in Quake 3 .bsp

Started by
9 comments, last by b612 19 years, 11 months ago
I''m having some difficulty getting lightmapping working in my Quake 3 bsp renderer. Everything seems to be working fine, except the lightmaps are being rendered in a weird way - they''re showing up as rainbows of colors. Here is the code I''m using to load them:

for (i = 0; i < numberOfLightMaps; i++)
{
     fread(&lightm, 1, sizeof(tBSPLightmap), fp);

     m_pD3DDev->CreateTexture(128,128,1,0,D3DFMT_X8R8G8B8,
			D3DPOOL_MANAGED,&m_pLightmaps);

     m_pLightmaps->GetSurfaceLevel(0, &TextureSurface);

     D3DLOCKED_RECT pLockedRect;
     RECT rectangleToLock;
     rectangleToLock.top = 0;
     rectangleToLock.left = 0;
     rectangleToLock.bottom = 128;
     rectangleToLock.right = 128;				
     TextureSurface->LockRect(&pLockedRect,&rectangleToLock,0 );
     DWORD* Data = (DWORD*)(pLockedRect.pBits);
	 
     for(int q = 0; q<128; q++) 	 
     {			 
	  for(int p = 0; p<128; p++)
	  {
	      Data[q+(p*(pLockedRect.Pitch/4))] = D3DCOLOR_XRGB(lightm.bytes[p][q][0],lightm.bytes[p][q][1],lightm.bytes[p][q][2]);
	  }
     }
     TextureSurface->UnlockRect();
     TextureSurface->Release();
}
 </pre> 

and then I set the texture stage states using:

0,D3DTSS_COLORARG1,D3DTA_TEXTURE
0,D3DTSS_COLOROP,D3DTOP_SELECTARG1
1,D3DTSS_COLORARG1,D3DTA_TEXTURE
1,D3DTSS_COLORARG2,D3DTA_CURRENT
1,D3DTSS_COLOROP,  D3DTOP_MODULATE4X

but they''re showing up as small rainbow colored patches.

BTW:
I''m also having another problem: When looping through and rendering the vertices, I have to make sure the current poly''s lightmap index isn''t below 0. This was giving me an access violation. I''ve never heard of this happening in a Quake 3 viewer before. <img src="sad.gif" width=15 height=15 align=middle>

Thanks for any help.
  </i>  
Advertisement
Are you sure you are using the right texture coordinates for the lightmaps?

It sounds like you may be using the same texture coordinates that are used for the base texture for the lightmaps too.

IIRC, the lightmaps have their own set of texture coordinates.

[edited by - yzzid on May 20, 2004 6:35:00 AM]
-dizzyGame Institute InternPlease rate me. :)
I thought that might be the problem, too, but I think everything is correct. Here is my structure for holding vertices:

D3DXVECTOR3 pos;
D3DXVECTOR3 normal;
float u,v;
float lu,lv;

and I use this FVF to describe it:

(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2)

and set the texture coordinate indexes during rendering:

0,D3DTSS_TEXCOORDINDEX,0
1,D3DTSS_TEXCOORDINDEX,1
0, D3DTSS_ALPHAOP, D3DTOP_DISABLE
1, D3DTSS_ALPHAOP, D3DTOP_DISABLE
0, D3DTSS_COLOROP, D3DTOP_SELECTARG1
0, D3DTSS_COLORARG1, D3DTA_TEXTURE
SetTexture(0), etc
1, D3DTSS_COLORARG1, D3DTA_TEXTURE
1, D3DTSS_COLORARG2, D3DTA_CURRENT
1, D3DTSS_COLOROP, D3DTOP_MODULATE
SetTexture(1), etc

this is starting to make me mad.
OK Sounds like you code is correctly displaying them. The problem might be when you create the textures. Try saving the lightmaps to disk in BMP or JPG format and checking them in a paint program. Maybe you will see if you are extracting them improperly.
-dizzyGame Institute InternPlease rate me. :)
Thanks very much for the replies.

Most of them are coming out looking almost like static on a television. Any idea what''s wrong with my loading code?
I did it a slightly different way using D3DXLoadSurfaceFromMemory.
Here is my code.
Please forgive the messiness.
It took me a long time to come up with this.

unsigned char *pLightmapData = m_pLightmapData;for(i = 0; i < nNumLightmaps; ++i){	int j;	unsigned char *pData = pLightmapData;	for(j = 0; j < nLightmapSize; j += 3)	{		// swap red and blue		unsigned char temp = pData[j];		pData[j] = pData[j + 2];		pData[j + 2] = temp;	}		m_pLightmaps[i] = NULL;	HRESULT hr;	hr = D3DXCreateTexture(m_pDevice, LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, 0, D3DUSAGE_RENDERTARGET,		D3DFMT_R8G8B8, D3DPOOL_DEFAULT, &m_pLightmaps[i]);	if(FAILED(hr))		MessageBox(NULL, "Failed", "Error", MB_OK);	LPDIRECT3DSURFACE9 pSurface;	hr = m_pLightmaps[i]->GetSurfaceLevel(0, &pSurface);	if(FAILED(hr))		MessageBox(NULL, "Failed", "Error", MB_OK);	RECT rect = {0, 0, LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT};	hr = D3DXLoadSurfaceFromMemory(pSurface,		NULL,		NULL,		pLightmapData,		D3DFMT_R8G8B8,		LIGHTMAP_WIDTH * 3,		NULL,		&rect,		D3DX_FILTER_LINEAR,		0);	D3DXFilterTexture(m_pLightmaps[i], NULL, 0, D3DX_FILTER_LINEAR);	if(FAILED(hr))		MessageBox(NULL, "Failed", "Error", MB_OK);	pSurface->Release();	pLightmapData += nLightmapSize;}



[edited by - yzzid on May 20, 2004 7:16:50 PM]
-dizzyGame Institute InternPlease rate me. :)
Again, thank you very much for the help.

Could you explain what m_pLightmapData and nLightMapSize are?
I''m assuming nLightMapSize is just the size of one ''tBSPLightmap'' struct, but I''m not sure.

Thanks again!
i had the exact same problem with my lightmaps - however the fix was quite easy :D

the thing is that in the lightmap data, you only have RGB. however, when using D3DFMT_X8R8G8B8, D3D allocates memory for the alpha channel, even though you are not using it.

here is what i do:

D3DLOCKED_RECT lockedRect;IDirect3DSurface9 *pLightmapSurface;unsigned char *pSurface;DWORD dwCharsPerRow;for (i = 0; i < m_numLightmaps; i++)	{		fread(&pLightmaps[i], 1, sizeof(sBSPLightmap), fp);		// create lightmap texture		ChangeGamma((unsigned char *)pLightmaps[i].imageData, 128*128*3, 5);		D3DXCreateTexture(m_pDevice, 128, 128, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &m_pLightmaps[i].lightmap);		m_pLightmaps[i].lightmap->GetSurfaceLevel(0, &pLightmapSurface);		pLightmapSurface->LockRect(&lockedRect, NULL, 0);		pSurface = static_cast<unsigned char*>(lockedRect.pBits);		dwCharsPerRow = lockedRect.Pitch;		for (DWORD r = 0; r < 128; r++)		{			DWORD dwIndex = r * dwCharsPerRow;			for (DWORD c = 0; c < 128; c++)			{				pSurface[dwIndex + c*4 + 0] = pLightmaps[i].imageData[r][c][2];				pSurface[dwIndex + c*4 + 1] = pLightmaps[i].imageData[r][c][1];				pSurface[dwIndex + c*4 + 2] = pLightmaps[i].imageData[r][c][0];				pSurface[dwIndex + c*4 + 3] = 255;			}		}		pLightmapSurface->UnlockRect();		D3DXFilterTexture(m_pLightmaps[i].lightmap, 0, 0, D3DX_FILTER_LINEAR);	}


[edited by - akdjr on May 20, 2004 12:00:31 AM]

[edited by - akdjr on May 20, 2004 12:01:37 AM]
It works!

Many thanks to akdjr and yzzid for their help!

I''m off to add PVS.
Cool.

Good luck.
PVS is a bitch to debug.
I should be resurrecting my Quake 3 viewer in the coming days.
Although, lately I noticed it is acting kind of flaky lately.
Anyway, if you need any help don't hesitate to ask.

[edited by - yzzid on May 21, 2004 5:54:32 AM]
-dizzyGame Institute InternPlease rate me. :)

This topic is closed to new replies.

Advertisement