/* ================= R_RotateForEntity Generates an orientation for an entity and viewParms Does NOT produce any GL calls Called by both the front end and the back end ================= */ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *ori ) { // float glMatrix[16]; vec3_t delta; float axisLength; if ( ent->e.reType != RT_MODEL ) { *ori = viewParms->world; return; } VectorCopy( ent->e.origin, ori->origin ); VectorCopy( ent->e.axis[0], ori->axis[0] ); VectorCopy( ent->e.axis[1], ori->axis[1] ); VectorCopy( ent->e.axis[2], ori->axis[2] ); preTransEntMatrix[0] = ori->axis[0][0]; preTransEntMatrix[4] = ori->axis[1][0]; preTransEntMatrix[8] = ori->axis[2][0]; preTransEntMatrix[12] = ori->origin[0]; preTransEntMatrix[1] = ori->axis[0][1]; preTransEntMatrix[5] = ori->axis[1][1]; preTransEntMatrix[9] = ori->axis[2][1]; preTransEntMatrix[13] = ori->origin[1]; preTransEntMatrix[2] = ori->axis[0][2]; preTransEntMatrix[6] = ori->axis[1][2]; preTransEntMatrix[10] = ori->axis[2][2]; preTransEntMatrix[14] = ori->origin[2]; preTransEntMatrix[3] = 0; preTransEntMatrix[7] = 0; preTransEntMatrix[11] = 0; preTransEntMatrix[15] = 1; myGlMultMatrix( preTransEntMatrix, viewParms->world.modelMatrix, ori->modelMatrix ); // calculate the viewer origin in the model's space // needed for fog, specular, and environment mapping VectorSubtract( viewParms->ori.origin, ori->origin, delta ); // compensate for scale in the axes if necessary if ( ent->e.nonNormalizedAxes ) { axisLength = VectorLength( ent->e.axis[0] ); if ( !axisLength ) { axisLength = 0; } else { axisLength = 1.0f / axisLength; } } else { axisLength = 1.0f; } ori->viewOrigin[0] = DotProduct( delta, ori->axis[0] ) * axisLength; ori->viewOrigin[1] = DotProduct( delta, ori->axis[1] ) * axisLength; ori->viewOrigin[2] = DotProduct( delta, ori->axis[2] ) * axisLength; }
/* ==================== EmitToCurrentView ==================== */ void idGuiModel::EmitToCurrentView( float modelMatrix[16], bool depthHack ) { float modelViewMatrix[16]; myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.modelViewMatrix, modelViewMatrix ); for( int i = 0 ; i < surfaces.Num() ; i++ ) { EmitSurface( &surfaces[i], modelMatrix, modelViewMatrix, depthHack ); } }
/* ================= R_RenderGuiSurf Create a texture space on the given surface and call the GUI generator to create quads for it. ================= */ void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ) { idVec3 origin, axis[3]; // for testing the performance hit if ( r_skipGuiShaders.GetInteger() == 1 ) { return; } // don't allow an infinite recursion loop if ( tr.guiRecursionLevel == 4 ) { return; } tr.pc.c_guiSurfs++; // create the new matrix to draw on this surface R_SurfaceToTextureAxis( drawSurf->geo, origin, axis ); float guiModelMatrix[16]; float modelMatrix[16]; guiModelMatrix[0] = axis[0][0] / 640.0; guiModelMatrix[4] = axis[1][0] / 480.0; guiModelMatrix[8] = axis[2][0]; guiModelMatrix[12] = origin[0]; guiModelMatrix[1] = axis[0][1] / 640.0; guiModelMatrix[5] = axis[1][1] / 480.0; guiModelMatrix[9] = axis[2][1]; guiModelMatrix[13] = origin[1]; guiModelMatrix[2] = axis[0][2] / 640.0; guiModelMatrix[6] = axis[1][2] / 480.0; guiModelMatrix[10] = axis[2][2]; guiModelMatrix[14] = origin[2]; guiModelMatrix[3] = 0; guiModelMatrix[7] = 0; guiModelMatrix[11] = 0; guiModelMatrix[15] = 1; myGlMultMatrix( guiModelMatrix, drawSurf->space->modelMatrix, modelMatrix ); tr.guiRecursionLevel++; // call the gui, which will call the 2D drawing functions tr.guiModel->Clear(); gui->Redraw( tr.viewDef->renderView.time ); tr.guiModel->EmitToCurrentView( modelMatrix, drawSurf->space->weaponDepthHack ); tr.guiModel->Clear(); tr.guiRecursionLevel--; }
/* ================= R_SetViewMatrix Sets up the world to view matrix for a given viewParm ================= */ void R_SetViewMatrix( viewDef_t *viewDef ) { idVec3 origin; viewEntity_t *world; float viewerMatrix[16]; static float s_flipMatrix[16] = { // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 }; world = &viewDef->worldSpace; memset(world, 0, sizeof(*world)); // the model matrix is an identity world->modelMatrix[0*4+0] = 1; world->modelMatrix[1*4+1] = 1; world->modelMatrix[2*4+2] = 1; // transform by the camera placement origin = viewDef->renderView.vieworg; viewerMatrix[0] = viewDef->renderView.viewaxis[0][0]; viewerMatrix[4] = viewDef->renderView.viewaxis[0][1]; viewerMatrix[8] = viewDef->renderView.viewaxis[0][2]; viewerMatrix[12] = -origin[0] * viewerMatrix[0] + -origin[1] * viewerMatrix[4] + -origin[2] * viewerMatrix[8]; viewerMatrix[1] = viewDef->renderView.viewaxis[1][0]; viewerMatrix[5] = viewDef->renderView.viewaxis[1][1]; viewerMatrix[9] = viewDef->renderView.viewaxis[1][2]; viewerMatrix[13] = -origin[0] * viewerMatrix[1] + -origin[1] * viewerMatrix[5] + -origin[2] * viewerMatrix[9]; viewerMatrix[2] = viewDef->renderView.viewaxis[2][0]; viewerMatrix[6] = viewDef->renderView.viewaxis[2][1]; viewerMatrix[10] = viewDef->renderView.viewaxis[2][2]; viewerMatrix[14] = -origin[0] * viewerMatrix[2] + -origin[1] * viewerMatrix[6] + -origin[2] * viewerMatrix[10]; viewerMatrix[3] = 0; viewerMatrix[7] = 0; viewerMatrix[11] = 0; viewerMatrix[15] = 1; // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) myGlMultMatrix( viewerMatrix, s_flipMatrix, world->modelViewMatrix ); }
/* ================= R_RotateForViewer Sets up the modelview matrix for a given viewParm ================= */ void R_RotateForViewer (void) { float viewerMatrix[16]; vec3_t origin; int j; Com_Memset (&tr.or, 0, sizeof(tr.or)); tr.or.axis[0][0] = 1; tr.or.axis[1][1] = 1; tr.or.axis[2][2] = 1; VectorCopy (tr.viewParms.or.origin, tr.or.viewOrigin); // transform by the camera placement VectorCopy( tr.viewParms.or.origin, origin ); viewerMatrix[0] = tr.viewParms.or.axis[0][0]; viewerMatrix[4] = tr.viewParms.or.axis[0][1]; viewerMatrix[8] = tr.viewParms.or.axis[0][2]; viewerMatrix[12] = -origin[0] * viewerMatrix[0] + -origin[1] * viewerMatrix[4] + -origin[2] * viewerMatrix[8]; viewerMatrix[1] = tr.viewParms.or.axis[1][0]; viewerMatrix[5] = tr.viewParms.or.axis[1][1]; viewerMatrix[9] = tr.viewParms.or.axis[1][2]; viewerMatrix[13] = -origin[0] * viewerMatrix[1] + -origin[1] * viewerMatrix[5] + -origin[2] * viewerMatrix[9]; viewerMatrix[2] = tr.viewParms.or.axis[2][0]; viewerMatrix[6] = tr.viewParms.or.axis[2][1]; viewerMatrix[10] = tr.viewParms.or.axis[2][2]; viewerMatrix[14] = -origin[0] * viewerMatrix[2] + -origin[1] * viewerMatrix[6] + -origin[2] * viewerMatrix[10]; viewerMatrix[3] = 0; viewerMatrix[7] = 0; viewerMatrix[11] = 0; viewerMatrix[15] = 1; // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) myGlMultMatrix( viewerMatrix, s_flipMatrix, tr.or.modelMatrix ); for (j=0;j<16;j++) { tr.or.u_modelMatrix[j]=viewerMatrix[j]; } tr.viewParms.world = tr.or; }
/* ====================== R_LockSurfaceScene r_lockSurfaces allows a developer to move around without changing the composition of the scene, including culling. The only thing that is modified is the view position and axis, no front end work is done at all Add the stored off command again, so the new rendering will use EXACTLY the same surfaces, including all the culling, even though the transformation matricies have been changed. This allow the culling tightness to be evaluated interactively. ====================== */ void R_LockSurfaceScene( viewDef_t *parms ) { // set the matrix for world space to eye space R_SetViewMatrix( parms ); tr.lockSurfacesCmd.viewDef->worldSpace = parms->worldSpace; // update the view origin and axis, and all // the entity matricies for (viewEntity_t* vModel = tr.lockSurfacesCmd.viewDef->viewEntitys; vModel; vModel = vModel->next) { myGlMultMatrix( vModel->modelMatrix, tr.lockSurfacesCmd.viewDef->worldSpace.modelViewMatrix, vModel->modelViewMatrix ); } // add the stored off surface commands again auto cmd = R_GetCommandBuffer<drawSurfsCommand_t>(); *cmd = tr.lockSurfacesCmd; }
// Sets up the modelview matrix for a given viewParm void R_RotateForViewer( void ) { float viewerMatrix[16]; vector3 origin; memset (&tr.or, 0, sizeof(tr.or)); tr.or.axis[0].x = 1; tr.or.axis[1].y = 1; tr.or.axis[2].z = 1; VectorCopy (&tr.viewParms.or.origin, &tr.or.viewOrigin); // transform by the camera placement VectorCopy( &tr.viewParms.or.origin, &origin ); viewerMatrix[ 0] = tr.viewParms.or.axis[0].x; viewerMatrix[ 4] = tr.viewParms.or.axis[0].y; viewerMatrix[ 8] = tr.viewParms.or.axis[0].z; viewerMatrix[12] = -origin.x * viewerMatrix[0] + -origin.y * viewerMatrix[4] + -origin.z * viewerMatrix[8]; viewerMatrix[ 1] = tr.viewParms.or.axis[1].x; viewerMatrix[ 5] = tr.viewParms.or.axis[1].y; viewerMatrix[ 9] = tr.viewParms.or.axis[1].z; viewerMatrix[13] = -origin.x * viewerMatrix[1] + -origin.y * viewerMatrix[5] + -origin.z * viewerMatrix[9]; viewerMatrix[ 2] = tr.viewParms.or.axis[2].x; viewerMatrix[ 6] = tr.viewParms.or.axis[2].y; viewerMatrix[10] = tr.viewParms.or.axis[2].z; viewerMatrix[14] = -origin.x * viewerMatrix[2] + -origin.y * viewerMatrix[6] + -origin.z * viewerMatrix[10]; viewerMatrix[ 3] = 0; viewerMatrix[ 7] = 0; viewerMatrix[11] = 0; viewerMatrix[15] = 1; // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) myGlMultMatrix( viewerMatrix, s_flipMatrix, tr.or.modelMatrix ); tr.viewParms.world = tr.or; }
// q3mme void R_RotateForWorld ( const orientationr_t* input, orientationr_t* world ) { float viewerMatrix[16]; const float *origin = input->origin; Com_Memset ( world, 0, sizeof(*world)); world->axis[0][0] = 1; world->axis[1][1] = 1; world->axis[2][2] = 1; // transform by the camera placement VectorCopy( origin, world->viewOrigin ); // VectorCopy( origin, world->viewOrigin ); viewerMatrix[0] = input->axis[0][0]; viewerMatrix[4] = input->axis[0][1]; viewerMatrix[8] = input->axis[0][2]; viewerMatrix[12] = -origin[0] * viewerMatrix[0] + -origin[1] * viewerMatrix[4] + -origin[2] * viewerMatrix[8]; viewerMatrix[1] = input->axis[1][0]; viewerMatrix[5] = input->axis[1][1]; viewerMatrix[9] = input->axis[1][2]; viewerMatrix[13] = -origin[0] * viewerMatrix[1] + -origin[1] * viewerMatrix[5] + -origin[2] * viewerMatrix[9]; viewerMatrix[2] = input->axis[2][0]; viewerMatrix[6] = input->axis[2][1]; viewerMatrix[10] = input->axis[2][2]; viewerMatrix[14] = -origin[0] * viewerMatrix[2] + -origin[1] * viewerMatrix[6] + -origin[2] * viewerMatrix[10]; viewerMatrix[3] = 0; viewerMatrix[7] = 0; viewerMatrix[11] = 0; viewerMatrix[15] = 1; // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) myGlMultMatrix( viewerMatrix, s_flipMatrix, world->modelMatrix ); }
/* ================ RB_PrepareStageTexturing ================ */ void RB_PrepareStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) { // set privatePolygonOffset if necessary if ( pStage->privatePolygonOffset ) { qglEnable( GL_POLYGON_OFFSET_FILL ); qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset ); } // set the texture matrix if needed if ( pStage->texture.hasMatrix ) { RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture ); } // texgens if ( pStage->texture.texgen == TG_DIFFUSE_CUBE ) { qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); } if ( pStage->texture.texgen == TG_SKYBOX_CUBE || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) { qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) ); } if ( pStage->texture.texgen == TG_SCREEN ) { qglEnable( GL_TEXTURE_GEN_S ); qglEnable( GL_TEXTURE_GEN_T ); qglEnable( GL_TEXTURE_GEN_Q ); float mat[16], plane[4]; myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); plane[0] = mat[0]; plane[1] = mat[4]; plane[2] = mat[8]; plane[3] = mat[12]; qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); plane[0] = mat[1]; plane[1] = mat[5]; plane[2] = mat[9]; plane[3] = mat[13]; qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); plane[0] = mat[3]; plane[1] = mat[7]; plane[2] = mat[11]; plane[3] = mat[15]; qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); } if ( pStage->texture.texgen == TG_SCREEN2 ) { qglEnable( GL_TEXTURE_GEN_S ); qglEnable( GL_TEXTURE_GEN_T ); qglEnable( GL_TEXTURE_GEN_Q ); float mat[16], plane[4]; myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); plane[0] = mat[0]; plane[1] = mat[4]; plane[2] = mat[8]; plane[3] = mat[12]; qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); plane[0] = mat[1]; plane[1] = mat[5]; plane[2] = mat[9]; plane[3] = mat[13]; qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); plane[0] = mat[3]; plane[1] = mat[7]; plane[2] = mat[11]; plane[3] = mat[15]; qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); } if ( pStage->texture.texgen == TG_GLASSWARP ) { if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) { qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP ); qglEnable( GL_FRAGMENT_PROGRAM_ARB ); GL_SelectTexture( 2 ); globalImages->scratchImage->Bind(); GL_SelectTexture( 1 ); globalImages->scratchImage2->Bind(); qglEnable( GL_TEXTURE_GEN_S ); qglEnable( GL_TEXTURE_GEN_T ); qglEnable( GL_TEXTURE_GEN_Q ); float mat[16], plane[4]; myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat ); plane[0] = mat[0]; plane[1] = mat[4]; plane[2] = mat[8]; plane[3] = mat[12]; qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane ); plane[0] = mat[1]; plane[1] = mat[5]; plane[2] = mat[9]; plane[3] = mat[13]; qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane ); plane[0] = mat[3]; plane[1] = mat[7]; plane[2] = mat[11]; plane[3] = mat[15]; qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane ); GL_SelectTexture( 0 ); } } if ( pStage->texture.texgen == TG_REFLECT_CUBE ) { if ( tr.backEndRenderer == BE_ARB2 ) { // see if there is also a bump map specified const shaderStage_t *bumpStage = surf->material->GetBumpStage(); if ( bumpStage ) { // per-pixel reflection mapping with bump mapping GL_SelectTexture( 1 ); bumpStage->texture.image->Bind(); GL_SelectTexture( 0 ); qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() ); qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() ); qglEnableVertexAttribArrayARB( 9 ); qglEnableVertexAttribArrayARB( 10 ); qglEnableClientState( GL_NORMAL_ARRAY ); // Program env 5, 6, 7, 8 have been set in RB_SetProgramEnvironmentSpace qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT ); qglEnable( GL_FRAGMENT_PROGRAM_ARB ); qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT ); qglEnable( GL_VERTEX_PROGRAM_ARB ); } else { // per-pixel reflection mapping without a normal map qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglEnableClientState( GL_NORMAL_ARRAY ); qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT ); qglEnable( GL_FRAGMENT_PROGRAM_ARB ); qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT ); qglEnable( GL_VERTEX_PROGRAM_ARB ); } } else { qglEnable( GL_TEXTURE_GEN_S ); qglEnable( GL_TEXTURE_GEN_T ); qglEnable( GL_TEXTURE_GEN_R ); qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT ); qglEnableClientState( GL_NORMAL_ARRAY ); qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() ); qglMatrixMode( GL_TEXTURE ); float mat[16]; R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat ); qglLoadMatrixf( mat ); qglMatrixMode( GL_MODELVIEW ); } } }
/* ================= R_RotateForEntity Generates an orientation for an entity and viewParms Does NOT produce any GL calls Called by both the front end and the back end ================= */ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *or ) { float glMatrix[16]; vec3_t delta; float axisLength; if ( ent->e.reType != RT_MODEL && ent->e.reType != RT_POLY_LOCAL ) { *or = viewParms->world; return; } VectorCopy( ent->e.origin, or->origin ); if ( ent->e.renderfx & RF_AUTOAXIS ) { VectorCopy( viewParms->or.axis[0], or->axis[0] ); VectorScale( or->axis[0], -1, or->axis[0]); VectorCopy( viewParms->or.axis[1], or->axis[1] ); if ( !viewParms->isMirror ) VectorScale( or->axis[1], -1, or->axis[1]); VectorCopy( viewParms->or.axis[2], or->axis[2] ); VectorScale( or->axis[2], -1, or->axis[2]); } else if ( ent->e.renderfx & RF_AUTOAXIS2 ) { vec3_t v1, v2; // compute forward vector VectorSubtract( ent->e.origin, ent->e.oldorigin, or->axis[0] ); VectorNormalize( or->axis[0] ); // compute side vector VectorSubtract( ent->e.oldorigin, viewParms->or.origin, v1 ); VectorNormalize( v1 ); VectorSubtract( ent->e.origin, viewParms->or.origin, v2 ); VectorNormalize( v2 ); CrossProduct( v1, v2, or->axis[2] ); VectorNormalize( or->axis[2] ); // compute up vector CrossProduct( or->axis[0], or->axis[2], or->axis[1] ); // find midpoint VectorAdd( ent->e.origin, ent->e.oldorigin, or->origin ); VectorScale( or->origin, 0.5f, or->origin ); } else { VectorCopy( ent->e.axis[0], or->axis[0] ); VectorCopy( ent->e.axis[1], or->axis[1] ); VectorCopy( ent->e.axis[2], or->axis[2] ); } glMatrix[0] = or->axis[0][0]; glMatrix[4] = or->axis[1][0]; glMatrix[8] = or->axis[2][0]; glMatrix[12] = or->origin[0]; glMatrix[1] = or->axis[0][1]; glMatrix[5] = or->axis[1][1]; glMatrix[9] = or->axis[2][1]; glMatrix[13] = or->origin[1]; glMatrix[2] = or->axis[0][2]; glMatrix[6] = or->axis[1][2]; glMatrix[10] = or->axis[2][2]; glMatrix[14] = or->origin[2]; glMatrix[3] = 0; glMatrix[7] = 0; glMatrix[11] = 0; glMatrix[15] = 1; myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, or->modelMatrix ); // calculate the viewer origin in the model's space // needed for fog, specular, and environment mapping VectorSubtract( viewParms->or.origin, or->origin, delta ); // compensate for scale in the axes if necessary if ( ent->e.nonNormalizedAxes ) { axisLength = VectorLength( ent->e.axis[0] ); if ( !axisLength ) { axisLength = 0; } else { axisLength = 1.0f / axisLength; } } else { axisLength = 1.0f; } or->viewOrigin[0] = DotProduct( delta, or->axis[0] ) * axisLength; or->viewOrigin[1] = DotProduct( delta, or->axis[1] ) * axisLength; or->viewOrigin[2] = DotProduct( delta, or->axis[2] ) * axisLength; }
/* ============= RB_ARB2_CreateDrawInteractions ============= */ void RB_GLSL_CreateDrawInteractions( const drawSurf_t *surf ) { if ( !surf ) { return; } // perform setup here that will be constant for all interactions GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc ); //GL_Cull(CT_TWO_SIDED); qglEnableClientState(GL_VERTEX_ARRAY); //qglDisableClientState(GL_VERTEX_ARRAY); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); glUseProgram(program); float modelMatrix[16]; myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, modelMatrix); glUniformMatrix4fv(wvp, 1, GL_FALSE, &modelMatrix[0] ); //glUniformMatrix4fv(wvp1, 1, GL_FALSE, &surf->space->modelViewMatrix[0] ); //const float* mat = backEnd.viewDef->projectionMatrix; //glUniformMatrix4fv(wvp, 1, GL_FALSE, &mat[0] ); // enable the vertex arrays glEnableVertexAttribArray( 1 ); glEnableVertexAttribArray( 2 ); glEnableVertexAttribArray( 3 ); glEnableVertexAttribArray( 4 ); glEnableVertexAttribArray( 5 ); glEnableVertexAttribArray( 6 ); // texture 0 is the normalization cube map for the vector towards the light glActiveTexture(GL_TEXTURE0); backEnd.glState.currenttmu = 0; if ( backEnd.vLight->lightShader->IsAmbientLight() ) { globalImages->ambientNormalMap->Bind(); } else { globalImages->normalCubeMapImage->Bind(); } // texture 6 is the specular lookup table glActiveTexture(GL_TEXTURE6); backEnd.glState.currenttmu = 6; if ( r_testARBProgram.GetBool() ) { globalImages->specular2DTableImage->Bind(); // variable specularity in alpha channel } else { globalImages->specularTableImage->Bind(); } for ( ; surf ; surf=surf->nextOnLight ) { // set the vertex pointers idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache ); qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() ); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(idDrawVert), ac->xyz.ToFloatPtr()); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(idDrawVert), ac->st.ToFloatPtr()); glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(idDrawVert), ac->color); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(idDrawVert), ac->normal.ToFloatPtr()); glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(idDrawVert), ac->tangents[0].ToFloatPtr()); glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(idDrawVert), ac->tangents[1].ToFloatPtr()); idVec4 localLight; R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.vLight->globalLightOrigin, localLight.ToVec3() ); localLight.w = 0.0f; glUniform3fv(lightOrgin, 1, localLight.ToFloatPtr()); //glDrawElements(GL_TRIANGLES, surf->geo->numIndexes, GL_UNSIGNED_SHORT, surf->geo->indexes); // this may cause RB_ARB2_DrawInteraction to be exacuted multiple // times with different colors and images if the surface or light have multiple layers RB_CreateSingleDrawInteractions( surf, RB_GLSL_DrawInteraction ); } glDisableVertexAttribArray( 1 ); glDisableVertexAttribArray( 2 ); glDisableVertexAttribArray( 3 ); glDisableVertexAttribArray( 4 ); glDisableVertexAttribArray( 5 ); glDisableVertexAttribArray( 6 ); // disable features glActiveTexture( GL_TEXTURE6 ); backEnd.glState.currenttmu = 6; globalImages->BindNull(); glActiveTexture( GL_TEXTURE5 ); backEnd.glState.currenttmu = 5; globalImages->BindNull(); glActiveTexture( GL_TEXTURE4 ); backEnd.glState.currenttmu = 4; globalImages->BindNull(); glActiveTexture( GL_TEXTURE3 ); backEnd.glState.currenttmu = 3; globalImages->BindNull(); glActiveTexture( GL_TEXTURE2 ); backEnd.glState.currenttmu = 2; globalImages->BindNull(); glActiveTexture( GL_TEXTURE1 ); backEnd.glState.currenttmu = 1; globalImages->BindNull(); glUseProgram(0); backEnd.glState.currenttmu = -1; GL_SelectTexture(0 ); }