static int test_inverse (const vec3_t angles, const vec3_t scale, const vec3_t translation) { int i; quat_t rotation; mat4_t mat, inv, I, res; AngleQuat (angles, rotation); Mat4Init (rotation, scale, translation, mat); Mat4Identity (I); Mat4Inverse (mat, inv); Mat4Mult (mat, inv, res); for (i = 0; i < 4 * 4; i++) if (!compare (I[i], res[i])) goto fail; return 1; fail: printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g)\n", VectorExpand (angles), VectorExpand (scale), VectorExpand (translation)); printf (" [%g %g %g %g]\n [%g %g %g %g]\n" " [%g %g %g %g]\n [%g %g %g %g]\n\n", Mat4Expand (mat)); printf (" [%g %g %g %g]\n [%g %g %g %g]\n" " [%g %g %g %g]\n [%g %g %g %g]\n\n", Mat4Expand (inv)); printf (" [%g %g %g %g]\n [%g %g %g %g]\n" " [%g %g %g %g]\n [%g %g %g %g]\n\n", Mat4Expand (res)); return 0; }
/* ================ RB_SetGL2D ================ */ void RB_SetGL2D (void) { mat4_t matrix; int width, height; if (backEnd.projection2D && backEnd.last2DFBO == glState.currentFBO) return; backEnd.projection2D = qtrue; backEnd.last2DFBO = glState.currentFBO; if (glState.currentFBO) { width = glState.currentFBO->width; height = glState.currentFBO->height; } else { width = glConfig.vidWidth; height = glConfig.vidHeight; } // set 2D virtual screen size qglViewport( 0, 0, width, height ); qglScissor( 0, 0, width, height ); Mat4Ortho(0, width, height, 0, 0, 1, matrix); GL_SetProjectionMatrix(matrix); Mat4Identity(matrix); GL_SetModelviewMatrix(matrix); GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglDisable( GL_CULL_FACE ); qglDisable( GL_CLIP_PLANE0 ); // set time for 2D shaders backEnd.refdef.time = ri.Milliseconds(); backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; // reset color scaling backEnd.refdef.colorScale = 1.0f; }
/* ================== RB_RenderFlares Because flares are simulating an occular effect, they should be drawn after everything (all views) in the entire frame has been drawn. Because of the way portals use the depth buffer to mark off areas, the needed information would be lost after each view, so we are forced to draw flares after each view. The resulting artifact is that flares in mirrors or portals don't dim properly when occluded by something in the main view, and portal flares that should extend past the portal edge will be overwritten. ================== */ void RB_RenderFlares (void) { flare_t *f; flare_t **prev; qboolean draw; mat4_t oldmodelview, oldprojection, matrix; if ( !r_flares->integer ) { return; } if(r_flareCoeff->modified) { R_SetFlareCoeff(); r_flareCoeff->modified = qfalse; } // Reset currentEntity to world so that any previously referenced entities // don't have influence on the rendering of these flares (i.e. RF_ renderer flags). backEnd.currentEntity = &tr.worldEntity; backEnd.or = backEnd.viewParms.world; // (SA) turned light flares back on. must evaluate problem id had with this RB_AddDlightFlares(); RB_AddCoronaFlares(); // perform z buffer readback on each flare in this view draw = qfalse; prev = &r_activeFlares; while ( ( f = *prev ) != NULL ) { // throw out any flares that weren't added last frame if ( f->addedFrame < backEnd.viewParms.frameCount - 1 ) { *prev = f->next; f->next = r_inactiveFlares; r_inactiveFlares = f; continue; } // don't draw any here that aren't from this scene / portal f->drawIntensity = 0; if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal ) { RB_TestFlare( f ); if ( f->drawIntensity ) { draw = qtrue; } else { // this flare has completely faded out, so remove it from the chain *prev = f->next; f->next = r_inactiveFlares; r_inactiveFlares = f; continue; } } prev = &f->next; } if ( !draw ) { return; // none visible } if ( backEnd.viewParms.isPortal ) { qglDisable (GL_CLIP_PLANE0); } Mat4Copy(glState.projection, oldprojection); Mat4Copy(glState.modelview, oldmodelview); Mat4Identity(matrix); GL_SetModelviewMatrix(matrix); Mat4Ortho( backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportY, backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight, -99999, 99999, matrix ); GL_SetProjectionMatrix(matrix); for ( f = r_activeFlares ; f ; f = f->next ) { if ( f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal && f->drawIntensity ) { RB_RenderFlare( f ); } } GL_SetProjectionMatrix(oldprojection); GL_SetModelviewMatrix(oldmodelview); }
void Renderer::Draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawBackground(); microbes_vbo.Bind(); microbes_vbo.VertexAttrib( 0, 3, GL_FLOAT, false, 0 );//vertex coordinates microbes_vbo.VertexAttrib( 1, 4, GL_UNSIGNED_BYTE, true, sizeof(float)*3 );//color VertexBuffer::EnableAttribs(2); microbes_shader.Bind(); //temp code for (int i=0; i<level->getLastMicrobeIndex(); ++i) { Microbe* microbe = level->getMicrobe(i); float mat[3][16]; Mat4Identity( mat[0] );//scale matrix mat[0][0]= float( screen_y ) / float( screen_x ) * scene_scale; mat[0][5]= scene_scale; Mat4Identity( mat[1] );//translate matirx mat[1][12]= microbe->X(); mat[1][13]= microbe->Y(); //Mat4Mul( mat[0], mat[1], mat[2] ); Mat4Identity( mat[2] );//rotate matrix mat[2][0]= cos( microbe->Dir() ); mat[2][1]= sin( microbe->Dir() ); mat[2][4]= -mat[2][1]; mat[2][5]= mat[2][0]; //rotate * translate * scale Mat4Mul( mat[2], mat[1] ); Mat4Mul( mat[2], mat[0] ); microbes_shader.UniformMat4( 0, mat[2] ); for( int j= 0; j< PART_COUNT; j++ ) { if( generation_func_animation_table[j] ) generation_func_table[j]( &part_meshes[j] ); microbes_vbo.VertexSubData( part_meshes[j].vertices, part_meshes[j].vertex_count * sizeof(MicrobeVertex), 0 ); if( part_meshes[j].indeces != NULL ) microbes_vbo.IndexSubData( part_meshes[j].indeces, part_meshes[j].index_count * sizeof(short), 0 ); part_meshes[j].Draw(); } } unsigned char color[]= { 255, 255, 255, 32 }; text.AddText( 0, 2, 2, color, "MicroRPG - a microbic 64k game" ); text.AddText( 0, 3, 1, color, "By Panzerschrek && Mmaulwurff" ); text.Draw(); }