Please visit ecere.org for my current cross platform Object Oriented, GUI & hardware-accelerated 3D Graphics technology.
Ok... we deeply discussed vectors and normals in the 3D mathematics tutorial, so here are some implementations:
float VEC_DotProduct(_3D Vector1, _3D Vector2) { return (Vector1.x*Vector2.x+Vector1.y*Vector2.y+Vector1.z*Vector2.z); } _3D VEC_CrossProduct(_3D Vector1, _3D Vector2) { return P3D(Vector1.y*Vector2.z-Vector1.z*Vector2.y, Vector1.z*Vector2.x-Vector1.x*Vector2.z, Vector1.x*Vector2.y-Vector1.y*Vector2.x); } void VEC_Normalize(_3D * Vector) { float m=sqrt(Vector->x*Vector->x+Vector->y*Vector->y+Vector->z*Vector->z); Vector->x/=m; Vector->y/=m; Vector->z/=m; }
For 3D shading, you need to add to ENG3D_SetPlane:
//Compute the normal of the plane PlaneNormal=VEC_CrossProduct(P3D(x2-x1,y2-y1,z2-z1),P3D(x3-x1,y3-y1,z3-z1)); VEC_Normalize(&PlaneNormal);
Now, as we said in the maths part, the cosine of the angle between two vectors is equal
to their dot product when both vectors are normalized. To find the light reaching a plane,
we simply add the ambient light to the cross product of the world coordinate of our
normalized light source, multiplied by the maximal light intensity. Here's some code:
Global definitions:
WORD AmbientLight=20; #define MAXLIGHT 32 static Vertex_t LightSource; WORD light;
And in SetPlane:
//Compute light intensity from the dot product of the normal and of //the lightsource light=MAXLIGHT*VEC_DotProduct(PlaneNormal,LightSource.World)+AmbientLight; if(light>MAXLIGHT)light=MAXLIGHT; if(light<1)light=1;
And you obviously need to initialize the light source, exactly like a normal vertex.
//Initialize Light Source LightSource.Local=P3D(0,0,0); MAT_Identity(matrix); TR_Translate(matrix, 10,10,10); TR_Rotate(matrix, 0,128-32,128); VEC_MultMatrix(&LightSource.Local,matrix,&LightSource.World); VEC_Normalize(&LightSource.World);
A light table is a method of using light intensities on a palette based display. You find the best color match for every color at every intensity. Christopher Lampton made a great light table generator (makelite.cpp) in his book Gardens of Imagination. Unfortunately, that one uses a module of his own for pcx, so you have the choice of either modying it yourself (actually, you only need to load the palette of the pcx, not the image) or using my own modification (makelite.c or makelite.exe). Once we have our light table, we load it in a global array:
BYTE LightTable[MAXLIGHT+1][256];
Once you've loaded it, all you need to change in your TEX_HLine function is the following:
screen[offset]=LightTable[light][color];
Copyright © 1996-1998 Jerome St-Louis