Skip to main content
gamedev.net
🔒 Locked

d3d7 texture problem

Started by 303 4 replies 700+ views
Original Post
303
303
i am doing a simple terrain engine and i would like to have textures generated from values of heightmap, but i can''t figure out why this code ain''t working: void TEXTURES:utPixel(LPDIRECTDRAWSURFACE7 pSurface, int x, int y, int r, int g, int b) { DDSURFACEDESC2 ddsd; ddsd.dwSize=sizeof(DDSURFACEDESC2); pSurface->GetSurfaceDesc(&ddsd); pSurface->Lock(NULL, &ddsd, 0, 0); DWORD lPitch=ddsd.lPitch; WORD* wDest=(WORD*)ddsd.lpSurface; wDest[x+y*lPitch]=RGB(r, g, b); pSurface->Unlock(0); } it doesn''t give me any errors, but doesn''t either write anything to my texture surface... i am using framework library.
mhkrause
mhkrause
First, you shouldn''t have a smiley face in your function''s name

But the wDest[x+y*lPitch] should be wDest[x+y*lPitch/sizeof(WORD)].

303
303
wow, i removed that smiley and now that function does work just fine!

yeah right... anyway, i did fix that function like you said, but still the result is same..

btw, i can render triangles with textures i am trying to edit with that putpixel function.. so problem doesn''t exist on texture initialization or anywhere like that.
ckillpack
ckillpack
quote:
Original post by 303


quote:

void TEXTURES:utPixel(LPDIRECTDRAWSURFACE7 pSurface, int x, int y, int r, int g, int b)
{
DDSURFACEDESC2 ddsd;

ddsd.dwSize=sizeof(DDSURFACEDESC2);
pSurface->GetSurfaceDesc(&ddsd);




Its good to get into the habit of zeroing all entries in structures you pass to DirectX, otherwise spurious things can happen (DirectX often interprets fields passed in). Also its a good idea to check the return state of functions.

However I don''t understand why you are getting the surface description for this surface when the information you require is returned by the Lock() call later.

In any case change the above code to

DDSURFACEDESC2 ddsd;
HRESULT hr;
ZeroMemory( &ddsd , sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
hr = pSurface->GetSurfaceDesc( &ddsd );
if (FAILED( hr ))
// Error: do something

ZeroMemory() is a DirectX function and FAILED is a standard Win32 macro.

quote:

pSurface->Lock(NULL, &ddsd, 0, 0);



This is personal preference but I always specify default flags for functions because I can''t remember the default behaviour of all DirectX functions! Viz Initially I thought your function parameters for Lock() were wrong and had to go and check in the SDK Help. But thats an aside really.

But again always check the result of the Lock function....

hr = pSurface->Lock( NULL , &ddsd , DDLOCK_SURFACEMEMORYPTR , NULL );
if (FAILED( hr ))
// Error: do something

quote:

DWORD lPitch=ddsd.lPitch;
WORD* wDest=(WORD*)ddsd.lpSurface;
wDest[x+y*lPitch]=RGB(r, g, b);



Right OK couple of questions. Is RGB your own macro or function? I ask because GDI defines an RGB macro which given Red, Green and Blue parameters of the type UBYTE in the range [0,255] returns the packed value in BGR format (DirectX packs in RGB format, that is B is in the LSB and R in the ''highest''). However remember you must look at the format of the surface to correctly determine the bit format of the pixel.

In addition the GDI''s RGB() macro returns a 32-bit value and you are trying to write to a 16-bit buffer. You will need to write your own packing function. I''ll assume that we have defined our own packing function, PackRGB(), that takes the RGB components and produces a packed 16-bit WORD in the correct format for the surface.

As pointed out by mhkrause the pitch is specified in bytes and you are trying to adjust a WORD pointer so you need to divide the pitch down by sizeof(WORD) (technically its 2 bytes).

So this is how it should look...

int lPitch = ddsd.lPitch / 2;
WORD pixel = PackRGB( r , g , b );
WORD* wDest = (WORD*)ddsd.lpSurface;
wDest[(y*lPitch)+x] = pixel;

So this is how I would write the complete function.... (I''m leaving in your GetSurfaceDesc() call for clarity, although as I mentioned it is strictly superfluous)

void TEXTURES::OutPixel( LPDIRECTDRAWSURFACE7 pSurface , int x , int y , int r , int g , int b)
{
DDSURFACEDESC2 ddsd;
HRESULT hr;

// Get the surface description
ZeroMemory( &ddsd , sizeof(ddsd) );
hr = pSurface->GetSurfaceDesc( &ddsd );
if (FAILED( hr ))
// Error: do something

// Lock the surface
hr = pSurface->Lock( NULL , &ddsd , DDLOCK_SURFACEMEMORYPTR , NULL );
if (FAILED( hr ))
// Error: do something

// Get info from the Lock (pitch and ptr)
WORD* wDest = (WORD*)ddsd.lpSurface;
int lPitch = ddsd.lPitch / 2;
// Generate the packed pixel from the r,g and b components
WORD pixel = PackRGB( r , g , b );
// Place it in the surface
wDest[(y*lPitch)+x] = pixel;

// Unlock
hr = pSurface->Unlock( NULL );
if (FAILED( hr ))
// Error: do something
}

I hope that you can understand my various ramblings it this proves of some use

Chris



Chris Killpack : ckillpack@ea.com
Technology Group : Bullfrog Productions Ltd
Chris Killpack : ckillpack@eaeurope.comTechnology Group : Bullfrog Productions Ltd
null_pointer
null_pointer
ckillpack: ZeroMemory is a windows.h-defined macro for memset:


#define ZeroMemory(pointer, size) memset((void*) pointer, 0, size);



Good Luck!


- null_pointer
Jeff K
Jeff K
Just call surface->GetDC() and use SetPixel().
(and surface->ReleaseDC() when you''re done)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.