Archived

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

Dave2001

D3D - Alpha in textures

Recommended Posts

Dave2001    122
HELP! I have no clue how to make a texture that uses alpha (more than one bit). Can someone please tell me how to create an alpha texture? Also, it would help to know how I can load a grayscale bitmap into it. Dave2001, MAILTO(Forrester6@msn.com);

Share this post


Link to post
Share on other sites
Goodlife    122
Hi Dave,
I was in your shoes about two days again-- and Mr. GameMaker didn't help much, either. However, off a visualbasic site, I got this, and it made my textures work fine:

There is a very EASY way to put alpha onto a texture. With the DirectX SDK (are you using directx?) there is a utility called the DirectX Texture Tool. With it, you can load a bitmap, and then load a greyscale image, and it merges them into 4444 format-- which means you lose some color depth, but this seems to be the only way directX supports alpha textures.

When you save with the color tool, it turns your new image into a .DDS file. The DDS file contains the bits of the graphic, plus a DDSURFACEDESC2 header in the front of it. Once you use DirectX Texture Tool to make a DDS texture, you can use this code snippet to load it onto a surface:


LPDIRECTDRAWSURFACE LoadDDS(HINTANCE instance, LPDIRECTDRAW lpdd, char *name) {
short ifile;
long code,skip;
long readlen;
char *bytes,*bptr,*hold,*last;
LPDIRECTDRAWSURFACE AlphaSurface;
LPDIRECTDRAWSURFACE NewSurface;
HRSRC finder;
HGLOBAL res;

NewSurface=NULL;

// Load the file into a memory array. Check first if it is a
// resource, and if not, see if it exists as a file.

finder=FindResource(instance,name,RT_RCDATA);
if (finder!=NULL) {
res=LoadResource(instance,finder);
bytes=bptr=last=(char*)LockResource(res);
last+=SizeofResource(instance,finder);
}
else {
ifile=open(name,O_BINARY|O_RDONLY);
if (ifile==-1) {
// Could not find a resource OR a file,
// so return NULL.
return NULL;
}
bytes=bptr=last=malloc(filelength(ifile));
read(ifile,bytes,filelength(ifile));
last+=filelength(ifile);
close(ifile);
}

code=*(long*)bptr;bptr+=4;

// The first doubleword in the file in an indicator to see if
// it is a .DDS file. So chekc that:

if (code==0x20534444) {

// Note that I am using DDSURFACEDESC, not DDSURFACEDESC2.
// Because of this, I have to load things in manually.
// If you are using DDSURFACEDESC2, you can just copy
// sizeof(DDSURFACEDESC2) bytes into your surface desc,
// and be ready to go.

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);

hold=bptr;
skip=*(long*)bptr;bptr+=4;

// Fill up DDSURFACEDESC manually, since I am not using
// DDSURFACEDESC2.

ddsd.dwFlags=*(long*)bptr;bptr+=4;
ddsd.dwHeight=*(long*)bptr;bptr+=4;
ddsd.dwWidth=*(long*)bptr;bptr+=4;
ddsd.lPitch=*(long*)bptr;bptr+=4;
ddsd.dwBackBufferCount=*(long*)bptr,bptr+=4;
ddsd.dwMipMapCount=*(long*)bptr,bptr+=4;
ddsd.dwAlphaBitDepth=*(long*)bptr,bptr+=4;
ddsd.dwReserved=*(long*)bptr,bptr+=4;
ddsd.lpSurface=*(long*)bptr,bptr+=4;
memcpy(&ddsd.ddckCKDestOverlay,bptr,sizeof(DDCOLORKEY));bptr+=sizeof(DDCOLORKEY);
memcpy(&ddsd.ddckCKDestBlt,bptr,sizeof(DDCOLORKEY));bptr+=sizeof(DDCOLORKEY);
memcpy(&ddsd.ddckCKSrcOverlay,bptr,sizeof(DDCOLORKEY));bptr+=sizeof(DDCOLORKEY);
memcpy(&ddsd.ddckCKSrcBlt,bptr,sizeof(DDCOLORKEY));bptr+=sizeof(DDCOLORKEY);
memcpy(&ddsd.ddpfPixelFormat,bptr,sizeof(DDPIXELFORMAT));bptr+=sizeof(DDPIXELFORMAT);
memcpy(&ddsd.ddsCaps,bptr,sizeof(DDSCAPS));bptr+=sizeof(DDSCAPS);

bptr=hold+skip;
readlen=last-bptr;

// Now, using that surfacedesc I loaded from the file,
// make a temporary surface that I can BLT from. I do
// this so that I get a nice dithered surface. I could
// copy the file bytes exactly, but then the color loss
// shows up much more.

ddsd.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY;
hRes=lpdd->lpVtbl->CreateSurface(lpdd,&ddsd,&AlphaSurface,NULL);
AlphaSurface->lpVtbl->Lock(AlphaSurface,NULL,&ddsd,DDLOCK_WAIT,0);
memcpy(ddsd.lpSurface,bptr,readlen);
AlphaSurface->lpVtbl->Unlock(AlphaSurface,NULL);

// Okay, our 'alpha' surface is all loaded up with the info
// from the file. Now we want to make a surface that we're
// REALLY going to use.

AlphaTextureDesc.dwFlags=DDSD_CAPS|DDSD_PIXELFORMAT|DDSD_WIDTH|DDSD_HEIGHT;
AlphaTextureDesc.ddsCaps.dwCaps=DDSCAPS_TEXTURE;
AlphaTextureDesc.dwWidth=ddsd.dwWidth;
AlphaTextureDesc.dwHeight=ddsd.dwHeight;

lpdd->lpVtbl->CreateSurface(lpdd,&AlphaTextureDesc,&NewSurface,NULL);

// Okay, BLT our temporary surface onto the new one. The
// nice dithering effects of BltFast make it look a little
// better than if we just copied it.

hRes=NewSurface->lpVtbl->BltFast(NewSurface,0,0,AlphaSurface,NULL,DDBLTFAST_WAIT);

// Free up our temporary alpha surface. We don't need it
// any more.

AlphaSurface->lpVtbl->Release(AlphaSurface);
}
else {
// The file was not a DDS file, so return NULL.
return NULL;
}

// Now free up our data area...
free(bytes);

// And return the surface. All you need to do now is query this
// surface for a texture handle, and use that handle when rendering
// triangles.
return NewSurface;
}

You could also manually load the surface if you wanted to, but then you would have to do your own converting from whatever file format you use to 4444 format.

I recommend using the directX texture tool, and then loading it, with either this function, or something similar.

Hope this helps!

...OH yes, and I nearly forgot. If you want to store the texture as a resource, you have to store it as type RCDATA, since no existing resource format covers .DDS files.


-- Goodlife

-----------------------------
Those whom the gods would destroy, they first drive mad.
--DirectX design team official motto

Edited by - goodlife on July 24, 2000 10:29:22 AM

Edited by - Goodlife on July 24, 2000 10:30:56 AM

Edited by - Goodlife on July 24, 2000 10:33:39 AM

Share this post


Link to post
Share on other sites
Shinkage    595
Or if you want to know how to add an alpha channel for your own purposes, then the source for the DXTex utility is available in the DirectX SDK. I found it quite useful.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
i found www.mr-gamemaker.com to be a lot of help with this.

They have tutorial that shows you how to load in a normal un alpha bitmap and then add an alpha channel to it.There are also functions to set the alpha channel in a number of different ways.

IT teaches you what the code is actually doing too.

Share this post


Link to post
Share on other sites