static void DrawSkySide( struct image_s *image, const int mins[2], const int maxs[2] ) { int s, t; GL_Bind( image ); #ifdef _XBOX int verts = ((maxs[0]+HALF_SKY_SUBDIVISIONS) - (mins[0]+HALF_SKY_SUBDIVISIONS)) * 2 + 2; #endif for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) { #ifdef _XBOX qglBeginEXT( GL_TRIANGLE_STRIP, verts, 0, 0, verts, 0); #else qglBegin( GL_TRIANGLE_STRIP ); #endif for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ ) { qglTexCoord2fv( s_skyTexCoords[t][s] ); qglVertex3fv( s_skyPoints[t][s] ); qglTexCoord2fv( s_skyTexCoords[t+1][s] ); qglVertex3fv( s_skyPoints[t+1][s] ); } qglEnd(); } }
/* ================ Draw_Char Draws one 8*8 graphics character with 0 being transparent. It can be clipped to the top of the screen to allow the console to be smoothly scrolled off. ================ */ void Draw_Char (int x, int y, int num) { int row, col; float frow, fcol, size; num &= 255; if ( (num&127) == 32 ) return; // space if (y <= -8) return; // totally off screen row = num>>4; col = num&15; frow = row*0.0625; fcol = col*0.0625; size = 0.0625; GL_Bind (draw_chars->texnum); qglBegin (GL_QUADS); qglTexCoord2f (fcol, frow); qglVertex2f (x, y); qglTexCoord2f (fcol + size, frow); qglVertex2f (x+8, y); qglTexCoord2f (fcol + size, frow + size); qglVertex2f (x+8, y+8); qglTexCoord2f (fcol, frow + size); qglVertex2f (x, y+8); qglEnd (); }
void Terrain_DrawFace( brush_t *brush, terrainFace_t *terraface ) { terrainMesh_t *pm; terravert_t a0; terravert_t a1; terravert_t a2; pm = brush->pTerrain; Terrain_GetTriangle( pm, terraface->index, &a0, &a1, &a2 ); qglBindTexture( GL_TEXTURE_2D, terraface->texture->texture_number ); qglBegin( GL_TRIANGLES ); // first tri qglColor4fv( a0.rgba ); qglTexCoord2fv( a0.tc ); qglVertex3fv( a0.xyz ); qglColor4fv( a1.rgba ); qglTexCoord2fv( a1.tc ); qglVertex3fv( a1.xyz ); qglColor4fv( a2.rgba ); qglTexCoord2fv( a2.tc ); qglVertex3fv( a2.xyz ); qglEnd (); }
/* ==================== TryAddNewEdge ==================== */ static bool TryAddNewEdge( optVertex_t *v1, optVertex_t *v2, optIsland_t *island ) { optEdge_t *e; // if the new edge crosses any other edges, don't add it for ( e = island->edges ; e ; e = e->islandLink ) { if ( EdgesCross( e->v1, e->v2, v1, v2 ) ) { return false; } } if ( dmapGlobals.drawflag ) { qglBegin( GL_LINES ); qglColor3f( 0, ( 128 + orandom.RandomInt( 127 ) )/ 255.0, 0 ); qglVertex3fv( v1->pv.ToFloatPtr() ); qglVertex3fv( v2->pv.ToFloatPtr() ); qglEnd(); qglFlush(); } // add it e = AllocEdge(); e->islandLink = island->edges; island->edges = e; e->v1 = v1; e->v2 = v2; e->created = true; // link the edge to its verts LinkEdge( e ); return true; }
/* ================ DrawAllEdges ================ */ static void DrawAllEdges() { // int i; if( !dmapGlobals.drawflag ) { return; } #if 0 Draw_ClearWindow(); qglBegin( GL_LINES ); for( i = 0 ; i < numOptEdges ; i++ ) { if( optEdges[i].v1 == NULL ) { continue; } qglColor3f( 1, 0, 0 ); qglVertex3fv( optEdges[i].v1->pv.ToFloatPtr() ); qglColor3f( 0, 0, 0 ); qglVertex3fv( optEdges[i].v2->pv.ToFloatPtr() ); } qglEnd(); qglFlush(); // GLimp_SwapBuffers(); #endif }
static void DrawSkySide( struct image_s *image, const int mins[2], const int maxs[2] ) { int s, t; GL_Bind( image ); #ifdef HAVE_GLES GLfloat vtx[3*1024]; // arbitrary sized GLfloat tex[2*1024]; int idx; GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY); GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY); if (glcol) qglDisableClientState(GL_COLOR_ARRAY); if (!text) qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); #endif for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) { #ifdef HAVE_GLES idx=0; #else qglBegin( GL_TRIANGLE_STRIP ); #endif for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ ) { #ifdef HAVE_GLES memcpy(tex+idx*2, s_skyTexCoords[t][s], sizeof(GLfloat)*2); memcpy(vtx+idx*3, s_skyPoints[t][s], sizeof(GLfloat)*3); idx++; memcpy(tex+idx*2, s_skyTexCoords[t+1][s], sizeof(GLfloat)*2); memcpy(vtx+idx*3, s_skyPoints[t+1][s], sizeof(GLfloat)*3); idx++; #else qglTexCoord2fv( s_skyTexCoords[t][s] ); qglVertex3fv( s_skyPoints[t][s] ); qglTexCoord2fv( s_skyTexCoords[t+1][s] ); qglVertex3fv( s_skyPoints[t+1][s] ); #endif } #ifdef HAVE_GLES //*TODO* Try to switch from many DrawArrays of GL_TRIANGLE_STRIP to a single DrawArrays of TRIANGLES to see if it perform better qglVertexPointer (3, GL_FLOAT, 0, vtx); qglTexCoordPointer(2, GL_FLOAT, 0, tex); qglDrawArrays(GL_TRIANGLE_STRIP, 0, idx); #else qglEnd(); #endif } #ifdef HAVE_GLES if (glcol) qglEnableClientState(GL_COLOR_ARRAY); if (!text) qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); #endif }
/* ================ DrawEdges ================ */ static void DrawEdges( optIsland_t* island ) { // optEdge_t *edge; if( !dmapGlobals.drawflag ) { return; } #if 0 Draw_ClearWindow(); qglBegin( GL_LINES ); for( edge = island->edges ; edge ; edge = edge->islandLink ) { if( edge->v1 == NULL ) { continue; } qglColor3f( 1, 0, 0 ); qglVertex3fv( edge->v1->pv.ToFloatPtr() ); qglColor3f( 0, 0, 0 ); qglVertex3fv( edge->v2->pv.ToFloatPtr() ); } qglEnd(); qglFlush(); // GLimp_SwapBuffers(); #endif }
/* ============= Draw_Pic ============= */ void Draw_Pic (int x, int y, char *pic) { image_t *gl; gl = Draw_FindPic (pic); if (!gl) { ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", pic); return; } if (scrap_dirty) Scrap_Upload (); if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) qglDisable (GL_ALPHA_TEST); GL_Bind (gl->texnum); qglBegin (GL_QUADS); qglTexCoord2f (gl->sl, gl->tl); qglVertex2f (x, y); qglTexCoord2f (gl->sh, gl->tl); qglVertex2f (x+gl->width, y); qglTexCoord2f (gl->sh, gl->th); qglVertex2f (x+gl->width, y+gl->height); qglTexCoord2f (gl->sl, gl->th); qglVertex2f (x, y+gl->height); qglEnd (); if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) qglEnable (GL_ALPHA_TEST); }
/* * ============= Draw_Fill * * Fills a box of pixels with a single color ============= */ void Draw_Fill(int x, int y, int w, int h, int c) { union { unsigned c; byte v[4]; } color; if ((unsigned)c > 255) ri.Sys_Error(ERR_FATAL, "Draw_Fill: bad color"); qglDisable(GL_TEXTURE_2D); color.c = d_8to24table[c]; qglColor3f(color.v[0] / 255.0, color.v[1] / 255.0, color.v[2] / 255.0); qglBegin(GL_QUADS); qglVertex2f(x, y); qglVertex2f(x + w, y); qglVertex2f(x + w, y + h); qglVertex2f(x, y + h); qglEnd(); qglColor3f(1, 1, 1); qglEnable(GL_TEXTURE_2D); }
/* * ============= Draw_TileClear * * This repeats a 64*64 tile graphic to fill the screen around a sized down * refresh window. ============= */ void Draw_TileClear(int x, int y, int w, int h, char *pic) { image_t *image; image = Draw_FindPic(pic); if (!image) { ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic); return; } if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !image->has_alpha) qglDisable(GL_ALPHA_TEST); GL_Bind(image->texnum); qglBegin(GL_QUADS); qglTexCoord2f(x / 64.0, y / 64.0); qglVertex2f(x, y); qglTexCoord2f((x + w) / 64.0, y / 64.0); qglVertex2f(x + w, y); qglTexCoord2f((x + w) / 64.0, (y + h) / 64.0); qglVertex2f(x + w, y + h); qglTexCoord2f(x / 64.0, (y + h) / 64.0); qglVertex2f(x, y + h); qglEnd(); if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !image->has_alpha) qglEnable(GL_ALPHA_TEST); }
static void DrawSkySideInner(struct image_s *image, const int mins[2], const int maxs[2]) { int s, t; GL_Bind(image); //qglDisable (GL_BLEND); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglEnable(GL_BLEND); GL_TexEnv(GL_MODULATE); for (t = mins[1] + HALF_SKY_SUBDIVISIONS; t < maxs[1] + HALF_SKY_SUBDIVISIONS; t++) { qglBegin(GL_TRIANGLE_STRIP); for (s = mins[0] + HALF_SKY_SUBDIVISIONS; s <= maxs[0] + HALF_SKY_SUBDIVISIONS; s++) { qglTexCoord2fv(s_skyTexCoords[t][s]); qglVertex3fv(s_skyPoints[t][s]); qglTexCoord2fv(s_skyTexCoords[t + 1][s]); qglVertex3fv(s_skyPoints[t + 1][s]); } qglEnd(); } qglDisable(GL_BLEND); }
/* ================= RB_ShadowFinish Darken everything that is is a shadow volume. We have to delay this until everything has been shadowed, because otherwise shadows from different body parts would overlap and double darken. ================= */ void RB_ShadowFinish( void ) { if ( r_shadows->integer != 2 ) { return; } if ( glConfig.stencilBits < 4 ) { return; } qglEnable( GL_STENCIL_TEST ); qglStencilFunc( GL_NOTEQUAL, 0, 255 ); qglDisable (GL_CLIP_PLANE0); qglDisable (GL_CULL_FACE); GL_Bind( tr.whiteImage ); qglLoadIdentity (); qglColor3f( 0.6f, 0.6f, 0.6f ); GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO ); // qglColor3f( 1, 0, 0 ); // GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); qglBegin( GL_QUADS ); qglVertex3f( -100, 100, -10 ); qglVertex3f( 100, 100, -10 ); qglVertex3f( 100, -100, -10 ); qglVertex3f( -100, -100, -10 ); qglEnd (); qglColor4f(1,1,1,1); qglDisable( GL_STENCIL_TEST ); }
/* * ================ Draw_Char * * Draws one 8*8 graphics character with 0 being transparent. It can be clipped * to the top of the screen to allow the console to be smoothly scrolled off. * ================ */ void Draw_Char(int x, int y, int num, int alpha) { int row, col; float frow, fcol, size; num &= 255; if (alpha >= 254) alpha = 254; else if (alpha <= 1) alpha = 1; if ((num & 127) == 32) return; /* space */ if (y <= -8) return; /* totally off screen */ row = num >> 4; col = num & 15; frow = row * 0.0625; fcol = col * 0.0625; size = 0.0625; { /* GLSTATE_DISABLE_ALPHATEST */ qglDisable(GL_ALPHA_TEST); GL_TexEnv(GL_MODULATE); qglColor4ub(255, 255, 255, alpha); /* GLSTATE_ENABLE_BLEND */ qglEnable(GL_BLEND); qglDepthMask(false); } GL_Bind(draw_chars->texnum); qglBegin(GL_QUADS); qglTexCoord2f(fcol, frow); qglVertex2f(x, y); qglTexCoord2f(fcol + size, frow); qglVertex2f(x + 8, y); qglTexCoord2f(fcol + size, frow + size); qglVertex2f(x + 8, y + 8); qglTexCoord2f(fcol, frow + size); qglVertex2f(x, y + 8); qglEnd(); { qglDepthMask(true); GL_TexEnv(GL_REPLACE); /* GLSTATE_DISABLE_BLEND */ qglDisable(GL_BLEND); qglColor4f(1,1,1,1); /* GLSTATE_ENABLE_ALPHATEST */ qglEnable(GL_ALPHA_TEST); } }
/* ================ idInterpolatedPosition::draw ================ */ void idInterpolatedPosition::draw( bool editMode ) { glLabeledPoint(colorBlue, startPos, (editMode) ? 5 : 3, "Start interpolated"); glLabeledPoint(colorBlue, endPos, (editMode) ? 5 : 3, "End interpolated"); qglBegin(GL_LINES); qglVertex3fv( startPos.ToFloatPtr() ); qglVertex3fv( endPos.ToFloatPtr() ); qglEnd(); }
/* ================== RB_STD_LightScale Perform extra blending passes to multiply the entire buffer by a floating point value ================== */ void RB_STD_LightScale( void ) { float v, f; if ( backEnd.overBright == 1.0f ) { return; } if ( r_skipLightScale.GetBool() ) { return; } // the scissor may be smaller than the viewport for subviews if ( r_useScissor.GetBool() ) { qglScissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, backEnd.viewDef->scissor.x2 - backEnd.viewDef->scissor.x1 + 1, backEnd.viewDef->scissor.y2 - backEnd.viewDef->scissor.y1 + 1 ); backEnd.currentScissor = backEnd.viewDef->scissor; } // full screen blends qglLoadIdentity(); qglMatrixMode( GL_PROJECTION ); qglPushMatrix(); qglLoadIdentity(); qglOrtho( 0, 1, 0, 1, -1, 1 ); GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_SRC_COLOR ); GL_Cull( CT_TWO_SIDED ); // so mirror views also get it globalImages->BindNull(); qglDisable( GL_DEPTH_TEST ); qglDisable( GL_STENCIL_TEST ); v = 1; while ( idMath::Fabs( v - backEnd.overBright ) > 0.01 ) { // a little extra slop f = backEnd.overBright / v; f /= 2; if ( f > 1 ) { f = 1; } qglColor3f( f, f, f ); v = v * f * 2; qglBegin( GL_QUADS ); qglVertex2f( 0,0 ); qglVertex2f( 0,1 ); qglVertex2f( 1,1 ); qglVertex2f( 1,0 ); qglEnd(); } qglPopMatrix(); qglEnable( GL_DEPTH_TEST ); qglMatrixMode( GL_MODELVIEW ); GL_Cull( CT_FRONT_SIDED ); }
/* ============= RB_DrawRotatePic2 ============= */ const void *RB_RotatePic2 ( const void *data ) { const rotatePicCommand_t *cmd; image_t *image; shader_t *shader; cmd = (const rotatePicCommand_t *)data; shader = cmd->shader; if ( shader->stages[0] ) { image = shader->stages[0]->bundle[0].image[0]; if ( image ) { if ( !backEnd.projection2D ) { RB_SetGL2D(); } // Get our current blend mode, etc. GL_State( shader->stages[0]->stateBits ); qglColor4ubv( backEnd.color2D ); qglPushMatrix(); // rotation point is going to be around the center of the passed in coordinates qglTranslatef( cmd->x, cmd->y, 0 ); qglRotatef( cmd->a, 0.0, 0.0, 1.0 ); GL_Bind( image ); qglBegin( GL_QUADS ); qglTexCoord2f( cmd->s1, cmd->t1); qglVertex2f( -cmd->w * 0.5f, -cmd->h * 0.5f ); qglTexCoord2f( cmd->s2, cmd->t1 ); qglVertex2f( cmd->w * 0.5f, -cmd->h * 0.5f ); qglTexCoord2f( cmd->s2, cmd->t2 ); qglVertex2f( cmd->w * 0.5f, cmd->h * 0.5f ); qglTexCoord2f( cmd->s1, cmd->t2 ); qglVertex2f( -cmd->w * 0.5f, cmd->h * 0.5f ); qglEnd(); qglPopMatrix(); // Hmmm, this is not too cool GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } } return (const void *)(cmd + 1); }
/* ================= RB_ShadowFinish Darken everything that is is a shadow volume. We have to delay this until everything has been shadowed, because otherwise shadows from different body parts would overlap and double darken. ================= */ void RB_ShadowFinish( void ) { if ( r_shadows->integer != 2 ) { return; } if ( glConfig.stencilBits < 4 ) { return; } #ifdef _DEBUG_STENCIL_SHADOWS return; #endif qglEnable( GL_STENCIL_TEST ); qglStencilFunc( GL_NOTEQUAL, 0, 255 ); qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); bool planeZeroBack = false; if (qglIsEnabled(GL_CLIP_PLANE0)) { planeZeroBack = true; qglDisable (GL_CLIP_PLANE0); } GL_Cull(CT_TWO_SIDED); //qglDisable (GL_CULL_FACE); GL_Bind( tr.whiteImage ); qglPushMatrix(); qglLoadIdentity (); // qglColor3f( 0.6f, 0.6f, 0.6f ); // GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO ); // qglColor3f( 1, 0, 0 ); // GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); qglColor4f( 0.0f, 0.0f, 0.0f, 0.5f ); //GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglBegin( GL_QUADS ); qglVertex3f( -100, 100, -10 ); qglVertex3f( 100, 100, -10 ); qglVertex3f( 100, -100, -10 ); qglVertex3f( -100, -100, -10 ); qglEnd (); qglColor4f(1,1,1,1); qglDisable( GL_STENCIL_TEST ); if (planeZeroBack) { qglEnable (GL_CLIP_PLANE0); } qglPopMatrix(); }
void R_RenderShadowEdges(void) { int i; int c, c2; int j, k; int i2; int c_edges = 0, c_rejected = 0; int hit[2]; // an edge is NOT a silhouette edge if its face doesn't face the light, // or if it has a reverse paired edge that also faces the light. // A well behaved polyhedron would have exactly two faces for each edge, // but lots of models have dangling edges or overfanned edges for (i = 0 ; i < tess.numVertexes ; i++) { c = numEdgeDefs[i]; for (j = 0 ; j < c ; j++) { if (!edgeDefs[i][j].facing) { continue; } hit[0] = 0; hit[1] = 0; i2 = edgeDefs[i][j].i2; c2 = numEdgeDefs[i2]; for (k = 0 ; k < c2 ; k++) { if (edgeDefs[i2][k].i2 == i) { hit[edgeDefs[i2][k].facing]++; } } // if it doesn't share the edge with another front facing // triangle, it is a sil edge if (hit[1] == 0) { qglBegin(GL_TRIANGLE_STRIP); qglVertex3fv(tess.xyz[i].v); qglVertex3fv(tess.xyz[i + tess.numVertexes].v); qglVertex3fv(tess.xyz[i2].v); qglVertex3fv(tess.xyz[i2 + tess.numVertexes].v); qglEnd(); c_edges++; } else { c_rejected++; } } } }
void R_DrawSkyBox (void) { int i; #if 0 qglEnable (GL_BLEND); GL_TexEnv( GL_MODULATE ); qglColor4f (1,1,1,0.5); qglDisable (GL_DEPTH_TEST); #endif if (skyrotate) { // check for no sky at all for (i=0 ; i<6 ; i++) if (skymins[0][i] < skymaxs[0][i] && skymins[1][i] < skymaxs[1][i]) break; if (i == 6) return; // nothing visible } qglPushMatrix (); qglTranslatef (r_origin[0], r_origin[1], r_origin[2]); qglRotatef (r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]); for (i=0 ; i<6 ; i++) { if (skyrotate) { // hack, forces full sky to draw when rotating skymins[0][i] = -1; skymins[1][i] = -1; skymaxs[0][i] = 1; skymaxs[1][i] = 1; } if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) continue; GL_Bind (sky_images[skytexorder[i]]->texnum); qglBegin (GL_QUADS); MakeSkyVec (skymins[0][i], skymins[1][i], i); MakeSkyVec (skymins[0][i], skymaxs[1][i], i); MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); MakeSkyVec (skymaxs[0][i], skymins[1][i], i); qglEnd (); } qglPopMatrix (); #if 0 glDisable (GL_BLEND); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor4f (1,1,1,0.5); glEnable (GL_DEPTH_TEST); #endif }
/* =============== RB_ShowImages Draw all the images to the screen, on top of whatever was there. This is used to test for texture thrashing. Also called by RE_EndRegistration =============== */ void RB_ShowImages(void) { int i; image_t *image; float x, y, w, h; int start, end; if(!backEnd.projection2D) { RB_SetGL2D(); } qglClear(GL_COLOR_BUFFER_BIT); qglFinish(); start = ri.Milliseconds(); for(i = 0 ; i < tr.numImages ; i++) { image = tr.images[i]; w = glConfig.vidWidth / 40; h = glConfig.vidHeight / 30; x = i % 40 * w; y = i / 30 * h; // show in proportional size in mode 2 if(r_showImages->integer == 2) { w *= image->uploadWidth / 512.0f; h *= image->uploadHeight / 512.0f; } GL_Bind(image); qglBegin(GL_QUADS); qglTexCoord2f(0, 0); qglVertex2f(x, y); qglTexCoord2f(1, 0); qglVertex2f(x + w, y); qglTexCoord2f(1, 1); qglVertex2f(x + w, y + h); qglTexCoord2f(0, 1); qglVertex2f(x, y + h); qglEnd(); } qglFinish(); end = ri.Milliseconds(); ri.Printf(PRINT_ALL, "%i msec to draw all images\n", end - start); }
/** * @note Unused. */ void RB_DrawBounds(vec3_t mins, vec3_t maxs) { vec3_t center; GL_Bind(tr.whiteImage); GL_State(GLS_POLYMODE_LINE); // box corners qglBegin(GL_LINES); qglColor3f(1, 1, 1); qglVertex3f(mins[0], mins[1], mins[2]); qglVertex3f(maxs[0], mins[1], mins[2]); qglVertex3f(mins[0], mins[1], mins[2]); qglVertex3f(mins[0], maxs[1], mins[2]); qglVertex3f(mins[0], mins[1], mins[2]); qglVertex3f(mins[0], mins[1], maxs[2]); qglVertex3f(maxs[0], maxs[1], maxs[2]); qglVertex3f(mins[0], maxs[1], maxs[2]); qglVertex3f(maxs[0], maxs[1], maxs[2]); qglVertex3f(maxs[0], mins[1], maxs[2]); qglVertex3f(maxs[0], maxs[1], maxs[2]); qglVertex3f(maxs[0], maxs[1], mins[2]); qglEnd(); center[0] = (mins[0] + maxs[0]) * 0.5; center[1] = (mins[1] + maxs[1]) * 0.5; center[2] = (mins[2] + maxs[2]) * 0.5; // center axis qglBegin(GL_LINES); qglColor3f(1, 0.85, 0); qglVertex3f(mins[0], center[1], center[2]); qglVertex3f(maxs[0], center[1], center[2]); qglVertex3f(center[0], mins[1], center[2]); qglVertex3f(center[0], maxs[1], center[2]); qglVertex3f(center[0], center[1], mins[2]); qglVertex3f(center[0], center[1], maxs[2]); qglEnd(); }
/* * ============= Draw_StretchPic -- only used for drawing console... * ============= */ void Draw_StretchPic(int x, int y, int w, int h, char *pic, float alpha) { image_t *gl; gl = Draw_FindPic(pic); if (!gl) { ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic); return; } if (scrap_dirty) Scrap_Upload(); if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha) qglDisable(GL_ALPHA_TEST); /* add alpha support */ if (gl->has_alpha || alpha < 1) { qglDisable(GL_ALPHA_TEST); GL_Bind(gl->texnum); GL_TexEnv(GL_MODULATE); qglColor4f(1, 1, 1, alpha); qglEnable(GL_BLEND); qglDepthMask(false); } else GL_Bind(gl->texnum); qglBegin(GL_QUADS); qglTexCoord2f(gl->sl, gl->tl); qglVertex2f(x, y); qglTexCoord2f(gl->sh, gl->tl); qglVertex2f(x + w, y); qglTexCoord2f(gl->sh, gl->th); qglVertex2f(x + w, y + h); qglTexCoord2f(gl->sl, gl->th); qglVertex2f(x, y + h); qglEnd(); /* add alpha support */ if (gl->has_alpha || alpha < 1) { qglDepthMask(true); GL_TexEnv(GL_REPLACE); qglDisable(GL_BLEND); qglColor4f(1, 1, 1, 1); qglEnable(GL_ALPHA_TEST); } if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha) qglEnable(GL_ALPHA_TEST); }
/* ================= RB_ShadowFinish Darken everything that is is a shadow volume. We have to delay this until everything has been shadowed, because otherwise shadows from different body parts would overlap and double darken. ================= */ void RB_ShadowFinish( void ) { if ( r_shadows->integer != 2 ) { return; } if ( glConfig.stencilBits < 4 ) { return; } qglEnable( GL_STENCIL_TEST ); qglStencilFunc( GL_NOTEQUAL, 0, 255 ); qglDisable (GL_CLIP_PLANE0); qglDisable (GL_CULL_FACE); GL_Bind( tr.whiteImage ); qglLoadIdentity (); qglColor3f( 0.6f, 0.6f, 0.6f ); GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO ); // qglColor3f( 1, 0, 0 ); // GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); #ifdef HAVE_GLES GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY); GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY); if (text) qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); if (glcol) qglDisableClientState( GL_COLOR_ARRAY ); GLfloat vtx[] = { -100, 100, -10, 100, 100, -10, 100, -100, -10, -100, -100, -10 }; qglVertexPointer ( 3, GL_FLOAT, 0, vtx ); qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); if (text) qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); if (glcol) qglEnableClientState( GL_COLOR_ARRAY ); #else qglBegin( GL_QUADS ); qglVertex3f( -100, 100, -10 ); qglVertex3f( 100, 100, -10 ); qglVertex3f( 100, -100, -10 ); qglVertex3f( -100, -100, -10 ); qglEnd (); #endif qglColor4f(1,1,1,1); qglDisable( GL_STENCIL_TEST ); }
/* * ============= Draw_Pic ============= */ void Draw_Pic(int x, int y, char *pic, float alpha) { image_t *gl; gl = Draw_FindPic(pic); if (!gl) { ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic); return; } if (scrap_dirty) Scrap_Upload(); if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha) qglDisable(GL_ALPHA_TEST); /* add alpha support */ { qglDisable(GL_ALPHA_TEST); qglBindTexture(GL_TEXTURE_2D, gl->texnum); GL_TexEnv(GL_MODULATE); qglColor4f(1, 1, 1, 0.999); /* need <1 for trans to work */ qglEnable(GL_BLEND); qglDepthMask(false); } GL_Bind(gl->texnum); qglBegin(GL_QUADS); qglTexCoord2f(gl->sl, gl->tl); qglVertex2f(x, y); qglTexCoord2f(gl->sh, gl->tl); qglVertex2f(x + gl->width, y); qglTexCoord2f(gl->sh, gl->th); qglVertex2f(x + gl->width, y + gl->height); qglTexCoord2f(gl->sl, gl->th); qglVertex2f(x, y + gl->height); qglEnd(); /* add alpha support */ { qglDepthMask(true); GL_TexEnv(GL_REPLACE); qglDisable(GL_BLEND); qglColor4f(1, 1, 1, 1); qglEnable(GL_ALPHA_TEST); } if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha) qglEnable(GL_ALPHA_TEST); }
/* ================ DrawBones Draws bounding box outlines for debugging ================ */ void DrawBones (skel_t *pose) { int i,j,k; vec3_t boneStart, boneEnd; GL_Bind( tr.whiteImage ); qglColor3f (1,1,1); qglDepthRange( 0, 0 ); // never occluded GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglBegin (GL_LINES); for (i = 0 ; i < pose->numBones; i++) { if(strcmp(pose->bones[i].name,"tag_") < 0) { qglVertex3fv (pose->bones[i].origin); qglColor3f (1,1,1); if(pose->bones[i].parent == -1 || pose->bones[i].parent > pose->numBones) qglVertex3fv (pose->bones[i].origin); else qglVertex3fv (pose->bones[pose->bones[i].parent].origin); qglColor3f (1,0,0); boneEnd[0] = pose->bones[i].origin[0] + pose->bones[i].axis[0][0]; boneEnd[1] = pose->bones[i].origin[1] + pose->bones[i].axis[1][0] ; boneEnd[2] = pose->bones[i].origin[2] + pose->bones[i].axis[2][0]; qglVertex3fv (boneEnd); boneEnd[0] = pose->bones[i].origin[0] - pose->bones[i].axis[0][0]; boneEnd[1] = pose->bones[i].origin[1] - pose->bones[i].axis[1][0]; boneEnd[2] = pose->bones[i].origin[2] - pose->bones[i].axis[2][0]; qglVertex3fv (boneEnd); qglColor3f (0,1,0); boneEnd[0] = pose->bones[i].origin[0] + pose->bones[i].axis[0][1]; boneEnd[1] = pose->bones[i].origin[1] + pose->bones[i].axis[1][1]; boneEnd[2] = pose->bones[i].origin[2] + pose->bones[i].axis[2][1]; qglVertex3fv (boneEnd); boneEnd[0] = pose->bones[i].origin[0] - pose->bones[i].axis[0][1]; boneEnd[1] = pose->bones[i].origin[1] - pose->bones[i].axis[1][1]; boneEnd[2] = pose->bones[i].origin[2] - pose->bones[i].axis[2][1]; qglVertex3fv (boneEnd); qglColor3f (0,0,1); boneEnd[0] = pose->bones[i].origin[0] + pose->bones[i].axis[0][2]; boneEnd[1] = pose->bones[i].origin[1] + pose->bones[i].axis[1][2]; boneEnd[2] = pose->bones[i].origin[2] + pose->bones[i].axis[2][2]; qglVertex3fv (boneEnd); boneEnd[0] = pose->bones[i].origin[0] - pose->bones[i].axis[0][2]; boneEnd[1] = pose->bones[i].origin[1] - pose->bones[i].axis[1][2]; boneEnd[2] = pose->bones[i].origin[2] - pose->bones[i].axis[2][2]; qglVertex3fv (boneEnd); qglColor3f (1,1,1); } } qglEnd (); qglDepthRange( 0, 1 ); }
/* =============== RB_ShowImages Draw all the images to the screen, on top of whatever was there. This is used to test for texture thrashing. Also called by RE_EndRegistration =============== */ void RB_ShowImages( void ) { image_t *image; float x, y, w, h; int start, end; if ( !backEnd.projection2D ) { RB_SetGL2D(); } qglFinish(); start = Sys_Milliseconds(); int i=0; // int iNumImages = R_Images_StartIteration(); while ( (image = R_Images_GetNextIteration()) != NULL) { w = glConfig.vidWidth / 20; h = glConfig.vidHeight / 15; x = i % 20 * w; y = i / 20 * h; // show in proportional size in mode 2 if ( r_showImages->integer == 2 ) { w *= image->width / 512.0; h *= image->height / 512.0; } GL_Bind( image ); #ifdef _XBOX qglBeginEXT (GL_QUADS, 4, 0, 0, 4, 0); #else qglBegin (GL_QUADS); #endif qglTexCoord2f( 0, 0 ); qglVertex2f( x, y ); qglTexCoord2f( 1, 0 ); qglVertex2f( x + w, y ); qglTexCoord2f( 1, 1 ); qglVertex2f( x + w, y + h ); qglTexCoord2f( 0, 1 ); qglVertex2f( x, y + h ); qglEnd(); i++; } qglFinish(); end = Sys_Milliseconds(); //VID_Printf( PRINT_ALL, "%i msec to draw all images\n", end - start ); }
void glTexturedBox(idVec3 &point, float size, const idMaterial *mat) { qglTranslatef(point.x, point.y, point.z); for (int i = 0; i < numQuads; i++) { qglBegin(GL_QUADS); for (int j = 0; j < 4; j++) { idVec3 v = cubeData[i * 4 + j].xyz; v *= size; qglTexCoord2fv(cubeData[i * 4 + j].st.ToFloatPtr()); qglVertex3fv(v.ToFloatPtr()); } qglEnd(); } }
/* * R_Bloom_Quad */ static inline void R_Bloom_Quad( int x, int y, int w, int h, float texwidth, float texheight ) { qglBegin( GL_QUADS ); qglTexCoord2f( 0, texheight ); qglVertex2f( x, glState.height-h-y ); qglTexCoord2f( 0, 0 ); qglVertex2f( x, glState.height-y ); qglTexCoord2f( texwidth, 0 ); qglVertex2f( x+w, glState.height-y ); qglTexCoord2f( texwidth, texheight ); qglVertex2f( x+w, glState.height-h ); qglEnd(); }
/* * R_Bloom_SamplePass */ static inline void R_Bloom_SamplePass( int xpos, int ypos ) { qglBegin( GL_QUADS ); qglTexCoord2f( 0, sampleText_tch ); qglVertex2f( xpos, ypos ); qglTexCoord2f( 0, 0 ); qglVertex2f( xpos, ypos+sample_height ); qglTexCoord2f( sampleText_tcw, 0 ); qglVertex2f( xpos+sample_width, ypos+sample_height ); qglTexCoord2f( sampleText_tcw, sampleText_tch ); qglVertex2f( xpos+sample_width, ypos ); qglEnd(); }
/* ================ glLabeledPoint ================ */ void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label) { qglColor3fv( color.ToFloatPtr() ); qglPointSize( size ); qglBegin( GL_POINTS ); qglVertex3fv( point.ToFloatPtr() ); qglEnd(); idVec3 v = point; v.x += 1; v.y += 1; v.z += 1; qglRasterPos3fv( v.ToFloatPtr() ); qglCallLists( strlen(label), GL_UNSIGNED_BYTE, label ); }