3D OpenGL Engine

BlitzPlus Forums/BlitzPlus Programming/3D OpenGL Engine

[first of all, sorry for my lack of explanation skills]
[All C presented here, ofcoarse needs to be converted to blitz]
Ok, studying up on what needs to be done with what I have ( C/C++ source code from NEHE Lesson 27 ), we need:

- light caster fields built into entity fields
- shadow caster fields built into entity fields

we need to do:
	SetConnectivity(&obj);								// Set Face To Face Connectivity

	for (unsigned int i=0;i<obj.nPlanes;i++)			// Loop Through All Object Planes
		CalcPlane(obj, &(obj.planes[i]));				// Compute Plane Equations For All Faces


for each entity that is a shadow caster. SetConnectivity & CalcPlane functions helps to create the shadow effect in the stencil buffer.

For the light caster entities, they will need to have an inverse matrix by doing all the actions in reverse order and with reverse parameters of all shadow caster entities effected by the specific light caster entity. So we need somehow to store all the movement/rotation actions of an entity that is to be a shadow caster in it's own structure fields. The light caster entities needs to somehow be called after all the shadow caster entites have moved (probably a second pass after everything is moved to see which ones are light casters and start calculating there). The light caster will be able to do the inverse matrix by getting the data directly from the shadow caster type fields.

[Ofcoarse also at the beginning, one would have to set what are light casters and shadow casters. A light caster will know what shadow casters it will deal with and vice versa.]

From each shadow caster, a light caster will do first:
- glLoadIdentity();
- reverse shadow caster rotation movements
- glGetFloatv(GL_MODELVIEW_MATRIX,Minv); Retrieve ModelView Matrix
- get light caster's position and store in a vector4f bank array.
- Multiply light vector with modelview matrix
- translate shadow caster's position
- glGetFloatv(GL_MODELVIEW_MATRIX,Minv); Retrieve new ModelView Matrix
- VMatMult(Minv, wlp); We Store The Position Of The World Origin Relative To The Local Coordinate System In 'wlp' bank Array
lp[0] += wlp[0]; Adding These Two Gives Us The
lp[1] += wlp[1]; Position Of The Light Relative To
lp[2] += wlp[2]; The Local Coordinate System

Then we do a ShadowCasting Function on the specific shadow caster entity with via the relative light positon.

This what the NEHE shadow castion function looks like (still got to sort this code out ):
void  CastShadow(glObject *o, float *lp){
	unsigned int	i, j, k, jj;
	unsigned int	p1, p2;
	sPoint			v1, v2;
	float			side;

	//set visual parameter
	for (i=0;i<o->nPlanes;i++){
		// chech to see if light is in front or behind the plane (face plane)
		side =	o->planes[i].PlaneEq.a*lp[0]+
				o->planes[i].PlaneEq.b*lp[1]+
				o->planes[i].PlaneEq.c*lp[2]+
				o->planes[i].PlaneEq.d*lp[3];
		if (side >0) o->planes[i].visible = TRUE;
				else o->planes[i].visible = FALSE;
	}

 	glDisable(GL_LIGHTING);
	glDepthMask(GL_FALSE);
	glDepthFunc(GL_LEQUAL);

	glEnable(GL_STENCIL_TEST);
	glColorMask(0, 0, 0, 0);
	glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

	// first pass, stencil operation decreases stencil value
	glFrontFace(GL_CCW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
	for (i=0; i<o->nPlanes;i++){
		if (o->planes[i].visible)
			for (j=0;j<3;j++){
				k = o->planes[i].neigh[j];
				if ((!k) || (!o->planes[k-1].visible)){
					// here we have an edge, we must draw a polygon
					p1 = o->planes[i].p[j];
					jj = (j+1)%3;
					p2 = o->planes[i].p[jj];

					//calculate the length of the vector
					v1.x = (o->points[p1].x - lp[0])*100;
					v1.y = (o->points[p1].y - lp[1])*100;
					v1.z = (o->points[p1].z - lp[2])*100;

					v2.x = (o->points[p2].x - lp[0])*100;
					v2.y = (o->points[p2].y - lp[1])*100;
					v2.z = (o->points[p2].z - lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(o->points[p1].x,
									o->points[p1].y,
									o->points[p1].z);
						glVertex3f(o->points[p1].x + v1.x,
									o->points[p1].y + v1.y,
									o->points[p1].z + v1.z);

						glVertex3f(o->points[p2].x,
									o->points[p2].y,
									o->points[p2].z);
						glVertex3f(o->points[p2].x + v2.x,
									o->points[p2].y + v2.y,
									o->points[p2].z + v2.z);
					glEnd();
				}
			}
	}

	// second pass, stencil operation increases stencil value
	glFrontFace(GL_CW);
	glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
	for (i=0; i<o->nPlanes;i++){
		if (o->planes[i].visible)
			for (j=0;j<3;j++){
				k = o->planes[i].neigh[j];
				if ((!k) || (!o->planes[k-1].visible)){
					// here we have an edge, we must draw a polygon
					p1 = o->planes[i].p[j];
					jj = (j+1)%3;
					p2 = o->planes[i].p[jj];

					//calculate the length of the vector
					v1.x = (o->points[p1].x - lp[0])*100;
					v1.y = (o->points[p1].y - lp[1])*100;
					v1.z = (o->points[p1].z - lp[2])*100;

					v2.x = (o->points[p2].x - lp[0])*100;
					v2.y = (o->points[p2].y - lp[1])*100;
					v2.z = (o->points[p2].z - lp[2])*100;
					
					//draw the polygon
					glBegin(GL_TRIANGLE_STRIP);
						glVertex3f(o->points[p1].x,
									o->points[p1].y,
									o->points[p1].z);
						glVertex3f(o->points[p1].x + v1.x,
									o->points[p1].y + v1.y,
									o->points[p1].z + v1.z);

						glVertex3f(o->points[p2].x,
									o->points[p2].y,
									o->points[p2].z);
						glVertex3f(o->points[p2].x + v2.x,
									o->points[p2].y + v2.y,
									o->points[p2].z + v2.z);
					glEnd();
				}
			}
	}

	glFrontFace(GL_CCW);
	glColorMask(1, 1, 1, 1);

	//draw a shadowing rectangle covering the entire screen
	glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	glPushMatrix();
	glLoadIdentity();
	glBegin(GL_TRIANGLE_STRIP);
		glVertex3f(-0.1f, 0.1f,-0.10f);
		glVertex3f(-0.1f,-0.1f,-0.10f);
		glVertex3f( 0.1f, 0.1f,-0.10f);
		glVertex3f( 0.1f,-0.1f,-0.10f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);

	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_TRUE);
	glEnable(GL_LIGHTING);
	glDisable(GL_STENCIL_TEST);
	glShadeModel(GL_SMOOTH);
}



So any comments? Lot's to do there. It's gonna take a bit for me to program in because I still have to familuarize myself with the entity structures.