]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/grgl1render.cpp
use LEGACY_GL to determine of GL1 is used or not
[taylor/freespace2.git] / src / graphics / grgl1render.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
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
6  * the source.
7  */
8
9 #ifdef LEGACY_GL
10
11 #include "SDL_opengl.h"
12
13 #include "pstypes.h"
14 #include "2d.h"
15 #include "gropengl.h"
16 #include "gropenglinternal.h"
17 #include "grgl1.h"
18 #include "bmpman.h"
19 #include "grinternal.h"
20 #include "3d.h"
21 #include "neb.h"
22 #include "line.h"
23 #include "palman.h"
24
25
26 #define NEBULA_COLORS 20
27
28
29 static void opengl1_rect_internal(int x, int y, int w, int h, int r, int g, int b, int a)
30 {
31         int saved_zbuf = gr_zbuffer_get();
32
33         // no zbuffering, no culling
34         gr_zbuffer_set(GR_ZBUFF_NONE);
35         gr_opengl_set_cull(0);
36
37         opengl1_set_state(TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE);
38
39         opengl_alloc_render_buffer(4);
40
41         render_buffer[0].x = i2fl(x);
42         render_buffer[0].y = i2fl(y);
43
44         render_buffer[1].x = i2fl(x);
45         render_buffer[1].y = i2fl(y + h);
46
47         render_buffer[2].x = i2fl(x + w);
48         render_buffer[2].y = i2fl(y);
49
50         render_buffer[3].x = i2fl(x + w);
51         render_buffer[3].y = i2fl(y + h);
52
53         r = Gr_gamma_lookup[r];
54         g = Gr_gamma_lookup[g];
55         b = Gr_gamma_lookup[b];
56
57         glColor4ub((ubyte)r, (ubyte)g, (ubyte)b, (ubyte)a);
58
59         glEnableClientState(GL_VERTEX_ARRAY);
60
61         glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
62
63         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
64
65         glDisableClientState(GL_VERTEX_ARRAY);
66
67         // restore zbuffer and culling
68         gr_zbuffer_set(saved_zbuf);
69         gr_opengl_set_cull(1);
70 }
71
72 static void opengl1_aabitmap_ex_internal(int x,int y,int w,int h,int sx,int sy)
73 {
74         if ( (w < 1) || (h < 1) ) {
75                 return;
76         }
77
78         if ( !gr_screen.current_color.is_alphacolor ) {
79                 return;
80         }
81
82         float u_scale, v_scale;
83
84         if ( !opengl1_tcache_set(gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP,
85                         &u_scale, &v_scale, 0, -1, -1, 0) )
86         {
87                 // Couldn't set texture
88                 mprintf(( "WARNING: Error setting aabitmap texture!\n" ));
89                 return;
90         }
91
92         opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
93
94         float u0, u1, v0, v1;
95         float x1, x2, y1, y2;
96         int bw, bh;
97
98         bm_get_info( gr_screen.current_bitmap, &bw, &bh );
99
100         u0 = u_scale*i2fl(sx)/i2fl(bw);
101         v0 = v_scale*i2fl(sy)/i2fl(bh);
102
103         u1 = u_scale*i2fl(sx+w)/i2fl(bw);
104         v1 = v_scale*i2fl(sy+h)/i2fl(bh);
105
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);
110
111         glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
112                         gr_screen.current_color.blue,gr_screen.current_color.alpha);
113
114         opengl_alloc_render_buffer(4);
115
116         render_buffer[0].x = x1;
117         render_buffer[0].y = y1;
118         render_buffer[0].u = u0;
119         render_buffer[0].v = v0;
120
121         render_buffer[1].x = x1;
122         render_buffer[1].y = y2;
123         render_buffer[1].u = u0;
124         render_buffer[1].v = v1;
125
126         render_buffer[2].x = x2;
127         render_buffer[2].y = y1;
128         render_buffer[2].u = u1;
129         render_buffer[2].v = v0;
130
131         render_buffer[3].x = x2;
132         render_buffer[3].y = y2;
133         render_buffer[3].u = u1;
134         render_buffer[3].v = v1;
135
136         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
137         glEnableClientState(GL_VERTEX_ARRAY);
138
139         glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
140         glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
141
142         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
143
144         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
145         glDisableClientState(GL_VERTEX_ARRAY);
146 }
147
148 static void opengl1_tmapper_internal( int nv, vertex ** verts, uint flags, int is_scaler )
149 {
150         int i;
151         float u_scale = 1.0f, v_scale = 1.0f;
152
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;
156
157         if (Gr_zbuffering) {
158                 if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) {
159                         zbuffer_type = ZBUFFER_TYPE_READ;
160                 } else {
161                         zbuffer_type = ZBUFFER_TYPE_FULL;
162                 }
163         }
164
165         int tmap_type = TCACHE_TYPE_NORMAL;
166
167         ubyte r = 255, g = 255, b = 255, a = 255;
168
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;
173         }
174
175         if (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) {
176                 alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE;
177
178                 // Blend with screen pixel using src*alpha+dst
179
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);
184                 }
185         }
186
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;
193         }
194
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) )
198                 {
199                         mprintf(( "Not rendering a texture because it didn't fit in VRAM!\n" ));
200                         return;
201                 }
202
203                 // use non-filtered textures for bitmap sections and UI graphics
204                 switch (tmap_type) {
205                         case TCACHE_TYPE_BITMAP_INTERFACE:
206                         case TCACHE_TYPE_BITMAP_SECTION:
207                                 texture_source = TEXTURE_SOURCE_NO_FILTERING;
208                                 break;
209
210                         default:
211                                 texture_source = TEXTURE_SOURCE_DECAL;
212                                 break;
213                 }
214         }
215
216
217         opengl1_set_state( texture_source, alpha_blend, zbuffer_type );
218
219         float ox = gr_screen.offset_x * 16.0f;
220         float oy = gr_screen.offset_y * 16.0f;
221
222         if (flags & TMAP_FLAG_PIXEL_FOG) {
223                 int fr, fg, fb;
224                 int ra, ga, ba;
225                 float sx, sy;
226
227                 ra = ga = ba = 0;
228
229                 for (i = nv-1; i >= 0; i--) {
230                         vertex * va = verts[i];
231
232                         sx = (va->sx * 16.0f + ox) / 16.0f;
233                         sy = (va->sy * 16.0f + oy) / 16.0f;
234
235                         neb2_get_pixel((int)sx, (int)sy, &fr, &fg, &fb);
236
237                         ra += fr;
238                         ga += fg;
239                         ba += fb;
240                 }
241
242                 ra /= nv;
243                 ga /= nv;
244                 ba /= nv;
245
246                 gr_opengl1_fog_set(GR_FOGMODE_FOG, ra, ga, ba, -1.0f, -1.0f);
247         }
248
249         opengl_alloc_render_buffer(nv);
250
251         int rb_offset = 0;
252
253         float sx, sy, sz = 0.99f, rhw = 1.0f;
254
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);
262
263         for (i = nv-1; i >= 0; i--) {
264                 vertex *va = verts[i];
265
266                 if (bZval) {
267                         sz = 1.0f - 1.0f / (1.0f + va->z / (32768.0f / 256.0f));
268
269                         if ( sz > 0.98f ) {
270                                 sz = 0.98f;
271                         }
272                 }
273
274                 if (bCorrect) {
275                         rhw = 1.0f / va->sw;
276                 }
277
278                 if (bAlpha) {
279                         a = va->a;
280                 }
281
282                 if (bRGB) {
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];
292                 } else if (bRamp) {
293                         r = g = b = (ubyte)Gr_gamma_lookup[va->b];
294                 }
295
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;
300
301                 sx = (va->sx * 16.0f + ox) / 16.0f;
302                 sy = (va->sy * 16.0f + oy) / 16.0f;
303
304                 if (bTextured) {
305                         render_buffer[rb_offset].u = va->u * u_scale;
306                         render_buffer[rb_offset].v = va->v * v_scale;
307                 }
308
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;
313
314                 ++rb_offset;
315         }
316
317         if (flags & TMAP_FLAG_TEXTURED) {
318                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
319                 glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
320         }
321
322         glEnableClientState(GL_COLOR_ARRAY);
323         glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r);
324
325         glEnableClientState(GL_VERTEX_ARRAY);
326         glVertexPointer(4, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
327
328         glDrawArrays(GL_TRIANGLE_FAN, 0, rb_offset);
329
330         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
331         glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
332         glDisableClientState(GL_COLOR_ARRAY);
333         glDisableClientState(GL_VERTEX_ARRAY);
334 }
335
336 void gr_opengl1_rect(int x,int y,int w,int h)
337 {
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);
341 }
342
343 void gr_opengl1_shade(int x,int y,int w,int h)
344 {
345         int r,g,b,a;
346
347         float shade1 = 1.0f;
348         float shade2 = 6.0f;
349
350         r = fl2i(gr_screen.current_shader.r*255.0f*shade1);
351         CAP(r, 0, 255);
352         g = fl2i(gr_screen.current_shader.g*255.0f*shade1);
353         CAP(g, 0, 255);
354         b = fl2i(gr_screen.current_shader.b*255.0f*shade1);
355         CAP(b, 0, 255);
356         a = fl2i(gr_screen.current_shader.c*255.0f*shade2);
357         CAP(a, 0, 255);
358
359         opengl1_rect_internal(x, y, w, h, r, g, b, a);
360 }
361
362 void gr_opengl1_aabitmap_ex(int x,int y,int w,int h,int sx,int sy)
363 {
364         if ( (x > gr_screen.clip_right ) || ((x+w-1) < gr_screen.clip_left) )
365                 return;
366
367         if ( (y > gr_screen.clip_bottom ) || ((y+h-1) < gr_screen.clip_top) )
368                 return;
369
370         opengl1_aabitmap_ex_internal(x, y, w, h, sx, sy);
371 }
372
373 void gr_opengl1_aabitmap(int x, int y)
374 {
375         int w, h;
376
377         bm_get_info( gr_screen.current_bitmap, &w, &h, NULL );
378
379         gr_opengl1_aabitmap_ex(x, y, w, h, 0, 0);
380 }
381
382 void gr_opengl1_string( int sx, int sy, const char *s )
383 {
384         int width, spacing, letter;
385         int x, y;
386         int rb_offset;
387         float u_scale, v_scale;
388         float u0, u1, v0, v1;
389         float x1, x2, y1, y2;
390         int bw, bh;
391         float fbw, fbh;
392
393         if ( !Current_font )    {
394                 return;
395         }
396
397         gr_set_bitmap(Current_font->bitmap_id, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
398
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" ));
402                 return;
403         }
404
405         bm_get_info( gr_screen.current_bitmap, &bw, &bh );
406
407         fbw = 1.0f / i2fl(bw);
408         fbh = 1.0f / i2fl(bh);
409
410         opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
411
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);
415
416         glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
417                         gr_screen.current_color.blue, gr_screen.current_color.alpha);
418
419         glEnableClientState(GL_VERTEX_ARRAY);
420         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
421
422         glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
423         glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u);
424
425         y = sy;
426
427         if (sx==0x8000) {                       //centered
428                 x = get_centered_x(s);
429         } else {
430                 x = sx;
431         }
432
433         spacing = 0;
434         rb_offset = 0;
435
436         while (*s)      {
437                 x += spacing;
438
439                 while (*s== '\n' )      {
440                         s++;
441                         y += Current_font->h;
442                         if (sx==0x8000) {                       //centered
443                                 x = get_centered_x(s);
444                         } else {
445                                 x = sx;
446                         }
447                 }
448                 if (*s == 0 ) break;
449
450                 letter = get_char_width(s[0],s[1],&width,&spacing);
451                 s++;
452
453                 //not in font, draw as space
454                 if (letter<0)   {
455                         continue;
456                 }
457
458                 int xd, yd, xc, yc;
459                 int wc, hc;
460
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;
466
467                 xd = yd = 0;
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;
470                 xc = x+xd;
471                 yc = y+yd;
472
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;
476
477                 if ( wc < 1 ) continue;
478                 if ( hc < 1 ) continue;
479
480                 float u = i2fl(Current_font->bm_u[letter] + xd);
481                 float v = i2fl(Current_font->bm_v[letter] + yd);
482
483                 x1 = i2fl(xc + gr_screen.offset_x);
484                 y1 = i2fl(yc + gr_screen.offset_y);
485                 x2 = x1 + i2fl(wc);
486                 y2 = y1 + i2fl(hc);
487
488                 u0 = u_scale * (u * fbw);
489                 v0 = v_scale * (v * fbh);
490
491                 u1 = u_scale * ((u+i2fl(wc)) * fbw);
492                 v1 = v_scale * ((v+i2fl(hc)) * fbh);
493
494                 // maybe go ahead and draw
495                 if (rb_offset == alocsize) {
496                         glDrawArrays(GL_TRIANGLE_STRIP, 0, rb_offset);
497                         rb_offset = 0;
498                 }
499
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;
504                 ++rb_offset;
505
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;
510                 ++rb_offset;
511
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;
516                 ++rb_offset;
517
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;
522                 ++rb_offset;
523         }
524
525         if (rb_offset) {
526                 glDrawArrays(GL_TRIANGLE_STRIP, 0, rb_offset);
527         }
528
529         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
530         glDisableClientState(GL_VERTEX_ARRAY);
531 }
532
533 void gr_opengl1_line(int x1,int y1,int x2,int y2)
534 {
535         opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
536
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());
539
540         float sx1, sy1;
541         float sx2, sy2;
542
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;
547
548         opengl_alloc_render_buffer(2);
549
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;
554
555                 glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
556                                 gr_screen.current_color.blue, gr_screen.current_color.alpha);
557
558                 glEnableClientState(GL_VERTEX_ARRAY);
559                 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
560
561                 glDrawArrays(GL_POINTS, 0, 1);
562
563                 glDisableClientState(GL_VERTEX_ARRAY);
564
565                 return;
566         }
567
568         if ( x1 == x2 ) {
569                 if ( sy1 < sy2 )    {
570                         sy2 += 0.5f;
571                 } else {
572                         sy1 += 0.5f;
573                 }
574         } else if ( y1 == y2 )  {
575                 if ( sx1 < sx2 )    {
576                         sx2 += 0.5f;
577                 } else {
578                         sx1 += 0.5f;
579                 }
580         }
581
582         render_buffer[0].x = sx2;
583         render_buffer[0].y = sy2;
584         render_buffer[0].z = -0.99f;
585
586         render_buffer[1].x = sx1;
587         render_buffer[1].y = sy1;
588         render_buffer[1].z = -0.99f;
589
590         glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green,
591                         gr_screen.current_color.blue, gr_screen.current_color.alpha);
592
593         glEnableClientState(GL_VERTEX_ARRAY);
594         glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
595
596         glDrawArrays(GL_LINES, 0, 2);
597
598         glDisableClientState(GL_VERTEX_ARRAY);
599 }
600
601 void gr_opengl1_aaline(vertex *v1, vertex *v2)
602 {
603         gr_opengl1_line( fl2i(v1->sx), fl2i(v1->sy), fl2i(v2->sx), fl2i(v2->sy) );
604 }
605
606 void gr_opengl1_gradient(int x1,int y1,int x2,int y2)
607 {
608         int swapped=0;
609
610         if ( !gr_screen.current_color.is_alphacolor )   {
611                 gr_line( x1, y1, x2, y2 );
612                 return;
613         }
614
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);
617
618         opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE );
619
620         int aa = swapped ? 0 : gr_screen.current_color.alpha;
621         int ba = swapped ? gr_screen.current_color.alpha : 0;
622
623         float sx1, sy1;
624         float sx2, sy2;
625
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;
630
631         if ( x1 == x2 ) {
632                 if ( sy1 < sy2 )    {
633                         sy2 += 0.5f;
634                 } else {
635                         sy1 += 0.5f;
636                 }
637         } else if ( y1 == y2 )  {
638                 if ( sx1 < sx2 )    {
639                         sx2 += 0.5f;
640                 } else {
641                         sx1 += 0.5f;
642                 }
643         }
644
645         opengl_alloc_render_buffer(2);
646
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;
654
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;
662
663         glEnableClientState(GL_COLOR_ARRAY);
664         glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r);
665
666         glEnableClientState(GL_VERTEX_ARRAY);
667         glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
668
669         glDrawArrays(GL_LINES, 0, 2);
670
671         glDisableClientState(GL_COLOR_ARRAY);
672         glDisableClientState(GL_VERTEX_ARRAY);
673 }
674
675 void gr_opengl1_circle( int xc, int yc, int d )
676 {
677         int p,x, y, r;
678
679         r = d/2;
680         p=3-d;
681         x=0;
682         y=r;
683
684         // Big clip
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;
689
690         while(x<y)      {
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 );
694
695                 if (p<0)
696                         p=p+(x<<2)+6;
697                 else    {
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 );
701
702                         p=p+((x-y)<<2)+10;
703                         y--;
704                 }
705                 x++;
706         }
707         if(x==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 );
710         }
711         return;
712 }
713
714 void gr_opengl1_pixel(int x, int y)
715 {
716         gr_opengl1_line(x, y, x, y);
717 }
718
719
720 // cross fade
721 void gr_opengl1_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct)
722 {
723         gr_set_bitmap(bmap1, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f - pct );
724         gr_bitmap(x1, y1);
725
726         gr_set_bitmap(bmap2, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, pct );
727         gr_bitmap(x2, y2);
728 }
729
730 void gr_opengl1_flash(int r, int g, int b)
731 {
732         CAP(r,0,255);
733         CAP(g,0,255);
734         CAP(b,0,255);
735
736         if ( r || g || b ) {
737                 opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE );
738
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);
744
745                 glColor4ub((GLubyte)r, (GLubyte)g, (GLubyte)b, 255);
746
747                 opengl_alloc_render_buffer(4);
748
749                 render_buffer[0].x = x1;
750                 render_buffer[0].y = y1;
751                 render_buffer[0].z = -0.99f;
752
753                 render_buffer[1].x = x1;
754                 render_buffer[1].y = y2;
755                 render_buffer[1].z = -0.99f;
756
757                 render_buffer[2].x = x2;
758                 render_buffer[2].y = y1;
759                 render_buffer[2].z = -0.99f;
760
761                 render_buffer[3].x = x2;
762                 render_buffer[3].y = y2;
763                 render_buffer[3].z = -0.99f;
764
765                 glEnableClientState(GL_VERTEX_ARRAY);
766                 glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x);
767
768                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
769
770                 glDisableClientState(GL_VERTEX_ARRAY);
771         }
772 }
773
774 void gr_opengl1_tmapper( int nverts, vertex **verts, uint flags )
775 {
776         opengl1_tmapper_internal( nverts, verts, flags, 0 );
777 }
778
779 #define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0))
780
781 void gr_opengl1_scaler(vertex *va, vertex *vb )
782 {
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;
789
790         //============= CLIP IT =====================
791
792         x0 = va->sx; y0 = va->sy;
793         x1 = vb->sx; y1 = vb->sy;
794
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);
797
798         u0 = va->u; v0 = va->v;
799         u1 = vb->u; v1 = vb->v;
800
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;
805
806         clipped_u0 = u0; clipped_v0 = v0;
807         clipped_u1 = u1; clipped_v1 = v1;
808
809         clipped_x0 = x0; clipped_y0 = y0;
810         clipped_x1 = x1; clipped_y1 = y1;
811
812         // Clip the left, moving u0 right as necessary
813         if ( x0 < xmin )        {
814                 clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1);
815                 clipped_x0 = xmin;
816         }
817
818         // Clip the right, moving u1 left as necessary
819         if ( x1 > xmax )        {
820                 clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1);
821                 clipped_x1 = xmax;
822         }
823
824         // Clip the top, moving v0 down as necessary
825         if ( y0 < ymin )        {
826                 clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1);
827                 clipped_y0 = ymin;
828         }
829
830         // Clip the bottom, moving v1 up as necessary
831         if ( y1 > ymax )        {
832                 clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1);
833                 clipped_y1 = ymax;
834         }
835
836         dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1);
837         dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1);
838
839         if (dx1<=dx0) return;
840         if (dy1<=dy0) return;
841
842         //============= DRAW IT =====================
843
844         vertex v[4];
845         vertex *vl[4];
846
847         vl[0] = &v[0];
848         v[0].sx = clipped_x0;
849         v[0].sy = clipped_y0;
850         v[0].sw = va->sw;
851         v[0].z = va->z;
852         v[0].u = clipped_u0;
853         v[0].v = clipped_v0;
854
855         vl[1] = &v[1];
856         v[1].sx = clipped_x1;
857         v[1].sy = clipped_y0;
858         v[1].sw = va->sw;
859         v[1].z = va->z;
860         v[1].u = clipped_u1;
861         v[1].v = clipped_v0;
862
863         vl[2] = &v[2];
864         v[2].sx = clipped_x1;
865         v[2].sy = clipped_y1;
866         v[2].sw = va->sw;
867         v[2].z = va->z;
868         v[2].u = clipped_u1;
869         v[2].v = clipped_v1;
870
871         vl[3] = &v[3];
872         v[3].sx = clipped_x0;
873         v[3].sy = clipped_y1;
874         v[3].sw = va->sw;
875         v[3].z = va->z;
876         v[3].u = clipped_u0;
877         v[3].v = clipped_v1;
878
879         opengl1_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 );
880 }
881
882 #endif