/* ============= SetColor ============= */ void idGuiModel::SetColor( float r, float g, float b, float a ) { if ( !glConfig.isInitialized ) { return; } if ( r == surf->color[0] && g == surf->color[1] && b == surf->color[2] && a == surf->color[3] ) { return; // no change } if ( surf->numVerts ) { AdvanceSurf(); } // change the parms surf->color[0] = r; surf->color[1] = g; surf->color[2] = b; surf->color[3] = a; // ---> sikk - pass shader parms to GUI model for post FX // keep respective color and shaderParms equal for ( int i = 0; i < 4; i++ ) { surf->shaderParms[ i ] = surf->color[ i ]; } // <--- sikk - pass shader parms to GUI model for post FX }
/* ============= AllocTris ============= */ idDrawVert * idGuiModel::AllocTris( int vertCount, const triIndex_t * tempIndexes, int indexCount, const idMaterial * material, const uint64 glState, const stereoDepthType_t stereoType ) { if ( material == NULL ) { return NULL; } if ( numIndexes + indexCount > MAX_INDEXES ) { static int warningFrame = 0; if ( warningFrame != tr.frameCount ) { warningFrame = tr.frameCount; idLib::Warning( "idGuiModel::AllocTris: MAX_INDEXES exceeded" ); } return NULL; } if ( numVerts + vertCount > MAX_VERTS ) { static int warningFrame = 0; if ( warningFrame != tr.frameCount ) { warningFrame = tr.frameCount; idLib::Warning( "idGuiModel::AllocTris: MAX_VERTS exceeded" ); } return NULL; } // break the current surface if we are changing to a new material or we can't // fit the data into our allocated block if ( material != surf->material || glState != surf->glState || stereoType != surf->stereoType ) { if ( surf->numIndexes ) { AdvanceSurf(); } surf->material = material; surf->glState = glState; surf->stereoType = stereoType; } int startVert = numVerts; int startIndex = numIndexes; numVerts += vertCount; numIndexes += indexCount; surf->numIndexes += indexCount; if ( ( startIndex & 1 ) || ( indexCount & 1 ) ) { // slow for write combined memory! // this should be very rare, since quads are always an even index count for ( int i = 0; i < indexCount; i++ ) { indexPointer[startIndex + i] = startVert + tempIndexes[i]; } } else { for ( int i = 0; i < indexCount; i += 2 ) { WriteIndexPair( indexPointer + startIndex + i, startVert + tempIndexes[i], startVert + tempIndexes[i+1] ); } } return vertexPointer + startVert; }
/* ============= SetColor ============= */ void idGuiModel::SetColor( float r, float g, float b, float a ) { if( !glConfig.isInitialized ) { return; } if( r == surf->color[0] && g == surf->color[1] && b == surf->color[2] && a == surf->color[3] ) { return; // no change } if( surf->numVerts ) { AdvanceSurf(); } // change the parms surf->color[0] = r; surf->color[1] = g; surf->color[2] = b; surf->color[3] = a; }
/* ============= SetShaderParm ============= */ void idGuiModel::SetShaderParm( int parm, float value ) { if ( !glConfig.isInitialized ) { return; } if ( surf->shaderParms[ parm ] == value ) { return; // no change } if ( surf->numVerts ) { AdvanceSurf(); } // change the parm surf->shaderParms[ parm ] = value; // keep respective color and shaderParms equal if ( parm >= 0 && parm < 4 ) { surf->color[ parm ] = value; } }
/* ================ idGuiModel::Clear Begins collecting draw commands into surfaces ================ */ void idGuiModel::Clear() { surfaces.SetNum( 0 ); AdvanceSurf(); }
/* ============= DrawStretchTri x/y/w/h are in the 0,0 to 640,480 range ============= */ void idGuiModel::DrawStretchTri( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) { idDrawVert tempVerts[3]; glIndex_t tempIndexes[3]; int vertCount = 3; int indexCount = 3; if ( !glConfig.isInitialized ) { return; } if ( !material ) { return; } tempIndexes[0] = 1; tempIndexes[1] = 0; tempIndexes[2] = 2; tempVerts[0].xyz[0] = p1.x; tempVerts[0].xyz[1] = p1.y; tempVerts[0].xyz[2] = 0; tempVerts[0].st[0] = t1.x; tempVerts[0].st[1] = t1.y; tempVerts[0].normal[0] = 0; tempVerts[0].normal[1] = 0; tempVerts[0].normal[2] = 1; tempVerts[0].tangents[0][0] = 1; tempVerts[0].tangents[0][1] = 0; tempVerts[0].tangents[0][2] = 0; tempVerts[0].tangents[1][0] = 0; tempVerts[0].tangents[1][1] = 1; tempVerts[0].tangents[1][2] = 0; tempVerts[1].xyz[0] = p2.x; tempVerts[1].xyz[1] = p2.y; tempVerts[1].xyz[2] = 0; tempVerts[1].st[0] = t2.x; tempVerts[1].st[1] = t2.y; tempVerts[1].normal[0] = 0; tempVerts[1].normal[1] = 0; tempVerts[1].normal[2] = 1; tempVerts[1].tangents[0][0] = 1; tempVerts[1].tangents[0][1] = 0; tempVerts[1].tangents[0][2] = 0; tempVerts[1].tangents[1][0] = 0; tempVerts[1].tangents[1][1] = 1; tempVerts[1].tangents[1][2] = 0; tempVerts[2].xyz[0] = p3.x; tempVerts[2].xyz[1] = p3.y; tempVerts[2].xyz[2] = 0; tempVerts[2].st[0] = t3.x; tempVerts[2].st[1] = t3.y; tempVerts[2].normal[0] = 0; tempVerts[2].normal[1] = 0; tempVerts[2].normal[2] = 1; tempVerts[2].tangents[0][0] = 1; tempVerts[2].tangents[0][1] = 0; tempVerts[2].tangents[0][2] = 0; tempVerts[2].tangents[1][0] = 0; tempVerts[2].tangents[1][1] = 1; tempVerts[2].tangents[1][2] = 0; // break the current surface if we are changing to a new material if ( material != surf->material ) { if ( surf->numVerts ) { AdvanceSurf(); } const_cast<idMaterial *>(material)->EnsureNotPurged(); // in case it was a gui item started before a level change surf->material = material; } int numVerts = verts.Num(); int numIndexes = indexes.Num(); verts.AssureSize( numVerts + vertCount ); indexes.AssureSize( numIndexes + indexCount ); surf->numVerts += vertCount; surf->numIndexes += indexCount; for ( int i = 0; i < indexCount; i++ ) { indexes[numIndexes + i] = numVerts + tempIndexes[i] - surf->firstVert; } memcpy( &verts[numVerts], tempVerts, vertCount * sizeof( verts[0] ) ); }
/* ================ idGuiModel::Clear Begins collecting draw commands into surfaces ================ */ void idGuiModel::Clear() { surfaces.SetNum( 0, false ); indexes.SetNum( 0, false ); verts.SetNum( 0, false ); AdvanceSurf(); }
/* ============= DrawStretchPic ============= */ void idGuiModel::DrawStretchPic( const idDrawVert *dverts, const glIndex_t *dindexes, int vertCount, int indexCount, const idMaterial *hShader, bool clip, float min_x, float min_y, float max_x, float max_y ) { if ( !glConfig.isInitialized ) { return; } if ( !( dverts && dindexes && vertCount && indexCount && hShader ) ) { return; } // break the current surface if we are changing to a new material if ( hShader != surf->material ) { if ( surf->numVerts ) { AdvanceSurf(); } const_cast<idMaterial *>(hShader)->EnsureNotPurged(); // in case it was a gui item started before a level change surf->material = hShader; } // add the verts and indexes to the current surface if ( clip ) { int i, j; // FIXME: this is grim stuff, and should be rewritten if we have any significant // number of guis asking for clipping idFixedWinding w; for ( i = 0; i < indexCount; i += 3 ) { w.Clear(); w.AddPoint(idVec5(dverts[dindexes[i]].xyz.x, dverts[dindexes[i]].xyz.y, dverts[dindexes[i]].xyz.z, dverts[dindexes[i]].st.x, dverts[dindexes[i]].st.y)); w.AddPoint(idVec5(dverts[dindexes[i+1]].xyz.x, dverts[dindexes[i+1]].xyz.y, dverts[dindexes[i+1]].xyz.z, dverts[dindexes[i+1]].st.x, dverts[dindexes[i+1]].st.y)); w.AddPoint(idVec5(dverts[dindexes[i+2]].xyz.x, dverts[dindexes[i+2]].xyz.y, dverts[dindexes[i+2]].xyz.z, dverts[dindexes[i+2]].st.x, dverts[dindexes[i+2]].st.y)); for ( j = 0; j < 3; j++ ) { if ( w[j].x < min_x || w[j].x > max_x || w[j].y < min_y || w[j].y > max_y ) { break; } } if ( j < 3 ) { idPlane p; p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = 1.0f; p.SetDist( min_x ); w.ClipInPlace( p ); p.Normal().y = p.Normal().z = 0.0f; p.Normal().x = -1.0f; p.SetDist( -max_x ); w.ClipInPlace( p ); p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = 1.0f; p.SetDist( min_y ); w.ClipInPlace( p ); p.Normal().x = p.Normal().z = 0.0f; p.Normal().y = -1.0f; p.SetDist( -max_y ); w.ClipInPlace( p ); } int numVerts = verts.Num(); verts.SetNum( numVerts + w.GetNumPoints(), false ); for ( j = 0 ; j < w.GetNumPoints() ; j++ ) { idDrawVert *dv = &verts[numVerts+j]; dv->xyz.x = w[j].x; dv->xyz.y = w[j].y; dv->xyz.z = w[j].z; dv->st.x = w[j].s; dv->st.y = w[j].t; dv->normal.Set(0, 0, 1); dv->tangents[0].Set(1, 0, 0); dv->tangents[1].Set(0, 1, 0); } surf->numVerts += w.GetNumPoints(); for ( j = 2; j < w.GetNumPoints(); j++ ) { indexes.Append( numVerts - surf->firstVert ); indexes.Append( numVerts + j - 1 - surf->firstVert ); indexes.Append( numVerts + j - surf->firstVert ); surf->numIndexes += 3; } } } else { int numVerts = verts.Num(); int numIndexes = indexes.Num(); verts.AssureSize( numVerts + vertCount ); indexes.AssureSize( numIndexes + indexCount ); surf->numVerts += vertCount; surf->numIndexes += indexCount; for ( int i = 0; i < indexCount; i++ ) { indexes[numIndexes + i] = numVerts + dindexes[i] - surf->firstVert; } memcpy( &verts[numVerts], dverts, vertCount * sizeof( verts[0] ) ); } }