/* ============== Tess_CheckOverflow ============== */ void Tess_CheckOverflow( int verts, int indexes ) { // FIXME: need to check if a vbo is bound, otherwise we fail on startup if ( glState.currentVBO != nullptr && glState.currentIBO != nullptr ) { Tess_CheckVBOAndIBO( tess.vbo, tess.ibo ); } if ( tess.buildingVBO ) { return; } if ( tess.numVertexes + verts < SHADER_MAX_VERTEXES && tess.numIndexes + indexes < SHADER_MAX_INDEXES ) { return; } if ( r_logFile->integer ) { // don't just call LogComment, or we will get // a call to va() every frame! GLimp_LogComment( va ( "--- Tess_CheckOverflow(%i + %i vertices, %i + %i triangles ) ---\n", tess.numVertexes, verts, ( tess.numIndexes / 3 ), indexes ) ); } Tess_End(); if ( verts >= SHADER_MAX_VERTEXES ) { ri.Error( ERR_DROP, "Tess_CheckOverflow: verts > std::max (%d > %d)", verts, SHADER_MAX_VERTEXES ); } if ( indexes >= SHADER_MAX_INDEXES ) { ri.Error( ERR_DROP, "Tess_CheckOverflow: indexes > std::max (%d > %d)", indexes, SHADER_MAX_INDEXES ); } Tess_Begin( tess.stageIteratorFunc, tess.stageIteratorFunc2, tess.surfaceShader, tess.lightShader, tess.skipTangentSpaces, tess.skipVBO, tess.lightmapNum, tess.fogNum ); }
/* ** RB_DrawSun */ void RB_DrawSun( void ) { #if 0 float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; matrix_t transformMatrix; matrix_t modelViewMatrix; if ( !backEnd.skyRenderedThisView ) { return; } if ( !r_drawSun->integer ) { return; } GL_PushMatrix(); GL_BindProgram( &tr.genericShader ); // set uniforms GLSL_SetUniform_TCGen_Environment( &tr.genericShader, qfalse ); GLSL_SetUniform_InverseVertexColor( &tr.genericShader, qfalse ); if ( glConfig2.vboVertexSkinningAvailable ) { GLSL_SetUniform_VertexSkinning( &tr.genericShader, qfalse ); } GLSL_SetUniform_DeformGen( &tr.genericShader, DGEN_NONE ); GLSL_SetUniform_AlphaTest( &tr.genericShader, -1.0 ); MatrixSetupTranslation( transformMatrix, backEnd.viewParms.orientation.origin[ 0 ], backEnd.viewParms.orientation.origin[ 1 ], backEnd.viewParms.orientation.origin[ 2 ] ); MatrixMultiply( backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix ); GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix ); GL_LoadModelViewMatrix( modelViewMatrix ); GLSL_SetUniform_ModelMatrix( &tr.genericShader, backEnd.orientation.transformMatrix ); GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] ); GLSL_SetUniform_PortalClipping( &tr.genericShader, backEnd.viewParms.isPortal ); if ( backEnd.viewParms.isPortal ) { float plane[ 4 ]; // clipping plane in world space plane[ 0 ] = backEnd.viewParms.portalPlane.normal[ 0 ]; plane[ 1 ] = backEnd.viewParms.portalPlane.normal[ 1 ]; plane[ 2 ] = backEnd.viewParms.portalPlane.normal[ 2 ]; plane[ 3 ] = backEnd.viewParms.portalPlane.dist; GLSL_SetUniform_PortalPlane( &tr.genericShader, plane ); } dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3) size = dist * 0.4; VectorScale( tr.sunDirection, dist, origin ); PerpendicularVector( vec1, tr.sunDirection ); CrossProduct( tr.sunDirection, vec1, vec2 ); VectorScale( vec1, size, vec1 ); VectorScale( vec2, size, vec2 ); // farthest depth range glDepthRange( 1.0, 1.0 ); // FIXME: use quad stamp Tess_Begin( Tess_StageIteratorGeneric, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum ); VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 1; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 3; Tess_End(); // back to standard depth range glDepthRange( 0.0, 1.0 ); GL_PopMatrix(); #endif }
/* ============= RB_StretchPic ============= */ const void *RB_StretchPic( const void *data ) { int i; const stretchPicCommand_t *cmd; shader_t *shader; int numVerts, numIndexes; GLimp_LogComment( "--- RB_StretchPic ---\n" ); cmd = ( const stretchPicCommand_t * ) data; if ( !backEnd.projection2D ) { RB_SetGL2D(); } shader = cmd->shader; if ( shader != tess.surfaceShader ) { if ( tess.numIndexes ) { Tess_End(); } backEnd.currentEntity = &backEnd.entity2D; Tess_Begin( Tess_StageIteratorGeneric, NULL, shader, NULL, qfalse, qfalse, -1, tess.fogNum ); } Tess_CheckOverflow( 4, 6 ); numVerts = tess.numVertexes; numIndexes = tess.numIndexes; tess.numVertexes += 4; tess.numIndexes += 6; tess.indexes[ numIndexes ] = numVerts + 3; tess.indexes[ numIndexes + 1 ] = numVerts + 0; tess.indexes[ numIndexes + 2 ] = numVerts + 2; tess.indexes[ numIndexes + 3 ] = numVerts + 2; tess.indexes[ numIndexes + 4 ] = numVerts + 0; tess.indexes[ numIndexes + 5 ] = numVerts + 1; for ( i = 0; i < 4; i++ ) { tess.colors[ numVerts + i ][ 0 ] = backEnd.color2D[ 0 ]; tess.colors[ numVerts + i ][ 1 ] = backEnd.color2D[ 1 ]; tess.colors[ numVerts + i ][ 2 ] = backEnd.color2D[ 2 ]; tess.colors[ numVerts + i ][ 3 ] = backEnd.color2D[ 3 ]; } tess.xyz[ numVerts ][ 0 ] = cmd->x; tess.xyz[ numVerts ][ 1 ] = cmd->y; tess.xyz[ numVerts ][ 2 ] = 0; tess.xyz[ numVerts ][ 3 ] = 1; tess.texCoords[ numVerts ][ 0 ] = cmd->s1; tess.texCoords[ numVerts ][ 1 ] = cmd->t1; tess.texCoords[ numVerts ][ 2 ] = 0; tess.texCoords[ numVerts ][ 3 ] = 1; tess.xyz[ numVerts + 1 ][ 0 ] = cmd->x + cmd->w; tess.xyz[ numVerts + 1 ][ 1 ] = cmd->y; tess.xyz[ numVerts + 1 ][ 2 ] = 0; tess.xyz[ numVerts + 1 ][ 3 ] = 1; tess.texCoords[ numVerts + 1 ][ 0 ] = cmd->s2; tess.texCoords[ numVerts + 1 ][ 1 ] = cmd->t1; tess.texCoords[ numVerts + 1 ][ 2 ] = 0; tess.texCoords[ numVerts + 1 ][ 3 ] = 1; tess.xyz[ numVerts + 2 ][ 0 ] = cmd->x + cmd->w; tess.xyz[ numVerts + 2 ][ 1 ] = cmd->y + cmd->h; tess.xyz[ numVerts + 2 ][ 2 ] = 0; tess.xyz[ numVerts + 2 ][ 3 ] = 1; tess.texCoords[ numVerts + 2 ][ 0 ] = cmd->s2; tess.texCoords[ numVerts + 2 ][ 1 ] = cmd->t2; tess.texCoords[ numVerts + 2 ][ 2 ] = 0; tess.texCoords[ numVerts + 2 ][ 3 ] = 1; tess.xyz[ numVerts + 3 ][ 0 ] = cmd->x; tess.xyz[ numVerts + 3 ][ 1 ] = cmd->y + cmd->h; tess.xyz[ numVerts + 3 ][ 2 ] = 0; tess.xyz[ numVerts + 3 ][ 3 ] = 1; tess.texCoords[ numVerts + 3 ][ 0 ] = cmd->s1; tess.texCoords[ numVerts + 3 ][ 1 ] = cmd->t2; tess.texCoords[ numVerts + 3 ][ 2 ] = 0; tess.texCoords[ numVerts + 3 ][ 3 ] = 1; return ( const void * )( cmd + 1 ); }
static void RB_RenderDrawSurfaces( qboolean opaque, qboolean depthFill ) { trRefEntity_t *entity, *oldEntity; shader_t *shader, *oldShader; int lightmapNum, oldLightmapNum; qboolean depthRange, oldDepthRange; int i; drawSurf_t *drawSurf; GLimp_LogComment( "--- RB_RenderDrawSurfaces ---\n" ); // draw everything oldEntity = NULL; oldShader = NULL; oldLightmapNum = -1; oldDepthRange = qfalse; depthRange = qfalse; backEnd.currentLight = NULL; for ( i = 0, drawSurf = backEnd.viewParms.drawSurfs; i < backEnd.viewParms.numDrawSurfs; i++, drawSurf++ ) { // update locals entity = drawSurf->entity; shader = tr.sortedShaders[ drawSurf->shaderNum ]; lightmapNum = drawSurf->lightmapNum; if ( opaque ) { // skip all translucent surfaces that don't matter for this pass if ( shader->sort > SS_OPAQUE ) { break; } } else { // skip all opaque surfaces that don't matter for this pass if ( shader->sort <= SS_OPAQUE ) { continue; } } if ( entity == oldEntity && shader == oldShader && lightmapNum == oldLightmapNum ) { // fast path, same as previous sort rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); continue; } // change the tess parameters if needed // an "entityMergable" shader is a shader that can have surfaces from separate // entities merged into a single batch, like smoke and blood puff sprites if ( shader != oldShader || lightmapNum != oldLightmapNum || ( entity != oldEntity && !shader->entityMergable ) ) { if ( oldShader != NULL ) { Tess_End(); } if ( depthFill ) { Tess_Begin( Tess_StageIteratorDepthFill, NULL, shader, NULL, qtrue, qfalse, lightmapNum, tess.fogNum ); } else { Tess_Begin( Tess_StageIteratorGeneric, NULL, shader, NULL, qfalse, qfalse, lightmapNum, tess.fogNum ); } oldShader = shader; oldLightmapNum = lightmapNum; } // change the modelview matrix if needed if ( entity != oldEntity ) { depthRange = qfalse; if ( entity != &tr.worldEntity ) { backEnd.currentEntity = entity; // set up the transformation matrix R_RotateEntityForViewParms( backEnd.currentEntity, &backEnd.viewParms, &backEnd.orientation ); if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) { // hack the depth range to prevent view model from poking into walls depthRange = qtrue; } } else { backEnd.currentEntity = &tr.worldEntity; backEnd.orientation = backEnd.viewParms.world; } #if defined( USE_D3D10 ) // TODO #else GL_LoadModelViewMatrix( backEnd.orientation.modelViewMatrix ); #endif // change depthrange if needed if ( oldDepthRange != depthRange ) { #if defined( USE_D3D10 ) // TODO #else if ( depthRange ) { qglDepthRange( 0, 0.3 ); } else { qglDepthRange( 0, 1 ); } #endif oldDepthRange = depthRange; } oldEntity = entity; } // add the triangles for this surface rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); } // draw the contents of the last shader batch if ( oldShader != NULL ) { Tess_End(); } // go back to the world modelview matrix #if defined( USE_D3D10 ) // TODO #else GL_LoadModelViewMatrix( backEnd.viewParms.world.modelViewMatrix ); #endif if ( depthRange ) { #if defined( USE_D3D10 ) // TODO #else qglDepthRange( 0, 1 ); #endif } #if defined( USE_D3D10 ) // TODO #else GL_CheckErrors(); #endif }
/* ============== Tess_EndBegin ============== */ void Tess_EndBegin() { Tess_End(); Tess_Begin( tess.stageIteratorFunc, tess.stageIteratorFunc2, tess.surfaceShader, tess.lightShader, tess.skipTangentSpaces, tess.skipVBO, tess.lightmapNum, tess.fogNum ); }
/* ================== RB_RenderFlare ================== */ void RB_RenderFlare(flare_t * f) { float size; vec3_t color; backEnd.pc.c_flareRenders++; #if 1 //VectorScale(f->color, f->drawIntensity, color); VectorScale(colorWhite, f->drawIntensity, color); size = backEnd.viewParms.viewportWidth * (r_flareSize->value / 640.0f + 8 / -f->eyeZ); #else /* As flare sizes stay nearly constant with increasing distance we must decrease the intensity to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be got by considering the ratio of (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare) An important requirement is: intensity <= 1 for all distances. The formula used here to compute the intensity is as follows: intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2. As you can see, the intensity will have a max. of 1 when the distance is 0. The coefficient flareCoeff will determine the falloff speed with increasing distance. */ float distance, intensity, factor; // We don't want too big values anyways when dividing by distance if(f->eyeZ > -1.0f) distance = 1.0f; else distance = -f->eyeZ; // calculate the flare size size = backEnd.viewParms.viewportWidth * (r_flareSize->value / 640.0f + 8 / distance); factor = distance + size * sqrt(flareCoeff); intensity = flareCoeff * size * size / (factor * factor); VectorScale(f->color, f->drawIntensity * intensity, color); iColor[0] = color[0] * 255; iColor[1] = color[1] * 255; iColor[2] = color[2] * 255; #endif Tess_Begin(Tess_StageIteratorGeneric, tr.flareShader, NULL, qfalse, qfalse, -1); // FIXME: use quadstamp? tess.xyz[tess.numVertexes][0] = f->windowX - size; tess.xyz[tess.numVertexes][1] = f->windowY - size; tess.xyz[tess.numVertexes][2] = 0; tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = color[0]; tess.colors[tess.numVertexes][1] = color[1]; tess.colors[tess.numVertexes][2] = color[2]; tess.colors[tess.numVertexes][3] = 1; tess.numVertexes++; tess.xyz[tess.numVertexes][0] = f->windowX - size; tess.xyz[tess.numVertexes][1] = f->windowY + size; tess.xyz[tess.numVertexes][2] = 0; tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = color[0]; tess.colors[tess.numVertexes][1] = color[1]; tess.colors[tess.numVertexes][2] = color[2]; tess.colors[tess.numVertexes][3] = 1; tess.numVertexes++; tess.xyz[tess.numVertexes][0] = f->windowX + size; tess.xyz[tess.numVertexes][1] = f->windowY + size; tess.xyz[tess.numVertexes][2] = 0; tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = color[0]; tess.colors[tess.numVertexes][1] = color[1]; tess.colors[tess.numVertexes][2] = color[2]; tess.colors[tess.numVertexes][3] = 1; tess.numVertexes++; tess.xyz[tess.numVertexes][0] = f->windowX + size; tess.xyz[tess.numVertexes][1] = f->windowY - size; tess.xyz[tess.numVertexes][2] = 0; tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = color[0]; tess.colors[tess.numVertexes][1] = color[1]; tess.colors[tess.numVertexes][2] = color[2]; tess.colors[tess.numVertexes][3] = 1; tess.numVertexes++; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 1; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; Tess_End(); }
/* ** RB_DrawSun */ void RB_DrawSun(void) { float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; matrix_t transformMatrix; matrix_t modelViewMatrix; if (!backEnd.skyRenderedThisView) { return; } if (!r_drawSun->integer) { return; } #if defined(USE_D3D10) //TODO #else GL_PushMatrix(); gl_genericShader->DisableAlphaTesting(); gl_genericShader->DisablePortalClipping(); gl_genericShader->DisableVertexSkinning(); gl_genericShader->DisableVertexAnimation(); gl_genericShader->DisableDeformVertexes(); gl_genericShader->DisableTCGenEnvironment(); gl_genericShader->BindProgram(); // set uniforms gl_genericShader->SetUniform_ColorModulate(CGEN_VERTEX, AGEN_VERTEX); #endif MatrixSetupTranslation(transformMatrix, backEnd.viewParms.orientation.origin[0], backEnd.viewParms.orientation.origin[1], backEnd.viewParms.orientation.origin[2]); MatrixMultiplyMOD(backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix); #if defined(USE_D3D10) //TODO #else GL_LoadProjectionMatrix(backEnd.viewParms.projectionMatrix); GL_LoadModelViewMatrix(modelViewMatrix); gl_genericShader->SetUniform_ModelMatrix(backEnd.orientation.transformMatrix); gl_genericShader->SetUniform_ModelViewProjectionMatrix(glState.modelViewProjectionMatrix[glState.stackIndex]); gl_genericShader->SetPortalClipping(backEnd.viewParms.isPortal); #endif if (backEnd.viewParms.isPortal) { float plane[4]; // clipping plane in world space plane[0] = backEnd.viewParms.portalPlane.normal[0]; plane[1] = backEnd.viewParms.portalPlane.normal[1]; plane[2] = backEnd.viewParms.portalPlane.normal[2]; plane[3] = backEnd.viewParms.portalPlane.dist; #if defined(USE_D3D10) //TODO #else gl_genericShader->SetUniform_PortalPlane(plane); #endif } dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3) size = dist * 0.4; VectorScale(tr.sunDirection, dist, origin); PerpendicularVector(vec1, tr.sunDirection); CrossProduct(tr.sunDirection, vec1, vec2); VectorScale(vec1, size, vec1); VectorScale(vec2, size, vec2); // farthest depth range #if defined(USE_D3D10) //TODO #else glDepthRange(1.0, 1.0); #endif // FIXME: use quad stamp Tess_Begin(Tess_StageIteratorGeneric, NULL, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum); VectorCopy(origin, temp); VectorSubtract(temp, vec1, temp); VectorSubtract(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorAdd(temp, vec1, temp); VectorSubtract(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorAdd(temp, vec1, temp); VectorAdd(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorSubtract(temp, vec1, temp); VectorAdd(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 1; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; Tess_End(); // back to normal depth range #if defined(USE_D3D10) //TODO #else glDepthRange(0.0, 1.0); GL_PopMatrix(); #endif }