void Light::setup(GLint glLightId_in) { GLint lightId = (glLightId_in != -1)?glLightId_in:glLightId; glLightId = lightId; enable(); glMatrixMode(GL_MODELVIEW); if (has_target && (type == LIGHT_SPOT || type == LIGHT_AREA)) { // Vector direction; direction = position; direction -= target; //direction.makeUnit(); //#if !defined(ARCH_PSP) && !defined(OPENGL_ES) && !defined(ARCH_DC) // GLShader::defaultShader.setShaderValue("lightDir",direction); //#endif #ifdef ARCH_PSP ScePspFVector3 lightPosition = { position.x, position.y, position.z }; ScePspFVector3 lightDirection = { direction.x, direction.y, direction.z }; sceGuLight( lightId, GU_SPOTLIGHT, GU_DIFFUSE_AND_SPECULAR, &lightPosition ); //sceGuLight( lightId, GU_SPOTLIGHT, GU_SPECULAR, &lightPosition ); sceGuLightSpot(lightId, &lightDirection, exponent, cutoff); #else #ifndef ARCH_DC GLfloat Direction[] = { direction.x, direction.y, direction.z, 1.0f }; GLfloat Position[] = { position.x, position.y, position.z, 1.0f }; glLightfv(lightId, GL_POSITION, Position); glLightfv(lightId, GL_SPOT_DIRECTION, Direction); #endif #endif } else { if (type==LIGHT_DIRECTIONAL) { direction = XYZ(1,0,0); if (rotation.x || rotation.y || rotation.z || rotation != rotation_last) { Vector direction_in; direction_in = XYZ(1,0,0); // float dirTransform[16]; // glMatrixMode(GL_MODELVIEW); // glPushMatrix(); // glLoadIdentity(); // glRotatef(rotation.z,0,0,1); // glRotatef(rotation.y,0,1,0); // glRotatef(rotation.x,1,0,0); // glGetFloatv(GL_MODELVIEW_MATRIX,dirTransform); // glPopMatrix(); // // matTransform(dirTransform,direction_in,direction); // direction.makeUnit(); directionTransform.pushMatrix(); if (rotation.z) directionTransform.rotate(rotation.z,0,0,1); if (rotation.y) directionTransform.rotate(rotation.y,0,1,0); if (rotation.x) directionTransform.rotate(rotation.x,1,0,0); directionTransform.apply(direction_in, direction); directionTransform.popMatrix(); // direction = XYZ(cos(DEGTORAD(rotation.x)),sin(DEGTORAD(rotation.y)),sin(DEGTORAD(rotation.z))); direction.makeUnit(); rotation_last = rotation; } #ifdef ARCH_PSP ScePspFVector3 lightDirection = { direction.x, direction.y, direction.z }; sceGuLight( lightId, GU_DIRECTIONAL, GU_DIFFUSE_AND_SPECULAR, &lightDirection ); //sceGuLight( lightId, GU_DIRECTIONAL, GU_SPECULAR, &lightDirection ); #else GLfloat Position[] = { direction.x, direction.y, direction.z, 0.0f }; // GLfloat Position[] = { 1, 0, 0, 0.0 }; #ifndef ARCH_DC glLightfv(lightId, GL_POSITION, Position); #endif #endif } #ifndef ARCH_PSP #ifndef ARCH_DC else { if (parent) { glPushMatrix(); parent->transformBegin(); } glPushMatrix(); ObjectController lCtl; lCtl.setRotation(rotation); lCtl.setPosition(position); lCtl.transformBegin(); // // if (position.x || position.y || position.z) // { // glTranslatef(position.x,position.y,position.z); // } // // if (rotation.x || rotation.y || rotation.z) // { // if (rotation.z) // { // glRotatef(rotation.z,0,0,1); // } // if (rotation.y) // { // glRotatef(rotation.y,0,1,0); // } // if (rotation.x) // { // glRotatef(rotation.x,1,0,0); // } // } GLfloat Direction[] = { 0, 0, -1, 1 }; glLightfv(lightId, GL_SPOT_DIRECTION, Direction); GLfloat Position[] = { 0, 0, 0, 1 }; glLightfv(lightId, GL_POSITION, Position); glGetFloatv(GL_MODELVIEW_MATRIX,transMatrix); lCtl.transformEnd(); glPopMatrix(); // glPushMatrix(); // #ifdef ARCH_PSP // ScePspFVector3 lightPosition = { position.x, position.y, position.z }; // //sceGuLight( lightId, GU_POINTLIGHT, GU_AMBIENT_AND_DIFFUSE, &lightPosition ); // sceGuLight( lightId, GU_POINTLIGHT, GU_SPECULAR, &lightPosition ); // #else // GLfloat Position[] = { position.x, position.y, position.z, 1.0 }; // glLightfv(lightId, GL_POSITION, Position); // #endif // glPopMatrix(); if (parent) { parent->transformEnd(); glPopMatrix(); } } #endif #endif // if (type == LIGHT_DIRECTIONAL) // { // GLfloat Position[] = { direction.x, direction.y, direction.z, 0 }; // glLightfv(lightId, GL_POSITION, Position); // } } #ifndef ARCH_DC if (type == LIGHT_POINT) { #ifdef ARCH_PSP ScePspFVector3 lightPosition = { position.x, position.y, position.z }; sceGuLight( lightId, GU_POINTLIGHT, GU_DIFFUSE_AND_SPECULAR, &lightPosition ); // sceGuLight( lightId, GU_POINTLIGHT, GU_SPECULAR, &lightPosition ); #else GLfloat Position[] = { position.x, position.y, position.z, 1 }; glLightfv(lightId, GL_POSITION, Position); // printf("pos: %d, %f, %f, %f\n",lightId,Position[0],Position[1],Position[2]); #endif #ifndef ARCH_PSP if (cutoff) { glLightf(lightId, GL_SPOT_EXPONENT, 1.0f/cutoff); } else { glLightf(lightId, GL_SPOT_EXPONENT, 0); } #endif } #ifndef ARCH_PSP if ((type == LIGHT_SPOT)) // || type == LIGHT_PROJECTOR { glLightf(lightId, GL_SPOT_CUTOFF, cutoff/2.0f); glLightf(lightId, GL_SPOT_EXPONENT, 1.0); } #endif #ifdef ARCH_PSP sceGuLightMode(GU_SEPARATE_SPECULAR_COLOR); sceGuLightColor( lightId, GU_AMBIENT, GU_COLOR( ambient.r, ambient.g, ambient.b, 1.0f )); sceGuLightColor( lightId, GU_DIFFUSE, GU_COLOR( diffuse.r, diffuse.g, diffuse.b, 1.0f )); sceGuLightColor( lightId, GU_SPECULAR, GU_COLOR( specular.r, specular.g, specular.b, 1.0f )); #else //#ifndef OPENGL_ES // glEnable(GL_SEPARATE_SPECULAR_COLOR); // glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); // glEnable(GL_COLOR_SUM); //#endif GLfloat Ambient[] = { ambient.r, ambient.g, ambient.b, 1 }; GLfloat Diffuse[] = { diffuse.r, diffuse.g, diffuse.b, 1 }; GLfloat Specular[] = { specular.r, specular.g, specular.b, 1 }; glLightfv(lightId, GL_AMBIENT, Ambient); glLightfv(lightId, GL_DIFFUSE, Diffuse); glLightfv(lightId, GL_SPECULAR, Specular); #endif #ifdef ARCH_PSP sceGuEnable(gl_lights[lightId]); sceGuLightAtt(lightId, constant_attenuation, linear_attenuation, quadratic_attenuation); #else glLightf(lightId, GL_CONSTANT_ATTENUATION, constant_attenuation); glLightf(lightId, GL_LINEAR_ATTENUATION, linear_attenuation); glLightf(lightId, GL_QUADRATIC_ATTENUATION, quadratic_attenuation); glEnable(lightId); #endif #endif };
int main(int argc, char* argv[]) { SetupCallbacks(); // generate geometry genGrid( GRID_ROWS, GRID_COLUMNS, GRID_SIZE, grid_vertices, grid_indices ); genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices ); // flush cache so that no stray data remains sceKernelDcacheWritebackAll(); // setup VRAM buffers void* frameBuffer = (void*)0; const void* doubleBuffer = (void*)0x44000; const void* renderTarget = (void*)0x88000; const void* depthBuffer = (void*)0x110000; // setup GU sceGuInit(); sceGuStart(GU_DIRECT,list); sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH); sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH); sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); sceGuDepthRange(0xc350,0x2710); sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuDepthFunc(GU_GEQUAL); sceGuEnable(GU_DEPTH_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuEnable(GU_CULL_FACE); sceGuEnable(GU_TEXTURE_2D); sceGuEnable(GU_DITHER); sceGuFinish(); sceGuSync(0,0); sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); // setup matrices ScePspFMatrix4 identity; ScePspFMatrix4 projection; ScePspFMatrix4 view; gumLoadIdentity(&identity); gumLoadIdentity(&projection); gumPerspective(&projection,75.0f,16.0f/9.0f,0.5f,1000.0f); { ScePspFVector3 pos = {0,0,-5.0f}; gumLoadIdentity(&view); gumTranslate(&view,&pos); } ScePspFMatrix4 textureProjScaleTrans; gumLoadIdentity(&textureProjScaleTrans); textureProjScaleTrans.x.x = 0.5; textureProjScaleTrans.y.y = -0.5; textureProjScaleTrans.w.x = 0.5; textureProjScaleTrans.w.y = 0.5; ScePspFMatrix4 lightProjection; ScePspFMatrix4 lightProjectionInf; ScePspFMatrix4 lightView; ScePspFMatrix4 lightMatrix; gumLoadIdentity(&lightProjection); gumPerspective(&lightProjection,75.0f,1.0f,0.1f,1000.0f); gumLoadIdentity(&lightProjectionInf); gumPerspective(&lightProjectionInf,75.0f,1.0f,0.0f,1000.0f); gumLoadIdentity(&lightView); gumLoadIdentity(&lightMatrix); // define shadowmap Texture shadowmap = { GU_PSM_4444, 0, 128, 128, 128, sceGeEdramGetAddr() + (int)renderTarget }; // define geometry Geometry torus = { identity, sizeof(torus_indices)/sizeof(unsigned short), torus_indices, torus_vertices, 0xffffff }; Geometry grid = { identity, sizeof(grid_indices)/sizeof(unsigned short), grid_indices, grid_vertices, 0xff7777 }; // run sample int val = 0; for(;;) { // update matrices // grid { ScePspFVector3 pos = {0,-1.5f,0}; gumLoadIdentity(&grid.world); gumTranslate(&grid.world,&pos); } // torus { ScePspFVector3 pos = {0,0.5f,0.0f}; ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; gumLoadIdentity(&torus.world); gumTranslate(&torus.world,&pos); gumRotateXYZ(&torus.world,&rot); } // orbiting light { ScePspFVector3 lightLookAt = { torus.world.w.x, torus.world.w.y, torus.world.w.z }; ScePspFVector3 rot1 = {0,val * 0.79f * (GU_PI/180.0f),0}; ScePspFVector3 rot2 = {-(GU_PI/180.0f)*60.0f,0,0}; ScePspFVector3 pos = {0,0,LIGHT_DISTANCE}; gumLoadIdentity(&lightMatrix); gumTranslate(&lightMatrix,&lightLookAt); gumRotateXYZ(&lightMatrix,&rot1); gumRotateXYZ(&lightMatrix,&rot2); gumTranslate(&lightMatrix,&pos); } gumFastInverse(&lightView,&lightMatrix); // render to shadow map { sceGuStart(GU_DIRECT,list); // set offscreen texture as a render target sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,shadowmap.stride); // setup viewport sceGuOffset(2048 - (shadowmap.width/2),2048 - (shadowmap.height/2)); sceGuViewport(2048,2048,shadowmap.width,shadowmap.height); // clear screen sceGuClearColor(0xffffffff); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // setup view/projection from light sceGuSetMatrix(GU_PROJECTION,&lightProjection); sceGuSetMatrix(GU_VIEW,&lightView); // shadow casters are drawn in black // disable lighting and texturing sceGuDisable(GU_LIGHTING); sceGuDisable(GU_TEXTURE_2D); // draw torus to shadow map drawShadowCaster( &torus ); sceGuFinish(); sceGuSync(0,0); } // render to frame buffer { sceGuStart(GU_DIRECT,list); // set frame buffer sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH); // setup viewport sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); // clear screen sceGuClearColor(0xff554433); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // setup view/projection from camera sceGuSetMatrix(GU_PROJECTION,&projection); sceGuSetMatrix(GU_VIEW,&view); sceGuSetMatrix(GU_MODEL,&identity); // setup a light ScePspFVector3 lightPos = { lightMatrix.w.x, lightMatrix.w.y, lightMatrix.w.z }; ScePspFVector3 lightDir = { lightMatrix.z.x, lightMatrix.z.y, lightMatrix.z.z }; sceGuLight(0,GU_SPOTLIGHT,GU_DIFFUSE,&lightPos); sceGuLightSpot(0,&lightDir, 5.0, 0.6); sceGuLightColor(0,GU_DIFFUSE,0x00ff4040); sceGuLightAtt(0,1.0f,0.0f,0.0f); sceGuAmbient(0x00202020); sceGuEnable(GU_LIGHTING); sceGuEnable(GU_LIGHT0); // draw torus drawGeometry( &torus ); // setup texture projection sceGuTexMapMode( GU_TEXTURE_MATRIX, 0, 0 ); sceGuTexProjMapMode( GU_POSITION ); // set shadowmap as a texture sceGuTexMode(shadowmap.format,0,0,0); sceGuTexImage(shadowmap.mipmap,shadowmap.width,shadowmap.height,shadowmap.stride,shadowmap.data); sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGB); sceGuTexFilter(GU_LINEAR,GU_LINEAR); sceGuTexWrap(GU_CLAMP,GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); // calculate texture projection matrix for shadowmap ScePspFMatrix4 shadowProj; gumMultMatrix(&shadowProj, &lightProjectionInf, &lightView); gumMultMatrix(&shadowProj, &textureProjScaleTrans, &shadowProj); // draw grid receiving shadow drawShadowReceiver( &grid, shadowProj ); sceGuFinish(); sceGuSync(0,0); } sceDisplayWaitVblankStart(); frameBuffer = sceGuSwapBuffers(); val++; } sceGuTerm(); sceKernelExitGame(); return 0; }