summaryrefslogtreecommitdiff
path: root/src/gl_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gl_draw.c')
-rw-r--r--src/gl_draw.c335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/gl_draw.c b/src/gl_draw.c
new file mode 100644
index 0000000..d906239
--- /dev/null
+++ b/src/gl_draw.c
@@ -0,0 +1,335 @@
+/*
+Copyright (C) 2003-2006 Andrey Nazarov
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "gl_local.h"
+
+drawStatic_t draw;
+
+static inline void _GL_StretchPic(
+ float x, float y, float w, float h,
+ float s1, float t1, float s2, float t2,
+ const byte *color, int texnum, int flags )
+{
+ vec_t *dst_vert;
+ uint32_t *dst_color;
+
+ if( tess.numverts + 4 > TESS_MAX_VERTICES ||
+ ( tess.numverts && tess.texnum[0] != texnum ) )
+ {
+ GL_Flush2D();
+ }
+
+ tess.texnum[0] = texnum;
+
+ dst_vert = tess.vertices + tess.numverts * 4;
+ Vector4Set( dst_vert, x, y, s1, t1 );
+ Vector4Set( dst_vert + 4, x + w, y, s2, t1 );
+ Vector4Set( dst_vert + 8, x + w, y + h, s2, t2 );
+ Vector4Set( dst_vert + 12, x, y + h, s1, t2 );
+
+ dst_color = ( uint32_t * )tess.colors + tess.numverts;
+ dst_color[0] = *( const uint32_t * )color;
+ dst_color[1] = *( const uint32_t * )color;
+ dst_color[2] = *( const uint32_t * )color;
+ dst_color[3] = *( const uint32_t * )color;
+
+ if( flags & if_transparent ) {
+ if( ( flags & if_paletted ) && draw.scale == 1 ) {
+ tess.flags |= 1;
+ } else {
+ tess.flags |= 2;
+ }
+ }
+ if( color[3] != 255 ) {
+ tess.flags |= 2;
+ }
+
+ tess.numverts += 4;
+}
+
+#define GL_StretchPic(x,y,w,h,s1,t1,s2,t2,color,image) \
+ _GL_StretchPic(x,y,w,h,s1,t1,s2,t2,color,(image)->texnum,(image)->flags)
+
+void GL_Blend( void ) {
+ color_t color = {
+ glr.fd.blend[0] * 255,
+ glr.fd.blend[1] * 255,
+ glr.fd.blend[2] * 255,
+ glr.fd.blend[3] * 255
+ };
+
+ _GL_StretchPic( glr.fd.x, glr.fd.y, glr.fd.width, glr.fd.height, 0, 0, 1, 1,
+ color, TEXNUM_WHITE, 0 );
+}
+
+void R_SetColor( int flags, const color_t color ) {
+ draw.flags &= ~DRAW_COLOR_MASK;
+
+ if( flags == DRAW_COLOR_CLEAR ) {
+ FastColorCopy( colorWhite, draw.colors[0] );
+ FastColorCopy( colorWhite, draw.colors[1] );
+ return;
+ }
+ if( flags == DRAW_COLOR_ALPHA ) {
+ draw.colors[0][3] = *( float * )color * 255;
+ draw.colors[1][3] = *( float * )color * 255;
+ } else if( flags == DRAW_COLOR_INDEXED ) {
+ *( uint32_t * )draw.colors[0] = d_8to24table[ *( uint32_t * )color & 255 ];
+ } else {
+ if( flags & DRAW_COLOR_RGB ) {
+ VectorCopy( color, draw.colors[0] );
+ VectorCopy( colorWhite, draw.colors[1] );
+ }
+ if( flags & DRAW_COLOR_ALPHA ) {
+ draw.colors[0][3] = color[3];
+ draw.colors[1][3] = color[3];
+ }
+ }
+
+ draw.flags |= flags;
+}
+
+void R_SetClipRect( int flags, const clipRect_t *clip ) {
+ clipRect_t rc;
+ float scale;
+
+ if( ( draw.flags & DRAW_CLIP_MASK ) == flags ) {
+ return;
+ }
+
+ GL_Flush2D();
+
+ if( flags == DRAW_CLIP_DISABLED ) {
+ qglDisable( GL_SCISSOR_TEST );
+ draw.flags &= ~DRAW_CLIP_MASK;
+ return;
+ }
+
+ scale = 1 / draw.scale;
+
+ rc.left = 0;
+ rc.top = 0;
+ if( flags & DRAW_CLIP_LEFT ) {
+ rc.left = clip->left * scale;
+ if( rc.left < 0 ) {
+ rc.left = 0;
+ }
+ }
+ if( flags & DRAW_CLIP_TOP ) {
+ rc.top = clip->top * scale;
+ if( rc.top < 0 ) {
+ rc.top = 0;
+ }
+ }
+
+ rc.right = gl_config.vidWidth;
+ rc.bottom = gl_config.vidHeight;
+ if( flags & DRAW_CLIP_RIGHT ) {
+ rc.right = clip->right * scale;
+ if( rc.right > gl_config.vidWidth ) {
+ rc.right = gl_config.vidWidth;
+ }
+ }
+ if( flags & DRAW_CLIP_BOTTOM ) {
+ rc.bottom = clip->bottom * scale;
+ if( rc.bottom > gl_config.vidHeight ) {
+ rc.bottom = gl_config.vidHeight;
+ }
+ }
+
+ if( rc.right < rc.left ) {
+ rc.right = rc.left;
+ }
+ if( rc.bottom < rc.top ) {
+ rc.bottom = rc.top;
+ }
+
+ qglEnable( GL_SCISSOR_TEST );
+ qglScissor( rc.left, gl_config.vidHeight - rc.bottom,
+ rc.right - rc.left, rc.bottom - rc.top );
+ draw.flags = ( draw.flags & ~DRAW_CLIP_MASK ) | flags;
+}
+
+void R_SetScale( float *scale ) {
+ float f = scale ? *scale : 1;
+
+ if( draw.scale == f ) {
+ return;
+ }
+
+ GL_Flush2D();
+
+ qglMatrixMode( GL_PROJECTION );
+ qglLoadIdentity();
+
+ qglOrtho( 0, gl_config.vidWidth * f, gl_config.vidHeight * f, 0, -1, 1 );
+
+ draw.scale = f;
+}
+
+qboolean R_GetPicSize( int *w, int *h, qhandle_t pic ) {
+ image_t *image = IMG_ForHandle( pic );
+
+ if( w ) {
+ *w = image->width;
+ }
+ if( h ) {
+ *h = image->height;
+ }
+ return image->flags & if_transparent;
+}
+
+void R_DrawStretchPicST( int x, int y, int w, int h, float s1, float t1,
+ float s2, float t2, qhandle_t pic )
+{
+ /* TODO: scrap support */
+ GL_StretchPic( x, y, w, h, s1, t1, s2, t2, draw.colors[0], IMG_ForHandle( pic ) );
+}
+
+void R_DrawStretchPic( int x, int y, int w, int h, qhandle_t pic ) {
+ image_t *image = IMG_ForHandle( pic );
+
+ GL_StretchPic( x, y, w, h, image->sl, image->tl, image->sh, image->th,
+ draw.colors[0], image );
+}
+
+void R_DrawPic( int x, int y, qhandle_t pic ) {
+ image_t *image = IMG_ForHandle( pic );
+
+ GL_StretchPic( x, y, image->width, image->height,
+ image->sl, image->tl, image->sh, image->th, draw.colors[0], image );
+}
+
+#define DIV64 ( 1.0f / 64.0f )
+
+void R_TileClear( int x, int y, int w, int h, qhandle_t pic ) {
+ GL_StretchPic( x, y, w, h, x * DIV64, y * DIV64,
+ ( x + w ) * DIV64, ( y + h ) * DIV64, colorWhite, IMG_ForHandle( pic ) );
+}
+
+void R_DrawFill( int x, int y, int w, int h, int c ) {
+ _GL_StretchPic( x, y, w, h, 0, 0, 1, 1, ( byte * )&d_8to24table[c & 255],
+ TEXNUM_WHITE, 0 );
+}
+
+void R_DrawFillEx( int x, int y, int w, int h, const color_t color ) {
+ _GL_StretchPic( x, y, w, h, 0, 0, 1, 1, color, TEXNUM_WHITE, 0 );
+}
+
+void R_FadeScreen( void ) {
+}
+
+static inline void draw_char( int x, int y, int c, qboolean alt, image_t *image ) {
+ float s, t;
+
+ if( ( c & 127 ) == 32 ) {
+ return;
+ }
+
+ c |= alt << 7;
+ s = ( c & 15 ) * 0.0625f;
+ t = ( c >> 4 ) * 0.0625f;
+ GL_StretchPic( x, y, 8, 8, s, t, s + 0.0625f, t + 0.0625f, draw.colors[alt], image );
+}
+
+void R_DrawChar( int x, int y, int flags, int c, qhandle_t font ) {
+ qboolean alt = ( flags & UI_ALTCOLOR ) ? qtrue : qfalse;
+ draw_char( x, y, c & 255, alt, IMG_ForHandle( font ) );
+}
+
+int R_DrawString( int x, int y, int flags, size_t maxlen, const char *s, qhandle_t font ) {
+ image_t *image = IMG_ForHandle( font );
+ qboolean alt = ( flags & UI_ALTCOLOR ) ? qtrue : qfalse;
+
+ while( maxlen-- && *s ) {
+ byte c = *s++;
+ draw_char( x, y, c, alt, image );
+ x += 8;
+ }
+
+ return x;
+}
+
+#ifdef _DEBUG
+
+image_t *r_charset;
+
+void Draw_Stringf( int x, int y, const char *fmt, ... ) {
+ va_list argptr;
+ char buffer[MAX_STRING_CHARS];
+ char *string;
+ byte c;
+ float s, t;
+
+ va_start( argptr, fmt );
+ Q_vsnprintf( buffer, sizeof( buffer ), fmt, argptr );
+ va_end( argptr );
+
+ if( !r_charset ) {
+ qhandle_t tmp;
+ tmp = R_RegisterFont( "conchars" );
+ if(!tmp) return;
+ r_charset = IMG_ForHandle( tmp );
+ }
+
+ string = buffer;
+ while( *string ) {
+ c = *string++;
+
+ s = ( c & 15 ) * 0.0625f;
+ t = ( c >> 4 ) * 0.0625f;
+
+ GL_StretchPic( x, y, 8, 8, s, t, s + 0.0625f, t + 0.0625f,
+ colorWhite, r_charset );
+ x += 8;
+ }
+}
+
+
+void Draw_Stats( void ) {
+ int x = 10, y = 10;
+
+ Draw_Stringf( x, y, "Nodes visible : %i", c.nodesVisible ); y += 10;
+ Draw_Stringf( x, y, "Nodes culled : %i", c.nodesCulled ); y += 10;
+ Draw_Stringf( x, y, "Faces drawn : %i", c.facesDrawn ); y += 10;
+ if( c.facesCulled ) {
+ Draw_Stringf( x, y, "Faces culled : %i", c.facesCulled ); y += 10;
+ }
+ if( c.boxesCulled ) {
+ Draw_Stringf( x, y, "Boxes culled : %i", c.boxesCulled ); y += 10;
+ }
+ if( c.spheresCulled ) {
+ Draw_Stringf( x, y, "Spheres culled : %i", c.spheresCulled ); y += 10;
+ }
+ if( c.rotatedBoxesCulled ) {
+ Draw_Stringf( x, y, "RtBoxes culled : %i", c.rotatedBoxesCulled ); y += 10;
+ }
+ Draw_Stringf( x, y, "Tris drawn : %i", c.trisDrawn ); y += 10;
+ Draw_Stringf( x, y, "Tex switches : %i", c.texSwitches ); y += 10;
+ if( c.batchesDrawn ) {
+ Draw_Stringf( x, y, "Batches drawn: %i", c.batchesDrawn ); y += 10;
+ Draw_Stringf( x, y, "Faces / batch: %i", c.facesDrawn / c.batchesDrawn );
+ y += 10;
+ Draw_Stringf( x, y, "Tris / batch : %i", c.trisDrawn / c.batchesDrawn );
+ y += 10;
+ }
+}
+
+#endif