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
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