D3D problem

Discussions related to graphics (2D and 3D), animation and games programming
RichardRussell
Posts: 232
Joined: Tue 15 Oct 2019, 09:10

Re: D3D problem

Post by RichardRussell »

Ric wrote:
Thu 12 Mar 2020, 19:07
What is the answer?
I should say at the outset that I am not an expert in this field, so there may be an element of the blind leading the blind! The following represents my (limited) understanding only.

The colour of an object may be defined in one (or more) of three ways: it may be specified 'per vertex' in the vertex description (e.g. in the FVF file), it may be specified in the material description (if there is a material) and it may be specified in a texture (if there is one). As a result, it can be necessary to tell Direct3D where the ambient component of the final colour originates.

By default (and I think this is where your program was failing) the source of the ambient component is the material, and indeed you did define a material for your object. But of course a material only provides a uniform colour over the entire object, so in this default case the ambient colour will also be uniform, which is not what you want.

In the specific case of your program, you want the ambient colour to depend on the vertex colour, not on the material, and since this is not the default you must tell Direct3D that you want a different behaviour. You do that as follows (here for D3D9):

Code: Select all

      D3DRS_AMBIENTMATERIALSOURCE = 147
      D3DMCS_COLOR1 = 1
      SYS !(!D3Ddevice%+228), D3Ddevice%, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1
(forgive the 'magic' number 228; I should have defined a structure containing D3Ddevice9's methods, but that was too much like hard work for the purposes of this simple illustration).

With the source of the ambient component now being the vertex colour, your program behaves as you wanted (I hope). I have deleted the material entirely in this case, because you don't need it:

Code: Select all

      MODE 8
      INSTALL @lib$+"D3D9LIB"

      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

      D3DRS_AMBIENTMATERIALSOURCE = 147
      D3DMCS_COLOR1 = 1

      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"
      SYS !(!D3Ddevice%+228), D3Ddevice%, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1

      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

      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
If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.

Ric
Posts: 46
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Thank you for that demo. The more small steps I take the bigger I can take in the future.
Regards Ric

Ric
Posts: 46
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

The "magic number 228" turned out to be the wrong one, had a look in the library file and changed it to 200 which works fine. The number 228 corresponds to "SetRenderState" in the list of methods i have, is the difference because the D3DLIB is written using D3D8 or am i barking up the wrong tree? If it is, where can i find the correct list of methods. Also the CreateVertexBuffer in the D3DLIB = 92 but in my list it would be 104.

Regards Ric

RichardRussell
Posts: 232
Joined: Tue 15 Oct 2019, 09:10

Re: D3D problem

Post by RichardRussell »

Ric wrote:
Mon 16 Mar 2020, 17:48
The "magic number 228" turned out to be the wrong one, had a look in the library file and changed it to 200 which works fine.
Of course it's not "the wrong one", indeed I have only today released version 6.13a of BBC BASIC for Windows in which I have deliberately added that statement to the WORLD.BBC example:

Code: Select all

      INSTALL @lib$+"D3D9LIB"

      pDevice% = FN_initd3d(@hwnd%, 1, 1)
      IF pDevice% = 0 ERROR 100, "Can't initialise Direct3D"
      SYS !(!pDevice%+228), pDevice%, 147, 1 : REM D3DRS_AMBIENTMATERIALSOURCE
It would be pretty serious (and silly) if I'd modified a supplied example incorrectly, but I didn't! If I change the number to 200 the program crashes spectacularly. :?
The number 228 corresponds to "SetRenderState" in the list of methods i have
And that is indeed the required function: the D3DRS_ constants all refer to that function: 'D3DRS' = 'Direct3D RenderState'.
is the difference because the D3DLIB is written using D3D8 or am i barking up the wrong tree?
D3DLIB does indeed use Direct3D 8, but that's not the library used by the program I listed here, nor is it the library used by WORLD.BBC. Both use D3D9LIB because I assumed that (having previously been using a much later version of Direct3D) you would want to use the latest version supported by the BB4W libraries.

If, as it seems, you prefer to use Direct3D 8 (and I don't understand why) I will not be in a position to provide as much assistance because of the difficulty of finding relevant documentation online for that old version.
If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.

Ric
Posts: 46
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

My appologies for invoking your wrath, but you presume too quickly. The only reason i am using D3DLIB and not D3D9LIB is because i have not got it. An update is obviously required.

Ric

RichardRussell
Posts: 232
Joined: Tue 15 Oct 2019, 09:10

Re: D3D problem

Post by RichardRussell »

Ric wrote:
Mon 16 Mar 2020, 21:15
The only reason i am using D3DLIB and not D3D9LIB is because i have not got it.
I find that hard to believe. The D3D9LIB and D3D9LIBA libraries were added to the BB4W distribution in version 6.10a, which was released on 6th April 2017. The last version not to have them was v6.02a, released more than four years ago, so if you really don't have them it would mean that you had not bothered to update BB4W since then.

If that's the case I wish I had known, because it has always been my policy not to provide support to users of BB4W and BBCSDL unless they first upgrade to the latest available version. I consider that a perfectly reasonable approach because I don't have earlier versions available here, so if users post or send code which is exhibiting some problem I can't run it in the same environment that they are. In any case their problem might originate from a bug that has since been fixed.

I thought that policy was well known but if not I'm pleased to have the opportunity to reiterate it here.
If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.

RichardRussell
Posts: 232
Joined: Tue 15 Oct 2019, 09:10

Re: D3D problem

Post by RichardRussell »

RichardRussell wrote:
Tue 17 Mar 2020, 11:38
The last version not to have them was v6.02a, released more than four years ago
I should add that the only 'v6' versions of BB4W not to come with the D3D9LIB and D3D9LIBA libraries were also the versions which suffered from the infamous 'string instability' bug (sometimes referred to as the Geoff Webb bug after the user who discovered it).

It was because of the potential for that bug to cause faults almost impossible to diagnose that I put so much effort into alerting users to it (I think I may even have sent an all-user email which is an extraordinarily rare event), and also to bump the version number of the next release to v6.10a to emphasise just how important upgrading was.

I would hope that the number of users who still have a copy with that bug (and hence don't have the D3D9 libraries) is zero!
If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.

Ric
Posts: 46
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

I have now decreased the total number without d3d9 by 1. Upgrade successful.

I have also now got a working version of my program in D3D9 :D

Is there a way to multiply two matrices together that already have FN_f4() elements?

Regards Ric

Ric
Posts: 46
Joined: Tue 17 Apr 2018, 21:03

Re: D3D problem

Post by Ric »

Here is the program as it stands.

In my search to understand i have translated all in to what i consider code that is easier to understand. The only problem is that it is unstable! 50% of the time when the program is closed it crashes, can someone with a higher knowledge of D3D9 help with this aspect?

https://1drv.ms/u/s!AqibHqCkE1VQ_AWKCR_ ... v?e=kErV5E

Regards Ric

RichardRussell
Posts: 232
Joined: Tue 15 Oct 2019, 09:10

Re: D3D problem

Post by RichardRussell »

Ric wrote:
Wed 18 Mar 2020, 16:55
Is there a way to multiply two matrices together that already have FN_f4() elements?
What size are your matrices? For 4x4 matrices there's D3DXMatrixMultiply for Direct3D 8 and glMultMatrixf for OpenGL. Despite neither of those libraries being what you are actually using, it seems at least possible that the functions would work in practice, because how could they tell that your matrices are D3D9 matrices rather than D3D8 or OpenGL matrices?! I suppose it is possible that the very act of loading a D3D8 or OpenGL DLL could interfere with the operation of D3D9. It would require experimentation.
If you have a comment about the style or tone of this message please report it to the moderators by clicking the exclamation mark icon, rather than complaining on the public forum.