D3D problem

Discussions related to graphics (2D and 3D), animation and games programming
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

The single variables I was referring to are in PYRAMID and the D3D9 library.

After some consideration i have decided that d3d11 is overly complicated! No surprise there then. I would like to start d3d9 by transposing the directxtutorial.com so that i can understand what is going on. The only problem is that i can not find a list of CONSTANTS with their NUMERICAL values.
Has anyone got one that they could post or can someone point me to a website that does?

Kind Regards
Ric
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Sorry i forgot to ask, does anyone have a working version of d3d9 that has the constants and definitions in it?
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
RichardRussell

Re: D3D problem

Post by RichardRussell »

Ric wrote: Sat 29 Feb 2020, 18:51 The single variables I was referring to are in PYRAMID and the D3D9 library.
As I'm sure you know, you are not supposed to be looking inside a library (other than for reasons of curiosity)! Libraries are opaque 'black boxes' and the only thing you should need to know about them is their public interface, in this case as defined in the main Help documentation. Because their code is 'private', libraries are invariably written to maximise performance rather than for clarity, so the code will often be highly abbreviated if you (unwisely) take a peek.

This is particularly relevant in the case of D3DLIB because the equivalent library in BBC BASIC for SDL 2.0 (ogllib) has a substantially identical public interface but the code inside has nothing in common with D3DLIB at all, because it's for OpenGL rather than Direct3D! If you looked at the library code you might conclude that writing a 3D graphics program that would run on both BB4W and BBCSDL would be very difficult, whereas in practice it's largely trivial.
The only problem is that i can not find a list of CONSTANTS with their NUMERICAL values.
Has anyone got one that they could post or can someone point me to a website that does?
Can you give an example of a constant that you need? Because the public interface of D3DLIB/ogllib is necessarily agnostic as regards Direct3D on the one hand and OpenGL on the other, you ought not to be needing constants that are specific to one or the other (using them could unnecessarily prevent your code working cross-platform). Having said that, many of the Direct3D9 constants can be found in the file D3D9.H which can be readily found using a Google search.
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Thank you to all who have replied so far. It is now clear that d3d9 is the correct path, I have complex objects spinning on screen, but with no directional light. I have tried the code for creating a light from the manual but I get bad DIM at

DIM lights%(0) 103

I understand this is reserving an array of 1 with 104 bytes.
Could anyone please explain the Bad DIM?

Kind regards

Ric
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
RichardRussell

Re: D3D problem

Post by RichardRussell »

Ric wrote: Mon 09 Mar 2020, 12:28I have tried the code for creating a light from the manual but I get bad DIM
In such circumstances I'd always recommend comparing your code with a known working example. In the case of the lighting engine one simple example is WORLD.BBC which is supplied as standard with BBC BASIC for Windows (in the EXAMPLES\GRAPHICS folder).

Another example, which also illustrates specular reflection from a shiny surface, is here (this example is supplied as standard with BBCSDL but not currently with BB4W; I intend to rectify that at the next release).
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Thanks Richard,
I have played around with different lighting effects now with some nice results, but there is one type i just cant get to work, and that is ambient lighting. All the other types show an object as though it were in space but in the real world the rear side of objects are lit. I have tried the following code (and more variations) but always come up with the same result. Ambient grey! What i really would like is for a dull version of the triangle with the vertex colours. Please can someone help?
Regards Ric

Code: Select all

      MODE 8
      INSTALL @lib$+"D3DLIB"

      DATA -1,-1,-1,0,0,1,&FF0000FF
      DATA 0,1,-1,0,0,1,&FFFF0000
      DATA 1,-1,-1,0,0,1,&FF00FF00

      D3Ddevice%        = 0                : REM      POINTER TO THE DIRECT3D DEVICE CREATED
      vertex_file$      = "TRIANGLE.FVF"   : REM      THE NAME OF THE FILE CONTAINING EACH GROUP OF TRIANGLES/OBJECT
      texture_file$     = "Export.BMP"     : REM      THE NAME OF THE FILE CONTAINING EACH TEXTURE

      bckgrd_colour%    = &FF000000        : REM      THE BACKGROUND COLOUR IN &AARRGGBB FORMAT
      camera_far        = 1000
      camera_near       = 1
      camera_zoom       = PI/4
      cull%             = 3                : REM            1 = NO CULLING          2 = ANTI_CLOCKWISE ONLY  3 = CLOCKWISE ONLY
      lighting%         = 1                : REM            0 = NO LIGHTING         1 = LIGHTING ENABLED
      num_lights%       = 1                : REM      NUMBER OF LIGHTS USED FOR THIS GROUP OF TRIANGLES/OBJECT
      num_of_vbuffers%  = 2                : REM      NUMBER OF VERTEX BUFFERS USED IN SCENE
      vertices%         = 3
      wnd_aspect_ratio  = 5/4

      DIM camera(2)                        : REM      POINTER TO ARRAY CONTAINING VECTOR XYZ FROM WHERE THE CAMERA LOOKS AT THE SCENE
      DIM light%(1)                        : REM      AN ARRAY OF DIRECT3D8 LIGHTING MODELS
      DIM material%(1)                     : REM      POINTER TO THE TYPE OF MATERIAL USED BY D3D9 :- MATT, SHINY ETC...
      DIM num_of_v%(1)                     : REM      NUMBER OF VERTICES IN THE B3D FILE AS RETURNED BY FN_load3d
      DIM obj_X_pos(1)                     : REM      OBJECT POSITION X
      DIM obj_Y_pos(1)                     : REM      OBJECT POSITION Y
      DIM obj_Z_pos(1)                     : REM      OBJECT POSITION Z
      DIM pitch(1)                         : REM      POINTER TO THE PITCH (X DEGREES) OF THE GROUP OF TRIANGLES/OBJECT
      DIM roll(1)                          : REM      POINTER TO THE ROLL (Z DEGREES) OF THE GROUP OF TRIANGLES/OBJECT
      DIM texture%(1)                      : REM      POINTER TO THE TEXTURES USED AS RETURNED BY FN_loadtexture
      DIM v_format%(1)                     : REM      FORMAT OF VERTICES IN THE B3D FILE AS RETURNED BY FN_load3d
      DIM v_size%(1)                       : REM      SIZE OF VERTICES IN BYTES IN THE B3D FILE AS RETURNED BY FN_load3d
      DIM vertex_buffer%(1)                : REM      POINTER TO THE BUFFER FOR EACH GROUP OF TRIANGLES/OBJECT :- OBJECT/TEXTURE
      DIM view(2)                          : REM      POINTER TO ARRAY CONTAINING VECTOR XYZ FROM WHERE THE 1ST PERSON LOOKS AT THE SCENE
      DIM yaw(1)                           : REM      POINTER TO THE YAW (Y DEGREES) OF THE GROUP OF TRIANGLES/OBJECT




      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END

      F% = OPENOUT"TRIANGLE.FVF"
      PROC4(vertices%)
      PROC4(&1C0052)
      
      FOR loop% = 1 TO vertices%
        READ p0,p1,p2,n0,n1,n2,c%
        PROC4(FN_f4(p0)):PROC4(FN_f4(p1)):PROC4(FN_f4(p2)):PROC4(FN_f4(n0)):PROC4(FN_f4(n1)):PROC4(FN_f4(n2)):PROC4(c%)
      NEXT

      CLOSE #F%

      D3Ddevice% = FN_initd3d(@hwnd%, cull%, lighting%)
      IF D3Ddevice% = 0 ERROR 100, "Can't initialise Direct3D"

      vertex_buffer%(0) = FN_load3d(D3Ddevice%, @dir$+vertex_file$, num_of_v%(0), v_format%(0), v_size%(0))
      IF vertex_buffer%(0) = 0 ERROR 100, "Can't load PYRAMID.B3D"

      REM vertex_file$      = "BASE.B3D"
      REM vertex_buffer%(1) = FN_load3d(D3Ddevice%, @dir$+vertex_file$, num_of_v%(1), v_format%(1), v_size%(1))
      REM IF vertex_buffer%(1) = 0 ERROR 100, "Can't load BASE.B3D"

      REM texture%(1) = FN_loadtexture(D3Ddevice%, @dir$+texture_file$)
      REM IF texture%(1) = 0 ERROR 100, "Can't load texture_file$"

      DIM light{(1)Type%, Diffuse{r%,g%,b%,a%}, Specular{r%,g%,b%,a%}, \
      \ Ambient{r%,g%,b%,a%}, Position{x%,y%,z%}, Direction{x%,y%,z%}, \
      \ Range%, Falloff%, Attenuation0%, Attenuation1%, Attenuation2%, \
      \ Theta%, Phi%}
      light%(0) = light{(0)}

      light{(0)}.Type% = 3               : REM directional light
      light{(0)}.Diffuse.r% = FN_f4(1)   : REM red component
      light{(0)}.Diffuse.g% = FN_f4(1)   : REM green component
      light{(0)}.Diffuse.b% = FN_f4(1)   : REM blue component
      light{(0)}.Direction.x% = FN_f4(300) : REM X component of direction
      light{(0)}.Direction.y% = FN_f4(0) : REM Y component of direction
      light{(0)}.Direction.z% = FN_f4(0) : REM Z component of direction

      light{(0)}.Ambient.r% = FN_f4(0.2) : REM red component
      light{(0)}.Ambient.g% = FN_f4(0.2) : REM green component
      light{(0)}.Ambient.b% = FN_f4(0.2) : REM blue component

      DIM material{Diffuse{r%,g%,b%,a%}, Ambient{r%,g%,b%,a%}, \
      \   Specular{r%,g%,b%,a%}, Emissive{r%,g%,b%,a%}, Power%}
      material%(0) = material{}

      material.Ambient.r% = FN_f4(1) : REM red component of colour
      material.Ambient.g% = FN_f4(1) : REM green component of colour
      material.Ambient.b% = FN_f4(1) : REM blue component of colour

      camera() = 0, 0, -6
      view() = 0, 0, 0
      REPEAT
        yaw() = TIME/100
        obj_X_pos() = 0
        PROC_render(D3Ddevice%, bckgrd_colour%, num_lights%, light%(), num_of_vbuffers%, material%(), texture%(), vertex_buffer%(), num_of_v%(), \
        \ v_format%(), v_size%(), yaw(), pitch(), roll(), obj_X_pos(), obj_Y_pos(), obj_Z_pos(), camera(), view(), camera_zoom, wnd_aspect_ratio, camera_near, camera_far)
      UNTIL INKEY(1)=0
      END

      DEF PROCcleanup

      FOR loop% = 0 TO num_of_vbuffers%-1
        texture%(loop%)       += 0:IF texture%(loop%)       PROC_release(texture%(loop%))
        vertex_buffer%(loop%) += 0:IF vertex_buffer%(loop%) PROC_release(vertex_buffer%(loop%))
      NEXT

      D3Ddevice%        += 0:IF D3Ddevice%        PROC_release(D3Ddevice%)

      ENDPROC

      DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
RichardRussell

Re: D3D problem

Post by RichardRussell »

Ric wrote: Wed 11 Mar 2020, 12:18 All the other types show an object as though it were in space but in the real world the rear side of objects are lit.
In the "real world" you will never get the kind of uniform 'ambient' light that Direct3D provides, corresponding to equal illumination from all directions; it's not physically realistic. If the rear sides of objects are lit it's only as a result of being illuminated by a source of light (even if indirectly such as by reflection or scattering).
I have tried the following code (and more variations) but always come up with the same result. Ambient grey!
I'm a little confused because in your code the ambient component of your light has equal values of R, G and B (0.2):

Code: Select all

      light{(0)}.Ambient.r% = FN_f4(0.2) : REM red component
      light{(0)}.Ambient.g% = FN_f4(0.2) : REM green component
      light{(0)}.Ambient.b% = FN_f4(0.2) : REM blue component
and the ambient component of your material also has equal values of R, G and B (1):

Code: Select all

      material.Ambient.r% = FN_f4(1) : REM red component of colour
      material.Ambient.g% = FN_f4(1) : REM green component of colour
      material.Ambient.b% = FN_f4(1) : REM blue component of colour
So surely the expected ambient colour is indeed grey (the product of the two)?
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Maybe I should have asked the question a different way.
When using diffuse light the face of an object moves in to total darkness when the incidence of the face normal and the light direction becomes more than 90 degrees (pi/2). As I said, this is ok if you are trying to assimilate space, but I am not. To solve this in my gui I set the ambient light to 0.3 and multiplied the diffuse light (divided the angle by 2 so that only normals completely opposing the light direction were nil light) by 0.7 and added the two together. I was hoping it was this easy with d3d9. I understand about scattering and reflection and the unrealistic aspect of totally uniform ambient light, but given that I would like to produce real time speed and not a Pixar movie, comprising is the only solution. In a d3d11 shader it is a simple equation, but I can not figure it out in d3d9, can you please help with this?
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023
RichardRussell

Re: D3D problem

Post by RichardRussell »

Ric wrote: Thu 12 Mar 2020, 09:42can you please help with this?
In any 3D application (OpenGL or DIrect3D) the most fundamental choice you have to make is whether to use the 'fixed function pipeline' or 'shaders'. The fixed function pipeline is much simpler in terms of coding, and is what the various BBC BASIC libraries support, but is limited in what it can achieve. Shaders are much more flexible, but are considerably more difficult from a coding perspective. So difficult, in fact, that I would expect many BBC BASIC programmers to find it too daunting (I have never attempted code a shader from scratch and wouldn't know where to start, not being a C programmer).

If you choose the fixed function pipeline then you must design your application with its capabilities and limitations in mind. The lighting model is relatively simple, but I would still have expected it to be adequate for most BBC BASIC applications. If you are trying to reproduce an effect similar to the indirect background illumination you would get from the sky, or from walls in a room etc., then can't you get fairly close either using ambient light or by positioning a few directional lights so that every surface gets lit by at least one of them (or both)?
divided the angle by 2 so that only normals completely opposing the light direction were nil light
That seems like a kludge and totally non-physical, I wouldn't expect the fixed function pipeline to support anything like that because it's not representative of how things work in the real world (and it offends my physics background!). I'd step back and think in terms of multiple light sources, perhaps including an ambient term.
Ric
Posts: 200
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

The "kludge" goes against my physics and mathematical background too, but it works remarkably well as an approximation of the real world light.
But that leads back to the origional question. If i have a cube which has all red vertices and i shine a diffuse light at it, the sides that are 90 degrees or more to the direction of light go black. How do i make them stay a darker shade of red using an ambient light source. If i use a lower level red light as the ambient light this would obviously work, but then i would have to change the ambient light for a blue cube etc..... not very practical! What is the answer?
Kind Regards Ric.

6502 back in the day, BB4W 2017 onwards, BBCSDL from 2023