コード例 #1
0
ファイル: REV.cpp プロジェクト: THEGITGIT/revolutionengine
void render(NODE * node, Vector camPos)
{
	Mtx tmp;
	if(!node->isRenderable()) return;//Skip non-renderable nodes such as empty nodes, regions or lights
	if(node->flags & F_Visible)//Is it visible?
	{
		//Set matrices
		Mtx aux, inv;
		GX_ClearVtxDesc();
		node->absMtx(modelM);
		char msg[64];

		guMtxConcat(view, modelM, modelview);
		GX_LoadPosMtxImm(modelview, GX_PNMTX0);//Load model view matrix
		guMtxInverse(modelview, tmp);
		guMtxTranspose(tmp,inv);
		GX_LoadNrmMtxImm(inv, GX_PNMTX0);//Load normal matrix

		//TODO: Better lighting (multiple lights)
		std::vector<LIGHT*>::iterator light = mainRoot->getLights().begin();
		//if(light == mainRoot->getLights().end())
		//	REVConsole->write("LIGHT");
		GXLightObj lObj[8];
		u8 lightMask = 0, tmpLight = GX_LIGHT0;
		for(u8 i = 0;light != mainRoot->getLights().end(); ++light, ++i)
		{
			Vector lpos = (*light)->getPos();
			guVecMultiply(view, &lpos, &lpos);
			
			GX_InitLightPos(&lObj[i],lpos.x,lpos.y,lpos.z);
			GX_InitLightAttn(&lObj[i], 1.0f,0.0f,0.0f,1.0f,0.0f,0.0f);
			GX_InitLightSpot(&lObj[i],0.0f,GX_SP_OFF);
			GX_InitLightColor(&lObj[i],(*light)->clr);
			GX_LoadLightObj(&lObj[i],tmpLight);
			lightMask |= tmpLight;
			tmpLight *= 2;
		}
		//Render the node
		node->render(lightMask);
	}
}
コード例 #2
0
ファイル: gl.c プロジェクト: machinamentum/gl2gx
void glEnd(void) {
     
     GX_SetCullMode(GX_CULL_FRONT);

	Mtx mvi;
	Mtx mv;
	
//	Mtx inversemodelview;

	// load the modelview matrix into matrix memory
	guMtxConcat(view,model,modelview);
	GX_LoadPosMtxImm(modelview, GX_PNMTX0);

	//for normals first calculate normal matrix (thanks shagkur)
    guMtxInverse(modelview,mvi); 
    guMtxTranspose(mvi,modelview); 
    GX_LoadNrmMtxImm(modelview,GX_PNMTX0); //experimtal leave out (hmm works good?)


	//use global ambient light together with current material ambient and add emissive material color
	GXColor constcolor;
	constcolor.r = (gxcurrentmaterialambientcolor.r*gxglobalambientlightcolor.r) * 0xFF;
	constcolor.g = (gxcurrentmaterialambientcolor.g*gxglobalambientlightcolor.g) * 0xFF;
	constcolor.b = (gxcurrentmaterialambientcolor.b*gxglobalambientlightcolor.b) * 0xFF;
	constcolor.a = (gxcurrentmaterialambientcolor.a*gxglobalambientlightcolor.a) * 0xFF;
	GX_SetTevColor(GX_TEVREG0, constcolor);
	
	GXColor emiscolor;
	emiscolor.r = gxcurrentmaterialemissivecolor.r * 0xFF;
	emiscolor.g = gxcurrentmaterialemissivecolor.g * 0xFF;
	emiscolor.b = gxcurrentmaterialemissivecolor.b * 0xFF;
	emiscolor.a = gxcurrentmaterialemissivecolor.a * 0xFF;
	GX_SetTevColor(GX_TEVREG1, emiscolor);

	//first check if a lightdirtyflag is set (thanks ector) so we do not have to set up light every run
	//also usefull on matrices etc.

	//now set each light
	GXColor gxchanambient;
	gxchanambient.r = gxcurrentmaterialambientcolor.r;
	gxchanambient.g = gxcurrentmaterialambientcolor.g;
	gxchanambient.b = gxcurrentmaterialambientcolor.b;
	gxchanambient.a = gxcurrentmaterialambientcolor.a;
	
	GXColor gxchanspecular;
	gxchanspecular.r = gxcurrentmaterialspecularcolor.r;
	gxchanspecular.g = gxcurrentmaterialspecularcolor.g;
	gxchanspecular.b = gxcurrentmaterialspecularcolor.b;
	gxchanspecular.a = gxcurrentmaterialspecularcolor.a;	
	
	int lightcounter = 0;
	for (lightcounter =0; lightcounter < 4; lightcounter++){

		if(gxlightenabled[lightcounter]){ //when light is enabled

            //somewhere here an error happens?

            //Setup mat/light ambient color 
			gxchanambient.r = ((gxchanambient.r * gxlightambientcolor[lightcounter].r) * 0xFF);
			gxchanambient.g = ((gxchanambient.g * gxlightambientcolor[lightcounter].g) * 0xFF);
			gxchanambient.b = ((gxchanambient.b * gxlightambientcolor[lightcounter].b) * 0xFF);
			gxchanambient.a = ((gxchanambient.a * gxlightambientcolor[lightcounter].a) * 0xFF);
			GX_SetChanAmbColor(GX_COLOR0A0, gxchanambient ); 
			
			//Setup diffuse material color
			GXColor mdc;
			mdc.r = (gxcurrentmaterialdiffusecolor.r * 0xFF);
			mdc.g = (gxcurrentmaterialdiffusecolor.g * 0xFF);
			mdc.b = (gxcurrentmaterialdiffusecolor.b * 0xFF);
			mdc.a = (gxcurrentmaterialdiffusecolor.a * 0xFF);
			GX_SetChanMatColor(GX_COLOR0A0, mdc ); 
			
			//Setup specular material color
//			gxcurrentmaterialshininess *
			gxchanspecular.r = (gxchanspecular.r * gxlightspecularcolor[lightcounter].r) * 0xFF;
			gxchanspecular.g = (gxchanspecular.g * gxlightspecularcolor[lightcounter].g) * 0xFF;
			gxchanspecular.b = (gxchanspecular.b * gxlightspecularcolor[lightcounter].b) * 0xFF;
			gxchanspecular.a = (gxchanspecular.a * gxlightspecularcolor[lightcounter].a) * 0xFF;
			GX_SetChanMatColor(GX_COLOR1A1, gxchanspecular); // use red as test color

            //Setup light diffuse color
            GXColor ldc;
			ldc.r = gxlightdiffusecolor[lightcounter].r * 0xFF;
			ldc.g = gxlightdiffusecolor[lightcounter].g * 0xFF;
			ldc.b = gxlightdiffusecolor[lightcounter].b * 0xFF;
			ldc.a = gxlightdiffusecolor[lightcounter].a * 0xFF;
			GX_InitLightColor(&gxlight[lightcounter], ldc ); //move call to glend or init?;
            GX_InitLightColor(&gxlight[lightcounter+4], ldc ); //move call to glend or init?;

			//Setup light postion
			
			//check on w component when 1. light is positional
			//                     when 0. light is directional at infinite pos
			
			guVector lpos;
			guVector wpos;
            lpos.x = gxlightpos[lightcounter].x;
            lpos.y = gxlightpos[lightcounter].y;
            lpos.z = gxlightpos[lightcounter].z;
               
               
            if (gxlightpos[lightcounter].w == 0){
                guVecNormalize(&lpos);
                lpos.x *= BIG_NUMBER;
                lpos.y *= BIG_NUMBER;
                lpos.z *= BIG_NUMBER;
            }
            
			guVecMultiply(view,&lpos,&wpos);	   //light position should be transformed by world-to-view matrix (thanks h0lyRS)
			GX_InitLightPosv(&gxlight[lightcounter], &wpos); //feed corrected coord to light pos
			GX_InitLightPosv(&gxlight[lightcounter+4], &wpos); //feed corrected coord to light pos
		


            //Setup light direction (when w is 1 dan dir = 0,0,0
            guVector ldir;
            if (gxlightpos[lightcounter].w==0){ 
               //lpos.x = gxlightpos[lightcounter].x;
			   //lpos.y = gxlightpos[lightcounter].y;
               //lpos.z = gxlightpos[lightcounter].z;
                                                
               ldir.x = gxlightpos[lightcounter].x;
               ldir.y = gxlightpos[lightcounter].y;
               ldir.z = gxlightpos[lightcounter].z;
            }
            else
            {
                if (gxspotcutoff[lightcounter] != 180){ //if we have a spot light direction is needed
                   ldir.x = gxspotdirection[lightcounter].x;
                   ldir.y = gxspotdirection[lightcounter].y;
                   ldir.z = gxspotdirection[lightcounter].z;
                }
                else { 
                     ldir.x = 0;
                     ldir.y = 0;
                     ldir.z = -1;
               }
            }
            
            //guVecNormalize(&ldir);
            //ldir.x *= BIG_NUMBER;
            //ldir.y *= BIG_NUMBER;
            //ldir.z *= BIG_NUMBER;
            
            guMtxInverse(view,mvi);
            guMtxTranspose(mvi,view);
            
            guVecMultiply(view,&ldir,&ldir); //and direction should be transformed by inv-transposed of world-to-view (thanks h0lyRS)
            
            GX_InitLightDir(&gxlight[lightcounter], ldir.x, ldir.y, ldir.z); //feed corrected coord to light dir
            GX_InitLightDir(&gxlight[lightcounter+4], ldir.x, ldir.y, ldir.z); //feed corrected coord to light dir
           
            
			if (gxspotcutoff[lightcounter] != 180){
               //Setup specular light (only for spotlight when GL_SPOT_CUTOFF <> 180)
			   //make this line optional? If on it disturbs diffuse light?
               guVector sdir;
               sdir.x = gxspotdirection[lightcounter].x;
               sdir.y = gxspotdirection[lightcounter].y;
               sdir.z = gxspotdirection[lightcounter].z;
               //guVecNormalize(&sdir);
                     
               //sdir.x *= BIG_NUMBER;
               //sdir.y *= BIG_NUMBER;
               //sdir.z *= BIG_NUMBER;       
                              
			   guVecMultiply(view,&sdir,&sdir);
			   
			   guVector light_dir;
			   guVecSub(&sdir, &lpos, &light_dir);
			   
			   GX_TestInitSpecularDir(&gxlight[lightcounter], light_dir.x, light_dir.y, light_dir.z); //needed to enable specular light
               GX_TestInitSpecularDir(&gxlight[lightcounter+4], light_dir.x, light_dir.y, light_dir.z); //needed to enable specular light
               
            };
            
            
            //this calls:
            // #define GX_InitLightShininess(lobj, shininess) (GX_InitLightAttn(lobj, 0.0F, 0.0F, 1.0F, (shininess)/2.0F, 0.0F, 1.0F-(shininess)/2.0F ))

            //Setup distance attinuation (opengl vs gx differences?)
			//GX_InitLightDistAttn(&gxlight[lightcounter], 100.0f, gxspotexponent[lightcounter], GX_DA_GENTLE); //gxspotexponent was 0.5f
                                                     //ref_dist, bright, dist func  
            //k0 = 1.0;                   
            //k1 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist);
 			//k2 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist*ref_dist); or 0.0f;                  
                    
                    
                     
            //Attenuation factor = 1 / (kc + kl*d + kq*d2) 
            //kc = constant attenuation factor (default = 1.0) 
            //kl = linear attenuation factor (default = 0.0) 
            //kq = quadratic attenuation factor (default = 0.0) 
         
            float distance = BIG_NUMBER; //either distance of light or falloff factor
            float factor = 1 / (gxconstantattanuation[lightcounter] + gxlinearattanuation[lightcounter]*distance + gxquadraticattanuation[lightcounter]*distance*distance);                   
             
            //float factor = 5.0; 
             
            //k0 - 0;                            
       		//k1 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist);
 			//k2 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist*ref_dist);                            

/*                           
            GX_InitLightAttn(&gxlight[lightcounter], 
                                                     1.0, //filled by initlightspot
                                                     0.0, //filled by initlightspot
                                                     0.0, //filled by initlightspot
                                                     gxconstantattanuation[lightcounter], 
                                                     gxlinearattanuation[lightcounter]*distance, 
                                                     gxquadraticattanuation[lightcounter]*distance*distance
                                                     
                                                     ) ;
                                                   //  k0              k1   , k2                    
*/                           
                                                     
            //GX_InitLightAttnK(&gxlight[lightcounter],  (gxcurrentmaterialshininess)/2.0F , 0.0F ,1.0F-(gxcurrentmaterialshininess)/2.0F);
            
             
                     
            
            GX_InitLightDistAttn(&gxlight[lightcounter], factor ,1.0, GX_DA_STEEP); //gxspotexponent[lightcounter] GX_DA_GENTLE
            GX_InitLightDistAttn(&gxlight[lightcounter+4], factor ,1.0, GX_DA_STEEP); //gxspotexponent[lightcounter] GX_DA_GENTLE

            
                                                         //ref_dist //ref_brite
            //                                           factor / strenght
//1.0 is //    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 10.0f); ??
                                                     
                                                           
            //Setup light type (normal/spotlight)
            //0-90 / 255-0
            
            
                                                //cut_off, spot func
            //GX_InitLightSpot(&gxlight[lightcounter], 0.0f, GX_SP_OFF); //not this is not a spot light
            
            //GX_InitLightShininess(&gxlight[lightcounter], gxcurrentmaterialshininess); // /180?
            
            //float testspot = 90 - ((gxcurrentmaterialshininess * 90) / 128); //thanks ector 90 - (x * 90 / 255) 
            //if (gxcurrentmaterialshininess == 0){
            //   testspot = 90;
            //}
            //zid 255-gxcurrentmaterialshininess/(255/90);
            
            //setup specular highlight
            //GX_InitLightSpot(&gxlight[lightcounter], testspot, GX_SP_COS); //not this is not a spot light (gxspotcutoff[lightcounter])
            
            //setup normal spotlight
            GX_InitLightSpot(&gxlight[lightcounter], gxspotcutoff[lightcounter], GX_SP_RING1); //not this is not a spot light ()
            GX_InitLightSpot(&gxlight[1], gxspotcutoff[lightcounter], GX_SP_RING1); //not this is not a spot light ()
            
            if ( gxcurrentmaterialshininess != 0 ) {
                 //if (gxspotcutoff[lightcounter] != 180) {
                    GX_TestInitLightShininess(&gxlight[lightcounter+4], gxcurrentmaterialshininess);
                 //}
            };

			//Load the light up
			switch (lightcounter){
				case 0: 
                     GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT0);
                     GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT4);  
                     break;
				case 1: 
                     GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT1);
                     GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT5); 
                     break;
				case 2: 
                     GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT2); 
                     GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT6);
                     break;
				case 3: 
                     GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT3); 
                     GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT7);
                     break;
//				case 4: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT4); break;
//				case 5: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT5); break;
//				case 6: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT6); break;
//				case 7: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT7); break;
			}
			
			//GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT0);
			//GX_LoadLightObj(&gxlight[1], GX_LIGHT1);

		}
	}


	//set the curtexture if tex2denabled
	if (tex2denabled){
	GX_LoadTexObj(&gxtextures[curtexture], GX_TEXMAP0); //TODO: make GX_TEXMAP0 dynamic for multitexturing
	};

	//now we can draw the gx way (experiment try render in reverse ivm normals pointing the wrong way)
	
	int countelements = _numelements*2;
	if (gxcullfaceanabled==true){
       countelements = _numelements;
    }
	
	GX_Begin(_type, GX_VTXFMT0, countelements); //dependend on culling setting
	int i =0;
                                //default
//order dependend on glFrontFace(GL_CCW); 
//or GL_CW //	for( i=0; i<_numelements; i++)

//GX_TRIANGLESTRIP   GL_TRIANGLE_STRIP
//0 1 2			     0 1 2
//1 3 2			     2 1 3
//2 3 4			     2 3 4
//better think of a clever swapping routine
//maybe then no need to invert normal for trianglestrip anymore

//also GX_TRIANLES need to be drawn in reverse?
//but GX_QUAD does not

//so GX = CW by default while opengl is CCW by default?

//bushing say cannot i be possibel that opengl reorders vertexes

//u32 reverse = 0;
//int pos = 0;
//int temp = 0;

//GL_POLYGON: http://www.gamedev.net/reference/articles/article425.asp

bool cw = true;
bool ccw = true;

if(gxcullfaceanabled==true){
   cw = false;
   ccw = false;                            
   switch(gxwinding){
      case GL_CW: cw = true; break;
      case GL_CCW: ccw = true; break;
   }                         
}

    if (cw==true){ 
       //CW     
       for( i=_numelements-1; i>=0; i--)
       {
            UploadVertex(i);    	
       }
    }
    
    if (ccw==true){
       //CCW
       for( i=0; i<_numelements; i++)
       {
            UploadVertex(i);    	
       }
    }


	GX_End();

	//clean up just to be sure
	i =0;
	for( i=0; i<_numelements; i++)
	{
		_vertexelements[i].x = 0.0F;
		_vertexelements[i].y = 0.0F;
		_vertexelements[i].z = 0.0F;

		_normalelements[i].x = 0.0F;
		_normalelements[i].y = 0.0F;
		_normalelements[i].z = 0.0F;

		_colorelements[i].r = 0.0F;
		_colorelements[i].g = 0.0F;
		_colorelements[i].b = 0.0F;
		_colorelements[i].a = 0.0F;

		_texcoordelements[i].s = 0.0F;
		_texcoordelements[i].t = 0.0F;

	}
	_numelements =0;
}