2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
11 #include "SDL_opengl.h"
16 #include "gropenglinternal.h"
19 #include "grinternal.h"
26 #define NEBULA_COLORS 20
29 static void opengl1_rect_internal(int x, int y, int w, int h, int r, int g, int b, int a)
31 int saved_zbuf = gr_zbuffer_get();
33 // no zbuffering, no culling
34 gr_zbuffer_set(GR_ZBUFF_NONE);
35 gr_opengl_set_cull(0);
37 opengl1_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE);
39 opengl_alloc_render_buffer(4);
41 render_buffer[0].x = i2fl(x);
42 render_buffer[0].y = i2fl(y);
44 render_buffer[1].x = i2fl(x);
45 render_buffer[1].y = i2fl(y + h);
47 render_buffer[2].x = i2fl(x + w);
48 render_buffer[2].y = i2fl(y);
50 render_buffer[3].x = i2fl(x + w);
51 render_buffer[3].y = i2fl(y + h);
53 r = Gr_gamma_lookup[r];
54 g = Gr_gamma_lookup[g];
55 b = Gr_gamma_lookup[b];
57 glColor4ub((ubyte)r, (ubyte)g, (ubyte)b, (ubyte)a);
59 glEnableClientState(GL_VERTEX_ARRAY);
61 glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
63 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
65 glDisableClientState(GL_VERTEX_ARRAY);
67 // restore zbuffer and culling
68 gr_zbuffer_set(saved_zbuf);
69 gr_opengl_set_cull(1);
72 static void opengl1_aabitmap_ex_internal(int x,int y,int w,int h,int sx,int sy)
74 if ( (w < 1) || (h < 1) ) {
78 if ( !gr_screen.current_color.is_alphacolor ) {
82 float u_scale, v_scale;
84 if ( !opengl1_tcache_set(gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP,
85 &u_scale, &v_scale, 0, -1, -1, 0) )
87 // Couldn't set texture
88 mprintf(( "WARNING: Error setting aabitmap texture!\n" ));
92 opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
98 bm_get_info( gr_screen.current_bitmap, &bw, &bh );
100 u0 = u_scale*i2fl(sx)/i2fl(bw);
101 v0 = v_scale*i2fl(sy)/i2fl(bh);
103 u1 = u_scale*i2fl(sx+w)/i2fl(bw);
104 v1 = v_scale*i2fl(sy+h)/i2fl(bh);
106 x1 = i2fl(x+gr_screen.offset_x);
107 y1 = i2fl(y+gr_screen.offset_y);
108 x2 = i2fl(x+w+gr_screen.offset_x);
109 y2 = i2fl(y+h+gr_screen.offset_y);
111 glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
112 gr_screen.current_color.blue,gr_screen.current_color.alpha);
114 opengl_alloc_render_buffer(4);
116 render_buffer[0].x = x1;
117 render_buffer[0].y = y1;
118 render_buffer[0].u = u0;
119 render_buffer[0].v = v0;
121 render_buffer[1].x = x1;
122 render_buffer[1].y = y2;
123 render_buffer[1].u = u0;
124 render_buffer[1].v = v1;
126 render_buffer[2].x = x2;
127 render_buffer[2].y = y1;
128 render_buffer[2].u = u1;
129 render_buffer[2].v = v0;
131 render_buffer[3].x = x2;
132 render_buffer[3].y = y2;
133 render_buffer[3].u = u1;
134 render_buffer[3].v = v1;
136 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
137 glEnableClientState(GL_VERTEX_ARRAY);
139 glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
140 glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
142 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
144 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
145 glDisableClientState(GL_VERTEX_ARRAY);
148 static void opengl1_tmapper_internal( int nv, vertex ** verts, uint flags, int is_scaler )
151 float u_scale = 1.0f, v_scale = 1.0f;
153 gr_texture_source texture_source = TEXTURE_SOURCE_NONE;
154 gr_alpha_blend alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA;
155 gr_zbuffer_type zbuffer_type = ZBUFFER_TYPE_NONE;
158 if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) {
159 zbuffer_type = ZBUFFER_TYPE_READ;
161 zbuffer_type = ZBUFFER_TYPE_FULL;
165 int tmap_type = TCACHE_TYPE_NORMAL;
167 ubyte r = 255, g = 255, b = 255, a = 255;
169 if ( !(flags & TMAP_FLAG_TEXTURED) ) {
170 r = gr_screen.current_color.red;
171 g = gr_screen.current_color.green;
172 b = gr_screen.current_color.blue;
175 if (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) {
176 alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE;
178 // Blend with screen pixel using src*alpha+dst
180 if (gr_screen.current_alpha < 1.0f) {
181 r = ubyte((r * gr_screen.current_alpha) + 0.5f);
182 g = ubyte((g * gr_screen.current_alpha) + 0.5f);
183 b = ubyte((b * gr_screen.current_alpha) + 0.5f);
187 if (flags & TMAP_FLAG_BITMAP_SECTION) {
188 SDL_assert( !(flags & TMAP_FLAG_BITMAP_INTERFACE) );
189 tmap_type = TCACHE_TYPE_BITMAP_SECTION;
190 } else if (flags & TMAP_FLAG_BITMAP_INTERFACE) {
191 SDL_assert( !(flags & TMAP_FLAG_BITMAP_SECTION) );
192 tmap_type = TCACHE_TYPE_BITMAP_INTERFACE;
195 if (flags & TMAP_FLAG_TEXTURED) {
196 if ( !opengl1_tcache_set(gr_screen.current_bitmap, tmap_type, &u_scale,
197 &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0) )
199 mprintf(( "Not rendering a texture because it didn't fit in VRAM!\n" ));
203 // use non-filtered textures for bitmap sections and UI graphics
205 case TCACHE_TYPE_BITMAP_INTERFACE:
206 case TCACHE_TYPE_BITMAP_SECTION:
207 texture_source = TEXTURE_SOURCE_NO_FILTERING;
211 texture_source = TEXTURE_SOURCE_DECAL;
217 opengl1_set_state( texture_source, alpha_blend, zbuffer_type );
219 float ox = gr_screen.offset_x * 16.0f;
220 float oy = gr_screen.offset_y * 16.0f;
222 if (flags & TMAP_FLAG_PIXEL_FOG) {
229 for (i = nv-1; i >= 0; i--) {
230 vertex * va = verts[i];
232 sx = (va->sx * 16.0f + ox) / 16.0f;
233 sy = (va->sy * 16.0f + oy) / 16.0f;
235 neb2_get_pixel((int)sx, (int)sy, &fr, &fg, &fb);
246 gr_opengl1_fog_set(GR_FOGMODE_FOG, ra, ga, ba, -1.0f, -1.0f);
249 opengl_alloc_render_buffer(nv);
253 float sx, sy, sz = 0.99f, rhw = 1.0f;
255 bool bZval = (Gr_zbuffering || (flags & TMAP_FLAG_NEBULA));
256 bool bCorrect = ((flags & TMAP_FLAG_CORRECT) == TMAP_FLAG_CORRECT);
257 bool bAlpha = ((flags & TMAP_FLAG_ALPHA) == TMAP_FLAG_ALPHA);
258 bool bNebula = ((flags & TMAP_FLAG_NEBULA) == TMAP_FLAG_NEBULA);
259 bool bRamp = ((flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD));
260 bool bRGB = ((flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD));
261 bool bTextured = ((flags & TMAP_FLAG_TEXTURED) == TMAP_FLAG_TEXTURED);
263 for (i = nv-1; i >= 0; i--) {
264 vertex *va = verts[i];
267 sz = 1.0f - 1.0f / (1.0f + va->z / (32768.0f / 256.0f));
283 // Make 0.75 be 256.0f
284 r = (ubyte)Gr_gamma_lookup[va->r];
285 g = (ubyte)Gr_gamma_lookup[va->g];
286 b = (ubyte)Gr_gamma_lookup[va->b];
287 } else if (bNebula) {
288 int pal = (va->b*(NEBULA_COLORS-1))/255;
289 r = gr_palette[pal*3+0];
290 g = gr_palette[pal*3+1];
291 b = gr_palette[pal*3+2];
293 r = g = b = (ubyte)Gr_gamma_lookup[va->b];
296 render_buffer[rb_offset].r = r;
297 render_buffer[rb_offset].g = g;
298 render_buffer[rb_offset].b = b;
299 render_buffer[rb_offset].a = a;
301 sx = (va->sx * 16.0f + ox) / 16.0f;
302 sy = (va->sy * 16.0f + oy) / 16.0f;
305 render_buffer[rb_offset].u = va->u * u_scale;
306 render_buffer[rb_offset].v = va->v * v_scale;
309 render_buffer[rb_offset].x = sx * rhw;
310 render_buffer[rb_offset].y = sy * rhw;
311 render_buffer[rb_offset].z = -sz * rhw;
312 render_buffer[rb_offset].w = rhw;
317 if (flags & TMAP_FLAG_TEXTURED) {
318 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
319 glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
322 glEnableClientState(GL_COLOR_ARRAY);
323 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r);
325 glEnableClientState(GL_VERTEX_ARRAY);
326 glVertexPointer(4, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
328 glDrawArrays(GL_TRIANGLE_FAN, 0, rb_offset);
330 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
331 glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
332 glDisableClientState(GL_COLOR_ARRAY);
333 glDisableClientState(GL_VERTEX_ARRAY);
336 void gr_opengl1_rect(int x,int y,int w,int h)
338 opengl1_rect_internal(x, y, w, h, gr_screen.current_color.red,
339 gr_screen.current_color.green, gr_screen.current_color.blue,
340 gr_screen.current_color.alpha);
343 void gr_opengl1_shade(int x,int y,int w,int h)
350 r = fl2i(gr_screen.current_shader.r*255.0f*shade1);
352 g = fl2i(gr_screen.current_shader.g*255.0f*shade1);
354 b = fl2i(gr_screen.current_shader.b*255.0f*shade1);
356 a = fl2i(gr_screen.current_shader.c*255.0f*shade2);
359 opengl1_rect_internal(x, y, w, h, r, g, b, a);
362 void gr_opengl1_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
364 if ( (x > gr_screen.clip_right ) || ((x+w-1) < gr_screen.clip_left) )
367 if ( (y > gr_screen.clip_bottom ) || ((y+h-1) < gr_screen.clip_top) )
370 opengl1_aabitmap_ex_internal(x, y, w, h, sx, sy);
373 void gr_opengl1_aabitmap(int x, int y)
377 bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
379 gr_opengl1_aabitmap_ex(x, y, w, h, 0, 0);
382 void gr_opengl1_string( int sx, int sy, const char *s )
384 int width, spacing, letter;
387 float u_scale, v_scale;
388 float u0, u1, v0, v1;
389 float x1, x2, y1, y2;
393 if ( !Current_font ) {
397 gr_set_bitmap(Current_font->bitmap_id, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
399 if ( !opengl1_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale, 0, -1, -1, 0 ) ) {
400 // Couldn't set texture
401 mprintf(( "WARNING: Error setting aabitmap texture!\n" ));
405 bm_get_info( gr_screen.current_bitmap, &bw, &bh );
407 fbw = 1.0f / i2fl(bw);
408 fbh = 1.0f / i2fl(bh);
410 opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
412 // don't want to create a super huge buffer size (i.e. credits text)
413 const int alocsize = 320; // 80 characters max per render call
414 opengl_alloc_render_buffer(alocsize);
416 glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
417 gr_screen.current_color.blue, gr_screen.current_color.alpha);
419 glEnableClientState(GL_VERTEX_ARRAY);
420 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
422 glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
423 glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
427 if (sx==0x8000) { //centered
428 x = get_centered_x(s);
441 y += Current_font->h;
442 if (sx==0x8000) { //centered
443 x = get_centered_x(s);
450 letter = get_char_width(s[0],s[1],&width,&spacing);
453 //not in font, draw as space
461 // Check if this character is totally clipped
462 if ( x + width < gr_screen.clip_left ) continue;
463 if ( y + Current_font->h < gr_screen.clip_top ) continue;
464 if ( x > gr_screen.clip_right ) continue;
465 if ( y > gr_screen.clip_bottom ) continue;
468 if ( x < gr_screen.clip_left ) xd = gr_screen.clip_left - x;
469 if ( y < gr_screen.clip_top ) yd = gr_screen.clip_top - y;
473 wc = width - xd; hc = Current_font->h - yd;
474 if ( xc + wc > gr_screen.clip_right ) wc = gr_screen.clip_right - xc;
475 if ( yc + hc > gr_screen.clip_bottom ) hc = gr_screen.clip_bottom - yc;
477 if ( wc < 1 ) continue;
478 if ( hc < 1 ) continue;
480 float u = i2fl(Current_font->bm_u[letter] + xd);
481 float v = i2fl(Current_font->bm_v[letter] + yd);
483 x1 = i2fl(xc + gr_screen.offset_x);
484 y1 = i2fl(yc + gr_screen.offset_y);
488 u0 = u_scale * (u * fbw);
489 v0 = v_scale * (v * fbh);
491 u1 = u_scale * ((u+i2fl(wc)) * fbw);
492 v1 = v_scale * ((v+i2fl(hc)) * fbh);
494 // maybe go ahead and draw
495 if (rb_offset == alocsize) {
496 glDrawArrays(GL_TRIANGLE_STRIP, 0, rb_offset);
500 render_buffer[rb_offset].x = x1;
501 render_buffer[rb_offset].y = y1;
502 render_buffer[rb_offset].u = u0;
503 render_buffer[rb_offset].v = v0;
506 render_buffer[rb_offset].x = x1;
507 render_buffer[rb_offset].y = y2;
508 render_buffer[rb_offset].u = u0;
509 render_buffer[rb_offset].v = v1;
512 render_buffer[rb_offset].x = x2;
513 render_buffer[rb_offset].y = y1;
514 render_buffer[rb_offset].u = u1;
515 render_buffer[rb_offset].v = v0;
518 render_buffer[rb_offset].x = x2;
519 render_buffer[rb_offset].y = y2;
520 render_buffer[rb_offset].u = u1;
521 render_buffer[rb_offset].v = v1;
526 glDrawArrays(GL_TRIANGLE_STRIP, 0, rb_offset);
529 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
530 glDisableClientState(GL_VERTEX_ARRAY);
533 void gr_opengl1_line(int x1,int y1,int x2,int y2)
535 opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
537 INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,
538 gr_screen.clip_right,gr_screen.clip_bottom,return,void(),void());
543 sx1 = i2fl(x1 + gr_screen.offset_x)+0.5f;
544 sy1 = i2fl(y1 + gr_screen.offset_y)+0.5f;
545 sx2 = i2fl(x2 + gr_screen.offset_x)+0.5f;
546 sy2 = i2fl(y2 + gr_screen.offset_y)+0.5f;
548 opengl_alloc_render_buffer(2);
550 if ( x1 == x2 && y1 == y2 ) {
551 render_buffer[0].x = sx1;
552 render_buffer[0].y = sy1;
553 render_buffer[0].z = -0.99f;
555 glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
556 gr_screen.current_color.blue, gr_screen.current_color.alpha);
558 glEnableClientState(GL_VERTEX_ARRAY);
559 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
561 glDrawArrays(GL_POINTS, 0, 1);
563 glDisableClientState(GL_VERTEX_ARRAY);
574 } else if ( y1 == y2 ) {
582 render_buffer[0].x = sx2;
583 render_buffer[0].y = sy2;
584 render_buffer[0].z = -0.99f;
586 render_buffer[1].x = sx1;
587 render_buffer[1].y = sy1;
588 render_buffer[1].z = -0.99f;
590 glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
591 gr_screen.current_color.blue, gr_screen.current_color.alpha);
593 glEnableClientState(GL_VERTEX_ARRAY);
594 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
596 glDrawArrays(GL_LINES, 0, 2);
598 glDisableClientState(GL_VERTEX_ARRAY);
601 void gr_opengl1_aaline(vertex *v1, vertex *v2)
603 gr_opengl1_line( fl2i(v1->sx), fl2i(v1->sy), fl2i(v2->sx), fl2i(v2->sy) );
606 void gr_opengl1_gradient(int x1,int y1,int x2,int y2)
610 if ( !gr_screen.current_color.is_alphacolor ) {
611 gr_line( x1, y1, x2, y2 );
615 INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,
616 gr_screen.clip_right,gr_screen.clip_bottom,return,void(),swapped=1);
618 opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
620 int aa = swapped ? 0 : gr_screen.current_color.alpha;
621 int ba = swapped ? gr_screen.current_color.alpha : 0;
626 sx1 = i2fl(x1 + gr_screen.offset_x)+0.5f;
627 sy1 = i2fl(y1 + gr_screen.offset_y)+0.5f;
628 sx2 = i2fl(x2 + gr_screen.offset_x)+0.5f;
629 sy2 = i2fl(y2 + gr_screen.offset_y)+0.5f;
637 } else if ( y1 == y2 ) {
645 opengl_alloc_render_buffer(2);
647 render_buffer[0].r = gr_screen.current_color.red;
648 render_buffer[0].g = gr_screen.current_color.green;
649 render_buffer[0].b = gr_screen.current_color.blue;
650 render_buffer[0].a = (ubyte)ba;
651 render_buffer[0].x = sx2;
652 render_buffer[0].y = sy2;
653 render_buffer[0].z = -0.99f;
655 render_buffer[1].r = gr_screen.current_color.red;
656 render_buffer[1].g = gr_screen.current_color.green;
657 render_buffer[1].b = gr_screen.current_color.blue;
658 render_buffer[1].a = (ubyte)aa;
659 render_buffer[1].x = sx1;
660 render_buffer[1].y = sy1;
661 render_buffer[1].z = -0.99f;
663 glEnableClientState(GL_COLOR_ARRAY);
664 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r);
666 glEnableClientState(GL_VERTEX_ARRAY);
667 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
669 glDrawArrays(GL_LINES, 0, 2);
671 glDisableClientState(GL_COLOR_ARRAY);
672 glDisableClientState(GL_VERTEX_ARRAY);
675 void gr_opengl1_circle( int xc, int yc, int d )
685 if ( (xc+r) < gr_screen.clip_left ) return;
686 if ( (xc-r) > gr_screen.clip_right ) return;
687 if ( (yc+r) < gr_screen.clip_top ) return;
688 if ( (yc-r) > gr_screen.clip_bottom ) return;
691 // Draw the first octant
692 gr_opengl1_line( xc-y, yc-x, xc+y, yc-x );
693 gr_opengl1_line( xc-y, yc+x, xc+y, yc+x );
698 // Draw the second octant
699 gr_opengl1_line( xc-x, yc-y, xc+x, yc-y );
700 gr_opengl1_line( xc-x, yc+y, xc+x, yc+y );
708 gr_opengl1_line( xc-x, yc-y, xc+x, yc-y );
709 gr_opengl1_line( xc-x, yc+y, xc+x, yc+y );
714 void gr_opengl1_pixel(int x, int y)
716 gr_opengl1_line(x, y, x, y);
721 void gr_opengl1_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct)
723 gr_set_bitmap(bmap1, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f - pct );
726 gr_set_bitmap(bmap2, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, pct );
730 void gr_opengl1_flash(int r, int g, int b)
737 opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE );
739 float x1, x2, y1, y2;
740 x1 = i2fl(gr_screen.clip_left+gr_screen.offset_x);
741 y1 = i2fl(gr_screen.clip_top+gr_screen.offset_y);
742 x2 = i2fl(gr_screen.clip_right+gr_screen.offset_x);
743 y2 = i2fl(gr_screen.clip_bottom+gr_screen.offset_y);
745 glColor4ub((GLubyte)r, (GLubyte)g, (GLubyte)b, 255);
747 opengl_alloc_render_buffer(4);
749 render_buffer[0].x = x1;
750 render_buffer[0].y = y1;
751 render_buffer[0].z = -0.99f;
753 render_buffer[1].x = x1;
754 render_buffer[1].y = y2;
755 render_buffer[1].z = -0.99f;
757 render_buffer[2].x = x2;
758 render_buffer[2].y = y1;
759 render_buffer[2].z = -0.99f;
761 render_buffer[3].x = x2;
762 render_buffer[3].y = y2;
763 render_buffer[3].z = -0.99f;
765 glEnableClientState(GL_VERTEX_ARRAY);
766 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
768 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
770 glDisableClientState(GL_VERTEX_ARRAY);
774 void gr_opengl1_tmapper( int nverts, vertex **verts, uint flags )
776 opengl1_tmapper_internal( nverts, verts, flags, 0 );
779 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
781 void gr_opengl1_scaler(vertex *va, vertex *vb )
783 float x0, y0, x1, y1;
784 float u0, v0, u1, v1;
785 float clipped_x0, clipped_y0, clipped_x1, clipped_y1;
786 float clipped_u0, clipped_v0, clipped_u1, clipped_v1;
787 float xmin, xmax, ymin, ymax;
788 int dx0, dy0, dx1, dy1;
790 //============= CLIP IT =====================
792 x0 = va->sx; y0 = va->sy;
793 x1 = vb->sx; y1 = vb->sy;
795 xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top);
796 xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom);
798 u0 = va->u; v0 = va->v;
799 u1 = vb->u; v1 = vb->v;
801 // Check for obviously offscreen bitmaps...
802 if ( (y1<=y0) || (x1<=x0) ) return;
803 if ( (x1<xmin ) || (x0>xmax) ) return;
804 if ( (y1<ymin ) || (y0>ymax) ) return;
806 clipped_u0 = u0; clipped_v0 = v0;
807 clipped_u1 = u1; clipped_v1 = v1;
809 clipped_x0 = x0; clipped_y0 = y0;
810 clipped_x1 = x1; clipped_y1 = y1;
812 // Clip the left, moving u0 right as necessary
814 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
818 // Clip the right, moving u1 left as necessary
820 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
824 // Clip the top, moving v0 down as necessary
826 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
830 // Clip the bottom, moving v1 up as necessary
832 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
836 dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
837 dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
839 if (dx1<=dx0) return;
840 if (dy1<=dy0) return;
842 //============= DRAW IT =====================
848 v[0].sx = clipped_x0;
849 v[0].sy = clipped_y0;
856 v[1].sx = clipped_x1;
857 v[1].sy = clipped_y0;
864 v[2].sx = clipped_x1;
865 v[2].sy = clipped_y1;
872 v[3].sx = clipped_x0;
873 v[3].sy = clipped_y1;
879 opengl1_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 );