Post

 Resources 

Console

Home | Profile | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 VBGamer
 VBGamer
 DirectDraw Lighting?

Note: You must be registered in order to post a reply.

Screensize:
UserName:
Password:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkInsert EmailInsert Image Insert CodeInsert QuoteInsert List Spell Checker
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

   Insert an File
Check here to include your profile signature.
Check here to subscribe to this topic.
    

T O P I C    R E V I E W
Amrazek Posted - Mar 24 2003 : 6:21:47 PM
Don't go and explode on me! I'm perfectly aware that DirectDraw doesn't support lighting... Natively. I want to write my own functions to do it for me, using GetLockedArray() and modifying the memory.

However, before I continue with what I already have, I'd like to get assured on a few things:

1) The longs in the array returned from GetLockedArray() are NOT normal colors, and I have to somehow convert them.

2) The array from GetLockedArray() will have the same dimensions as the screen, right?

3) Some of the lighting code from www.Directx4vb.com will work, with slight modification.

4) I CANNOT make DLL calls while I have a surface locked, correct?

Thanks!
-Amrazek
15   L A T E S T    R E P L I E S    (Newest First)
Amrazek Posted - Jun 19 2003 : 1:09:23 PM
According to the DirectX7 SDK, the long argument in the ColorGet functions is supposed to be between 0 and 255...

color
Color from which the red component is retrieved. A value between 0 and 255.

?
Amrazek Posted - Jun 15 2003 : 12:11:18 PM
I downloaded the source code to the Dx/DD fullscreen tutorial and tried this out, and got the same results, so it's probably not the initialization...
Amrazek Posted - Jun 15 2003 : 12:51:58 AM
Hmm... Interesting... I'll post the portion of GfxEngine that contains that:
  
'; Return the R component of a DD long
Public Function GetColorRed(lngDXColor As Long) As Single
    GetColorRed = DX.ColorGetRed(lngDXColor)  
End Function
  
'; Return the G component of a DD long
Public Function GetColorGreen(lngDXColor As Long) As Single
    GetColorGreen = DX.ColorGetGreen(lngDXColor)  
End Function
  
'; Return the B component of a DD long
Public Function GetColorBlue(lngDXColor As Long) As Single
    GetColorBlue = DX.ColorGetBlue(lngDXColor)  
End Function
  

That looks alright to me... Perhaps something in the initialize sub is wrong?
  
Private Sub DDInit(ByRef myForm As Long, ByRef iScreenWidth As Integer, ByRef _  
                   iScreenHeight As Integer, ByRef iBPP As Integer, ByRef _  
                   iColorKey As Integer, ByRef bUseVideoMemory As Boolean, _  
                   ByRef bytFontRed As Byte, ByRef bytFontGreen As Byte, _  
                   ByRef bytFontBlue As Byte, ByRef bSetFontTransparent As _  
                   Boolean, ByRef iBackBufferCount As Integer, ByRef _  
                   bGammaController As Boolean, ByRef bytGammaRed As Byte, _  
                   ByRef bytGammaGreen As Byte, ByRef bytGammaBlue As Byte)  
On Error Resume Next
  
    Set DX = New DirectX7  
    Set DD = DX.DirectDrawCreate("")  
  
    'Full screen exclusive mode always  
    Call DD.SetCooperativeLevel(myForm, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)  
  
    DD.SetDisplayMode iScreenWidth, iScreenHeight, iBPP, 0, DDSDM_DEFAULT  
  
    'Fill out primary surface description  
    Ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT  
    If Not bSetFontTransparent = True Then
        Ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX Or DDSCAPS_SYSTEMMEMORY  
    Else
        Ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX  
    End If
  
    '\\ Allow D3D capability  
    Ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_3DDEVICE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX Or DDSCAPS_VIDEOMEMORY  
    Ddsd1.lBackBufferCount = iBackBufferCount 'Could be more than one backbuffer  
  
    'ddsFront is the primary surface  
    Set ddsFront = DD.CreateSurface(Ddsd1)  
        InitializeLighting  
  
    If bGammaController Then
        Set GammaController = ddsFront.GetDirectDrawGammaControl  
        GammaController.GetGammaRamp DDSGR_DEFAULT, OriginalRamp  
    End If
  
    'Attach the backbuffer  
    Dim Caps As DDSCAPS2  
    If Not bUseVideoMemory = True Then
        Caps.lCaps = DDSCAPS_BACKBUFFER Or DDSCAPS_SYSTEMMEMORY  
    Else
        Caps.lCaps = DDSCAPS_BACKBUFFER  
    End If
  
    Set ddsBack = ddsFront.GetAttachedSurface(Caps)  
        ddsBack.GetSurfaceDesc Ddsd2  
  
        Set D3D = DD.GetDirect3D  
        Set DEV = D3D.CreateDevice("IID_IDirect3DHALDevice", ddsBack)  
  
  
    DDSetFont "Calligraphic 421 BT", 12, RGB(bytFontRed, bytFontGreen, bytFontBlue)  
  
    If bSetFontTransparent Then
        ddsBack.SetFontTransparency True
    End If
  
    '\\ set up screen variables  
    With Screen  
        .nWidth = iScreenWidth  
        .nHeight = iScreenHeight  
        .nBPP = iBPP  
  
        .bytFontRed = bytFontRed  
        .bytFontGreen = bytFontGreen  
        .bytFontBlue = bytFontBlue  
        .bFontTransparent = bSetFontTransparent  
  
        .iColorKey = iColorKey  
        .bUseVideoMemory = bUseVideoMemory  
  
        .iBackBufferCount = iBackBufferCount  
        .bGammaController = bGammaController  
        .bytGammaRed = bytGammaRed  
        .bytGammaGreen = bytGammaGreen  
        .bytGammaBlue = bytGammaBlue  
    End With
  
    If bGammaController Then
        SetGamma bytGammaRed, bytGammaGreen, bytGammaBlue  
    End If
  


Also of note: I'm using 2 backbuffers, and am using the gamma controller. BPP = 16, and the ColorKey is black. Another thing: GfxEngine is actually a whole DirectDraw engine I wrote, and is a DLL.

This is more difficult than I initially thought... Oh well, much knowledge to be gained.

-Amrazek
Eric Coleman Posted - Jun 15 2003 : 12:16:08 AM
Did you write the "GetColor" functions in the GfxEngine class? A value of "h31" should translate to value of "1.0" in 16 bit color.
Amrazek Posted - Jun 14 2003 : 2:23:23 PM
The pixel format is beginning to make sense. I was using this:
  
            '\\ retrieve pixel (0,0)  
            Dim pBytes(0 To 1) As Byte
  
                pBytes(0) = BytMem(0 * 2, 0)  
                pBytes(1) = BytMem(0 * 2 + 1, 0)  
  
                CopyMemory pDest, pBytes(0), 2  
  
            '\\ Output the data  
            Debug.Print "Output:"  
            Debug.Print "   Returned: "; CStr(pDest)  
            Debug.Print "   Hex:      "; Hex(pDest)  
            Debug.Print "   Byte1:    "; CStr(pBytes(0))  
            Debug.Print "   Byte2:    "; CStr(pBytes(1))  
            Debug.Print "   retR:     "; GfxEngine.GetColorRed(pDest)  
            Debug.Print "   retG:     "; GfxEngine.GetColorGreen(pDest)  
            Debug.Print "   retB:     "; GfxEngine.GetColorBlue(pDest)  
  

I made a solid blue rectangle on the screen and tried various things with it. The results that were outputted were:
  
Output:
   Returned: 31  
   Hex:      1F  
   Byte1:    31  
   Byte2:    0  
   retR:      0  
   retG:      0  
   retB:      0.1215686  
  


I see that the blue channel is at least returning something, but I don't know what it means... I have no idea of what format retB is in.

-Amrazek
Eric Coleman Posted - Jun 07 2003 : 12:30:19 PM
Try using some solid color surfaces first to help you get a better idea of how the bytes are laid out in the byte array. You could try an all blue surface, and then output a few bytes in HEX, then you could easily combine them with the windows Calculator to see how things are organized. For example, if you use Debug.print to get something like this... 0 1F 0 1F, you would use the number "001F001F" in Calculator to convert to a binary of "0000 0001 1111 0000 0000 0001 1111", and that would show you the color is only using 6 Bits. If you explore a bit more, you'll understand how things are packed together.
Amrazek Posted - Jun 06 2003 : 10:47:13 PM
I believe I understand now -- didn't know that it was only 2 bytes and that you could use CopyMemory to combine them. That helps a lot =)

However, the value returned is still incorrect... Perhaps I need to do some kind of a conversion on it?
Eric Coleman Posted - Jun 04 2003 : 9:55:51 PM
.GetColorRed/Green/Blue expects a LONG, the data from the byte array is a BYTE. If you are in 16bit mode, two bytes make a color for each pixel, in 24bit mode, then its 3 bytes to a pixel, and in 32 bit mode, its 4 bytes to a pixel.

A 32bit example would look something like this after you use GetLockedArray
  
Dim B(0 to 3) as Byte, L as Long
B(0)= LckdArray(0+0,0)  
B(1)= LckdArray(0+1,0)  
B(2)= LckdArray(0+2,0)  
B(3)= LckdArray(0+3,0)  
CopyMemory(L, B(0), 4)  'copy 4 bytes to the long  
Debug.Print dx.ColorGetRed(L)  
Debug.Print dx.ColorGetGreen(L)  
Debug.Print dx.ColorGetBlue(L)  
  


A 16bit example would be only two bytes to the byte array, B(0 to 1), and then copymemory would be CopyMemory(L, B(0)), 2).

Of course, there are faster ways to do this. I'm just trying to show you how the bytes are arranged. The pixel at location (0,0) would be LckdArray(0,0), LckdArray(1,0), LckdArray(2,0), LckdArray(3,0), the pixel at location (1,0) would be LckdArray(4,0), LckdArray(5,0), LckdArray(6,0), LckdArray(7,0).
Amrazek Posted - Jun 04 2003 : 9:26:57 PM
My hopeful idea didn't work... I was thinking that .GetLockedArray returned the width of the surface * 3, for BGR... However, .ColorGetRed/Green/Blue didn't work... Red returned 1, the others returned 0. Frustrating
Amrazek Posted - Jun 04 2003 : 6:16:12 PM

I've got the changing my RGB color into a DXRGB color conversion working. However, I cannot change a DXRGB color back into RGB... I've tried .ColorGetRed / Blue / Green, but that requires a value of 0-255. As I understand it, the values in GetLockedArray ARE up to 255, but it's in a different format... There are 3 bytes per pixel... Unless... Just maybe... I've got an idea. I'll have to go check it out right now.

-Amrazek
Eric Coleman Posted - Jun 04 2003 : 09:41:41 AM
Look at that link I provided in my last message. For GetLockedArray(), I think you are supposed to use an array of Bytes.
Amrazek Posted - Jun 03 2003 : 9:47:54 PM
I'm having difficulty returning the color of a pixel... I just can't seem to figure out how to change the DirectDraw long value back into RGB...
Amrazek Posted - May 30 2003 : 3:18:16 PM
I put this project off a little bit, for lack of understanding, but my interest has been rekindled. So far, I've got the code to set the correct color implemented and working, but the second part is returning a color back to its original state. I've lost the source for this project, but I had added a few capabilites to my general game engine that will allow me to rebuild it in about a half hour. I've got a couple theories going; I'll add a reply on anything that I've found.

-Amrazek
Eric Coleman Posted - Apr 14 2003 : 4:08:09 PM
check out the discussion about color here

To sum it all up, you need to find the color masks for your surface, and then use those to extract the data returned from GetLockedArray. If you have the individual R,G,B color components, then you can decrease each one individualy, or if you want to be really accurate, you could convert the RGB color to a different color space and change the luminance or brightness.

This is what YCC conversion would look like using RGB values 0 to 255,
  
'Convert R,G,B to YCC
Y = 0.299 * R + 0.587 * G + 0.114 * B  
Cb = -0.1687 * R - 0.3313 * G + 0.5 * B + 128  
Cr = 0.5 * R - 0.4187 * G - 0.0813 * B + 128  
  
'Decrease the brightness by 10%
Y = Y * 0.9  
  
'Convert back to RGB color
R = Y + 1.402 * (Cr - 128)  
G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)  
B = Y + 1.772 * (Cb - 128)  
  

Amrazek Posted - Apr 13 2003 : 10:38:22 AM

I feel like I've run into a brick wall. I'm using GetLockedArray() to get a pointer to the [backbuffer's] surface memory, and so far all that works. Changes are reflected in the surface, as they should be.

The problem is that I cannot obtain the 'true' color of a pixel, nor specify my own color. This is because I cannot determine the RGB of the pixel -- it's in a format that I don't know how to change. How can I convert the raw data into a usable RGB format?

Mind as well hit two birds with one stone... Is there a 'darkening' formula I can use? Just changing the RGB of a pixel to a lower value doesn't darken it; it changes the color completely.

Thanks!
Amrazek

VBGamer © Go To Top Of Page
This page was generated in 0.5 seconds. Snitz Forums 2000

Copyright © 2002 - 2004 Eric Coleman, Peter Kuchnio , et. al.