Archived

This topic is now archived and is closed to further replies.

b612

Lightmaps in Quake 3 .bsp

Recommended Posts

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[i]);

     m_pLightmaps[i]->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[i].bytes[p][q][0],lightm[i].bytes[p][q][1],lightm[i].bytes[p][q][2]);
	  }
     }
     TextureSurface->UnlockRect();
     TextureSurface->Release();
}
 
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. Thanks for any help.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
good luck too :D

i''m not very far on my D3D renderer, but i''ll try and help wherever i can...

Share this post


Link to post
Share on other sites