Archived

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

jevdsnny

Drawing on a texture

Recommended Posts

jevdsnny    122
Did anyone figure out how to draw on a texture? One example of a need for this is a moving map display- a base texture that has the border and some buttons, and a black area where you draw terrain highlights, other units, the direction of the player, etc. All of these map elements need to be draw in real time as things are changing in the game. Any ideas?

Share this post


Link to post
Share on other sites
ChrisE    184
Here is some code that will write pixels to the back buffer. You can use the same thing for any texture surface.


/* Structure to hold RGB format info */
typedef struct
{
RGBQUAD depth;
RGBQUAD Amount;
RGBQUAD Position;
} RGBINFO;
RGBINFO rgbInfo;



BOOL GetRGBFormat (PR_SURFACE Surface)
/* Get the RGB format of the surface so we can do color conversion later */
{
// Get the surface''s pixel format
D3DSURFACE_DESC d3dsd;
D3DFORMAT SurfFormat;
BYTE shiftcount;
PR_DWORD dwRBitMask;
PR_DWORD dwGBitMask;
PR_DWORD dwBBitMask;

ZeroMemory(&d3dsd, sizeof(d3dsd));
Surface->lpVtbl->GetDesc(Surface, &d3dsd);
SurfFormat = d3dsd.Format;

switch(d3dsd.Format)
{
case D3DFMT_R5G6B5:
dwRBitMask = 0xF800;
dwGBitMask = 0x07E0;
dwBBitMask = 0x001F;
break;

case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
dwRBitMask = 0x7C00;
dwGBitMask = 0x03E0;
dwBBitMask = 0x001F;
break;

case D3DFMT_R8G8B8:
dwRBitMask = 0xFF0000;
dwGBitMask = 0x00FF00;
dwBBitMask = 0x0000FF;
break;

case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
default:
dwRBitMask = 0xFF0000;
dwGBitMask = 0x00FF00;
dwBBitMask = 0x0000FF;
break;
}

//get red
shiftcount = 0;
while (!(dwRBitMask & 1))
{
dwRBitMask >>= 1;
shiftcount++;
}

rgbInfo.depth.rgbRed = (BYTE) dwRBitMask;
rgbInfo.Position.rgbRed = shiftcount;

if (PR_Globals.PR_OutputDevice.bitdepth == 32)
rgbInfo.Amount.rgbRed = 0;
else
rgbInfo.Amount.rgbRed = (dwRBitMask == 0x1f) ? 3 : 2;

//get green
shiftcount = 0;
while (!(dwGBitMask & 1))
{
dwGBitMask >>= 1;
shiftcount++;
}
rgbInfo.depth.rgbGreen =(BYTE)dwGBitMask;
rgbInfo.Position.rgbGreen = shiftcount;

if (PR_Globals.PR_OutputDevice.bitdepth == 32)
rgbInfo.Amount.rgbGreen = 0;
else
rgbInfo.Amount.rgbGreen = (dwGBitMask == 0x1f) ? 3 : 2;

//get Blue
shiftcount = 0;
while (!(dwBBitMask & 1))
{
dwBBitMask >>= 1;
shiftcount++;
}
rgbInfo.depth.rgbBlue =(BYTE)dwBBitMask;
rgbInfo.Position.rgbBlue = shiftcount;

if (PR_Globals.PR_OutputDevice.bitdepth == 32)
rgbInfo.Amount.rgbBlue = 0;
else
rgbInfo.Amount.rgbBlue = (dwBBitMask == 0x1f) ? 3 : 2;

return TRUE;
}




PR_UWORD MakePackedColor16 (PR_DWORD r, PR_DWORD g, PR_DWORD b)
{
PR_UWORD col;

col = (PR_UWORD)(((r >> rgbInfo.Amount.rgbRed) << rgbInfo.Position.rgbRed)|
((g >> rgbInfo.Amount.rgbGreen) << rgbInfo.Position.rgbGreen)|
((b >> rgbInfo.Amount.rgbBlue) << rgbInfo.Position.rgbBlue));
return col;
}


/* Same as above but returns a dword */
PR_UDWORD MakePackedColor32 (PR_DWORD r, PR_DWORD g, PR_DWORD b)
{
PR_UDWORD col;

col = (PR_UDWORD)(((r >> rgbInfo.Amount.rgbRed) << rgbInfo.Position.rgbRed)|
((g >> rgbInfo.Amount.rgbGreen) << rgbInfo.Position.rgbGreen)|
((b >> rgbInfo.Amount.rgbBlue) << rgbInfo.Position.rgbBlue));

return col;
}



void WriteDots16 (void)
{
PR_UWORD col16;
PR_UWORD *surface_bits16;
PR_DWORD x, y;
PR_DWORD pitch=0;

surface_bits16 = (PR_UWORD *)PR_LockSurface (PR_Globals.PR_BackBuffer, &pitch);
if (surface_bits16 == NULL)
PR_FatalError ("cannot lock back buffer", "oops");

/* Convert the 24 bit color to a 16 bit one */
col16 = MakePackedColor16 (255, 0, 0);

/* Pitch is given in bytes, but we are using words, so the pitch must be expressed as words too */
pitch >>= 1;

/* Start drawing all the points at once */
for (x = 0; x < 320; x++)
for (y = 0; y < 240; y++)
{
surface_bits16[x + y*pitch] = col16;
}

PR_UnlockSurface (PR_Globals.PR_BackBuffer);
}



void WriteDots32 (void)
{
PR_UDWORD col32;
PR_UDWORD *surface_bits32;
PR_DWORD x, y;
PR_DWORD pitch=0;

surface_bits32 = (PR_UDWORD *)PR_LockSurface (PR_Globals.PR_BackBuffer, &pitch);
if (surface_bits32 == NULL)
PR_FatalError ("cannot lock back buffer", "oops");

/* Convert the 24 bit color to a 32 bit one matching the back buffer pixel format */
col32 = MakePackedColor32 (255, 0, 0);

/* Pitch is given in bytes, but we are using dwords, so the pitch must be expressed as dwords too */
pitch >>= 2;

/* Start drawing all the points at once */
for (x = 0; x < 320; x++)
for (y = 0; y < 240; y++)
{
surface_bits32[x + y*pitch] = col32;
}

PR_UnlockSurface (PR_Globals.PR_BackBuffer);
}

...

if (PR_Settings.Use32Bit)
WriteDots32();
else
WriteDots16();


Share this post


Link to post
Share on other sites
jevdsnny    122
Thanks Chris, I will ty it out. This is probably a good topic to address in an example/tutorial- it''s a common task that game developers will need to execute.

Share this post


Link to post
Share on other sites