Sign in to follow this  
staticVoid2

surfaces question

Recommended Posts

staticVoid2    381
hi, I'm trying to set a palette on a offscreen surface and then retrieve the actual 32 bit color value from it to copy to a primary surface. The problem is that I have a function which at some point copies a pixel from one surface to another assuming that the data type is the same: function(UINT * surface1, UINT * surface2); eg surface1[0] = surface2[0] Is there any way to get the 32 bit color value from the surface memory of the offscreen surface?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by staticVoid2
hi, I'm trying to set a palette on a offscreen surface and then retrieve the actual 32 bit color value from it to copy to a primary surface. The problem is that I have a function which at some point copies a pixel from one surface to another assuming that the data type is the same:

function(UINT * surface1, UINT * surface2);

eg surface1[0] = surface2[0]

Is there any way to get the 32 bit color value from the surface memory of the offscreen surface?
Yes, but it involves a large switch() statement, with one case for each D3DFORMAT you want to support.

Also, what do you mean a "palette"? Do you mean D3DFORMAT_P8? Because paletteised surfaces aren't supported on any recent card.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Ah, that makes it a bit easier then. You can grab the pixel format for each surface and use that. Something like (Off the top of my head, untested):

// Lock the surface
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
pSurface->Lock(NULL, &desc, 0, NULL);

// Get some useful values
BYTE* pBits = (BYTE*)desc.lpSurface;
DWORD nRShift = ShiftFromMask(desc.ddpfPixelFormat.dwRBitMask);
DWORD nGShift = ShiftFromMask(desc.ddpfPixelFormat.dwGBitMask);
DWORD nBShift = ShiftFromMask(desc.ddpfPixelFormat.dwBBitMask);

DWORD dwPixel = 0; // Output pixel in xxrrggbb format


for(UINT y=0; y<desc.dwHeight; ++y)
{
BYTE* pRow = pBits + desc.lPitch * y;
for(UINT x=0; x<desc.dwWidth; ++x)
{
DWORD in = 0;

// Stride of one pixel depends on bit count
if(desc.ddpfPixelFormat.dwRGBBitCount == 32)
{
// Pixels are 4 bytes
in = *(DWORD*)pRow;
pRow += 4;

dwPixel |= ((in & desc.ddpfPixelFormat.dwRBitMask)>>nRShift)<<24;
dwPixel |= ((in & desc.ddpfPixelFormat.dwGBitMask)>>nGShift)<<16;
dwPixel |= ((in & desc.ddpfPixelFormat.dwBBitMask)>>nBShift)<<8;
}
else if(desc.ddpfPixelFormat.dwRGBBitCount == 24)
{
// Pixels are 3 bytes - Note: Not sure if this reads the bytes in the correct order
in |= ((DWORD)pRow[0])<<0;
in |= ((DWORD)pRow[1])<<8;
in |= ((DWORD)pRow[2])<<16;
pRow += 3;

dwPixel |= ((in & desc.ddpfPixelFormat.dwRBitMask)>>nRShift)<<24;
dwPixel |= ((in & desc.ddpfPixelFormat.dwGBitMask)>>nGShift)<<16;
dwPixel |= ((in & desc.ddpfPixelFormat.dwBBitMask)>>nBShift)<<8;
}
else if(desc.ddpfPixelFormat.dwRGBBitCount == 16)
{
// Pixels are 2 bytes
in = *(WORD*)pRow;
pRow += 2;

dwPixel |= ((in & desc.ddpfPixelFormat.dwRBitMask)>>nRShift)<<24;
dwPixel |= ((in & desc.ddpfPixelFormat.dwGBitMask)>>nGShift)<<16;
dwPixel |= ((in & desc.ddpfPixelFormat.dwBBitMask)>>nBShift)<<8;
}
}
}



And ShiftFromMask is:

DWORD ShiftFromMask(DWORD dwMask)
{
for(DWORD i=0; i<32; ++i)
{
if(dwMask & (1<<i))
return i;
}
return 32; // Should never happen
}




Actually, if your source format is actually a palettised surface, you can just read the palette with IDirectDrawSurface7::GetPalette

Although, I'd recommend against DirectDraw, you get this sort of thing for free with Direct3D...

Share this post


Link to post
Share on other sites
staticVoid2    381
but I take it there's no way to blt a surface to another which has a different bit-depth? and would it be overall more efficient to use palettised surfaces for storing textures because some textures im using only require 16 colors

Quote:

Although, I'd recommend against DirectDraw, you get this sort of thing for free with Direct3D...


I'm using directdraw mostly for learning purposes, I know direct3d is faster but I think of It as cheating mostly - when I found out that it done texture mapping, z-buffering, clipping etc. all for you it just put me off, I hate to think what a 3d engine does for you.

#include "3dengine.h"

int main() {
MakeACoolGame();
}

Share this post


Link to post
Share on other sites
staticVoid2    381
I think I might just add another parameters on the function:



function(UINT * surface1, void * surface2, int bitsFlag, PALETTEENTRY * palette) {

int bitShift = 4;

if(palette != NULL) {
switch(bitsFlag) {
case 1:
// similar to 4
break;
case 4:
{
if(bitShift == 4) bitShift = 0;
else bitShift = 4;
surface1[a] = palette[surface2[a] >> bitShift & 15];
}
break;
case 8:
surface1[a] = palette[surface2[a]];
break;
}
}

} else {
if(bitFlag == 32)
surface1[a] = surface2[a]
}








somthing like that, I know ive missed out 16 and 24 bit but you get the idea, although it would probaly slow down my texture mapping function to a crawl to add that extra code in for evey pixel.

[Edited by - staticVoid2 on February 20, 2008 4:27:11 PM]

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by staticVoid2
but I take it there's no way to blt a surface to another which has a different bit-depth?
It's been years since I used DirectDraw (I ditched it shortly after DDraw 7 came out), but if the surface Blt() function doesn't handle pixel format conversion (And it wouldn't surprise me if it doesn't), you'll have to do it yourself. DirectDraw is designed to be as low level as possible, so if the Blt() function does do format conversion, every DirectDraw driver would have to support it.

Quote:
Original post by staticVoid2
and would it be overall more efficient to use palettised surfaces for storing textures because some textures im using only require 16 colors
I'm not really sure. You won't get any hardware acceleration either way though. It's possibly slower to use palettised surfaces because there's an extra lookup for each pixel, and memory savings aren't really anything to worry about.

Quote:
Original post by staticVoid2
I'm using directdraw mostly for learning purposes, I know direct3d is faster but I think of It as cheating mostly - when I found out that it done texture mapping, z-buffering, clipping etc. all for you it just put me off, I hate to think what a 3d engine does for you.

#include "3dengine.h"

int main() {
MakeACoolGame();
}
Ha, if only [smile]
Using DirectDraw for learning purposes is fine, so long as you realise that DDraw doesn't have any hardware acceleration at all (On all but a few specialised graphics cards) - so your graphics card doesn't matter at all, and that D3D is much easier for most things. If you're using DirectDraw for learning about rasterisation and the like, then sure, go for it - that's how I started with DirectX stuff.

Share this post


Link to post
Share on other sites
staticVoid2    381
Quote:

and memory savings aren't really anything to worry about.


but say I had a 800x600 texture as a 32-bit surface, would that not require around 1.8MB of video memory? and what if you have a 16MB graphics card? that would mean you could only store around 8 of these textures without using system memory.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by staticVoid2
but say I had a 800x600 texture as a 32-bit surface, would that not require around 1.8MB of video memory? and what if you have a 16MB graphics card? that would mean you could only store around 8 of these textures without using system memory.
DirectDraw isn't hardware accelerated, so it wouldn't use any graphics memory, it uses system memory.
In any case, 1.8MB would be just over 10% of the total vram, and you're not going to have 10 of them around are you?

If you want to support systems with a 16MB graphics card, go ahead - but then you could argue you should support Windows 95 / 98, since that's the sort of era you'd get a 16MB graphics card in.

Share this post


Link to post
Share on other sites
staticVoid2    381
Quote:

DirectDraw isn't hardware accelerated, so it wouldn't use any graphics memory, it uses system memory.


why does it give the option between video and surface memory when creating surfaces then?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by staticVoid2
Quote:

DirectDraw isn't hardware accelerated, so it wouldn't use any graphics memory, it uses system memory.


why does it give the option between video and surface memory when creating surfaces then?
Ok, I'll rephrase that. The surface can be in video memory, but there's little or no support for hardware blitting, so the data will be transferred to system memory and blitted on the CPU. And in Vista it's not even kept in video memory (Since DirectDraw is emulated).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this