d3d sprites

Advanced game related topics
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

d3d sprites

Post by coma »

A question for all the directx coders. (I know that some peoples here are using directx with pb).

I'm trying to use ID3DXSPRITE.
For the moment, it works fine, I use D3DXCreateTextureFromFile (from d3dx9.dll) to load a bitmap, and I draw it to the screen with the draw method.

But how can I have directly access to the graphic datas ?
for example, if I want to create my own texture using CreateTexture, and then put my own bitmap on it, or to change pixels color values or alpha values ?
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Re: d3d sprites

Post by traumatic »

coma wrote: But how can I have directly access to the graphic datas ?
for example, if I want to create my own texture using CreateTexture, and then put my own bitmap on it, or to change pixels color values or alpha values ?
I never used any of the d3dx-functions myself as they are just too big for
my liking (static and dll) but the manual says (ok, it's the one from the dx8-sdk) :

ID3DXSprite::Draw

Code: Select all

HRESULT Draw(
  LPDIRECT3DTEXTURE8 pSrcTexture,
  CONST RECT* pSrcRect,
  CONST D3DXVECTOR2* pScaling,
  CONST D3DXVECTOR2* pRotationCenter,
  FLOAT Rotation,
  CONST D3DVECTOR2* pTranslation,
  D3DCOLOR Color
);
So you should be able to use any texture you want and also write
directly to the surface using LockRect() / UnlockRect().

Or is your question about how to create a texture yourself, without d3dx ?
Good programmers don't comment their code. It was hard to write, should be hard to read.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

thanks traumatic.
Well, I can create an empty texture with this :

Code: Select all

d3dDevice\CreateTexture(64,64, 1, #D3DUSAGE_RENDERTARGET,  #D3DFMT_A8R8G8B8,  #D3DPOOL_DEFAULT,  @D3DTexture, #NULL)
but after this, how can I draw in this texture ? (draw a pixel, put a purebasic image...)
(I'm confused with the texture/surface concept in dx9, what are the differences ?)
How can I access datas with LockRect/UnlockRect, concretely ?

I never used any of the d3dx-functions myself as they are just too big for
my liking (static and dll) but the manual says (ok, it's the one from the dx8-sdk) :
I'd like to get rid of this big d3dx9.dll. For the moment I need it to load textures, load meshes, and for matrice functions (but I know that I can use yours D3DX Replacement Functions for this :D )
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

I don't have the time right now, but I'll make you a short example
later tonight. Promised! :)


EDIT: it's later now, so here we go...


People who know me also know that I'm not a real fan of giving away
properly working copy&paste-compatible code. This is just to give you
the idea, I'm sure you'll figure the rest out on your own! ;)

(If not, you can always come back and ask of course)

Code: Select all

Procedure CreateTexture(*device.IDirect3DDevice8, width.l, height.l, color.l)
  texture.IDirect3DTexture8
  If *device\CreateTexture(width, height, 0, 0, #D3DFMT_A8R8G8B8 , #D3DPOOL_MANAGED, @texture) = #D3D_OK
    rect.D3DLOCKED_RECT
  
    If texture\LockRect(0, @rect, 0, 0) <> #D3D_OK 
      ; we're (hopefully) using a 32bit display,
      ; therefore using 4 bytes per pixel
      ;
      ; ( 4 => 32bit  , 3 => 24bit; 2 = 16bit )
      bpp.b = 4
  
      *dest = rect\pBits
      pitch = rect\pitch/bpp
  
      For x=0 To width-1
        For y=0 To height-1 Step 4
          PokeL(*dest+(x + (pitch * y)) * bpp, color)
        Next
      Next
  
      texture\UnlockRect(0)
    EndIf
    ProcedureReturn texture 
  Else
    ProcedureReturn #False
  EndIf 
EndProcedure
This is for DX8 but shouldn't be too different in DX9.
I wrote this more or less from memory so I hope it works.
The code is supposed to draw horizontal lines onto the texture-surface.
There're are better ways than using Poke, but this way is just easier to understand I think.

Regarding your question about textures vs. surfaces:
There's a quite good explanation in the DX-SDK-Helpfile.
Basically imagine a surface as the 2-dimensional image-data whereas
a texture 'wraps' the surface, containing u- and v- coordinates.

No, that's not a good example - better have a look into the helpfile :roll:
Good programmers don't comment their code. It was hard to write, should be hard to read.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

BTW: You used D3DPOOL_DEFAULT and I used D3DPOOL_MANAGED.
D3DPOOL_DEFAULT is the only way to go if you want to use the texture
as the render-target (as you wanted to according to your code).

...just wanted to say this is absolutely correct! Don't let yourself get puzzled! :D
Good programmers don't comment their code. It was hard to write, should be hard to read.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

works perfectly ! you're great.

I don't need to use D3DUSAGE_RENDERTARGET for this, so no problem, I can use D3DPOOL_MANAGED.

I continue my experiments with directx9... (and I will ask for your help if I have another problem :) )



(for the difference between texture and surface, if the texture contains the uv, why do we use texture\LockRect to access data, and not surface\LockRect ? Is it not for multiple "layers" ? > a texture can have multiple surfaces, or something like that ?)
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

I continue my experiments with directx9... (and I will ask for your help if I have another problem :) )
Yes, of course - no problem!
(for the difference between texture and surface, if the texture contains the uv, why do we use texture\LockRect to access data, and not surface\LockRect ? Is it not for multiple "layers" ? > a texture can have multiple surfaces, or something like that ?)
Internally, Direct3D stores textures as surfaces.

The first parameter of LockRect() specifies the level, ie. if you are using mip-mapping,
you can access the other parts too. This all is really hard to explain for me since
english is not my native tongue (good excuse, eh? :lol:).

However, if you were about to lock the surface that's fine - you'd still have to make
a texture from the surface because all you can do with a plain surface is to 'blit' it to
the screen (or write to it).

If you want to use the surface in 3D (and that's what Direct3D is about ;))
you need a texture.

So it's like

Code: Select all

TEXTURE
|___SURFACE
       |____different LEVELS

I guess I'll get stoned to death for this explanation but I really don't know how
to explain it better...

If I got you right: No, this has nothing to do with multi-texturing (hint for that:
SetTextureStageState()).


I have some english books, maybe I'll find some good (english) explanations
for you tommorrow.

I hope that helped so far...
Good programmers don't comment their code. It was hard to write, should be hard to read.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

well, its works, so I don't try to understand for the moment...

This all is really hard to understand for me since english is not my native tongue (good excuse, eh? ).

thanks again.
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

coma wrote:This all is really hard to understand for me since english is not my native tongue (good excuse, eh? ).
LOL! :lol:

BTW, is anyone of you able to pronounce "SetTextureStageState" fast and fluently?
I really wonder what kind of weed they were smoking over there at Redmond...
Good programmers don't comment their code. It was hard to write, should be hard to read.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

Ok, now, I want to load an image with loadimage() and copy it on my texture.
I do it like that :

Code: Select all

  LoadImage(0,"texture.bmp")
  UseImage(0)
  StartDrawing(ImageOutput())
  For x=0 To 127
    For y=0 To 127
      color=Point(x,y)
      color=RGB(Blue(Color),Green(Color),Red(Color)) | $ff000000
      PokeL(*dest+(x + (pitch * y)) * 4, color ) 
    Next 
  Next  
  StopDrawing() 
But I'm not sure that it's the fastest way do to this :
firstly, I need to swap the red and blue values.
secondly, I use the point() function.

I can't use peek (or asm) to get the colors of the image, cause I don't have the memory address of this image.

with sprites, it's possible to do "*source = DrawingBuffer()", but I can't use sprites here, cause I don't use purebasic openscreen.

any suggestion ?
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

You could go the GetDIBits() route

Example: viewtopic.php?t=8347

But personally I'd alter it kind of like this:

Code: Select all

[...]
          *img = AllocateMemory(ImageWidth * ImageHeight * 3)
       
          bmi.BITMAPINFO
          bmi\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
          bmi\bmiheader\biWidth       = ImageWidth
          bmi\bmiheader\biHeight      = ImageHeight
          bmi\bmiheader\biPlanes      = 1
          bmi\bmiheader\biBitCount    = 24
          bmi\bmiheader\biCompression = #BI_RGB
          bmi\bmiheader\biSizeImage   = (bmi\bmiHeader\biWidth * bmi\bmiHeader\biHeight * bmi\bmiHeader\biBitCount / 8)-1
         
          GetDIBits_(hDC, hBmp, 0, ImageHeight, *img, bmi, #DIB_RGB_COLORS)
and later on...

Code: Select all

For x=0 To ImageWidth-1
  For y=0 To ImageHeight-1
    CopyMemory(*img + (x + (pitch * y)) * imgbpp, *dest + (x + (pitch * y) ) * bpp, 4 )
  Next
Next
where imgbpp is the amount of bytes/pixel of your image. This will
be 3 in most cases (24bit images).
Good programmers don't comment their code. It was hard to write, should be hard to read.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

Thank youuuuuuuuuu.

Just a little thing :

bmi\bmiheader\biHeight = -ImageHeight

without the -, the image is flipped vertically, as mentioned in the other post.
coma
Enthusiast
Enthusiast
Posts: 164
Joined: Fri Aug 15, 2003 3:46 am
Location: Canada

Post by coma »

Help Traumatic !!

Is it possible to keep the alpha values of a png file in an image ??

If not, how can I do this without d3dx9.dll ? Code my own png decoder ?...
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

Sorry, I don't know whether PB's PNG-Loader supports alphachannels or not -
maybe someone else can answer that.

However, if you decide to manually extract the alphavalues, I'd recommend
you to start with TGA as it's much easier to handle. Did you have a look at 'd3dutil.cpp'?
Maybe you can find something useful in there (I'm at work right now so I can't check)
Good programmers don't comment their code. It was hard to write, should be hard to read.
Post Reply