Drop in SDL
[theoddone33/hhexen.git] / opengl / ogl_draw.c
1 //**************************************************************************
2 //**
3 //** OGL_DRAW.C
4 //**
5 //** Version:           1.0
6 //** Last Build:        -?-
7 //** Author:            jk
8 //**
9 //** OpenGL drawing functions.
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #ifdef __WIN32__
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
18 #endif
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <malloc.h>
23 #include <math.h>
24 #include <GL/gl.h>
25 #include <GL/glu.h>
26 #include "h2def.h"
27 #include "ogl_def.h"
28 #include "p_local.h"
29
30 // MACROS ------------------------------------------------------------------
31
32 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
33
34 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
35
36 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
37
38 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
39
40 // PUBLIC DATA DEFINITIONS -------------------------------------------------
41
42 // PRIVATE DATA DEFINITIONS ------------------------------------------------
43
44 static int curfilter = 0;       // The current filter (0 = none).
45
46 // CODE --------------------------------------------------------------------
47
48 void OGL_DrawRawScreen(int lump)        // Raw screens are 320 x 200.
49 {
50         float tcbottom;
51         int pixelBorder;
52         //float shift64 = 1.0/(64*screenWidth/320.0);
53         //float onePhysPixel = 320/(float)screenWidth;
54
55         glMatrixMode(GL_MODELVIEW);
56         glPushMatrix();
57         glLoadIdentity();
58         glMatrixMode(GL_PROJECTION);
59         glPushMatrix();
60         glLoadIdentity();
61         gluOrtho2D(0, screenWidth, screenHeight, 0);
62
63         OGL_SetRawImage(lump,1);
64         tcbottom = lumptexsizes[lump].h / (float)FindNextPower2(lumptexsizes[lump].h);
65         pixelBorder = lumptexsizes[lump].w * screenWidth / 320;
66
67         glColor3f(1,1,1);
68         glBegin(GL_QUADS);
69         glTexCoord2f(0,0);
70         glVertex2f(0,0);
71         glTexCoord2f(1,0);
72         glVertex2f(pixelBorder, 0);
73         glTexCoord2f(1,tcbottom);
74         glVertex2f(pixelBorder, screenHeight);
75         glTexCoord2f(0,tcbottom);
76         glVertex2f(0, screenHeight);
77         glEnd();
78
79         // And the other part.
80         OGL_SetRawImage(lump,2);
81         glBegin(GL_QUADS);
82         glTexCoord2f(0,0);
83         glVertex2f(pixelBorder-1, 0);
84         glTexCoord2f(1,0);
85         glVertex2f(screenWidth, 0);
86         glTexCoord2f(1, tcbottom);
87         glVertex2f(screenWidth, screenHeight);
88         glTexCoord2f(0, tcbottom);
89         glVertex2f(pixelBorder-1, screenHeight);
90         glEnd();
91
92         // Restore the old projection matrix.
93         glPopMatrix();
94
95         glMatrixMode(GL_MODELVIEW);
96         glPopMatrix();
97 }
98
99 // Drawing with the current state.
100 void OGL_DrawPatch_CS(int x, int y, int lumpnum)
101 {
102         int             w, h, p2w, p2h;
103         float   tcright, tcbottom;
104
105         // Set the texture.
106         OGL_SetPatch(lumpnum);
107
108         w = lumptexsizes[lumpnum].w;
109         h = lumptexsizes[lumpnum].h;
110         p2w = FindNextPower2(w); 
111         p2h = OGL_ValidTexHeight2(w, h);
112         tcright = (float)w/(float)p2w; 
113         tcbottom = (float)h/(float)p2h;
114         
115         x += lumptexsizes[lumpnum].offx;
116         y += lumptexsizes[lumpnum].offy;
117
118         glBegin(GL_QUADS);
119         
120         glTexCoord2f(0, 0);
121         glVertex2i(x, y);
122
123         glTexCoord2f(tcright, 0);
124         glVertex2i(x+w, y);
125
126         glTexCoord2f(tcright, tcbottom);
127         glVertex2i(x+w, y+h);
128
129         glTexCoord2f(0, tcbottom);
130         glVertex2i(x, y+h);
131
132         glEnd();
133
134         // Is there a second part?
135         if(OGL_GetOtherPart(lumpnum))
136         {
137                 x += w;
138
139                 OGL_BindTexture(OGL_GetOtherPart(lumpnum));
140                 w = lumptexsizes[lumpnum].w2;
141                 p2w = FindNextPower2(w);
142                 tcright = w/(float)p2w;
143
144                 glBegin(GL_QUADS);
145
146                 glTexCoord2f(0, 0);
147                 glVertex2i(x, y);
148
149                 glTexCoord2f(tcright, 0);
150                 glVertex2i(x+w, y);
151
152                 glTexCoord2f(tcright, tcbottom);
153                 glVertex2i(x+w, y+h);
154
155                 glTexCoord2f(0, tcbottom);
156                 glVertex2i(x, y+h);
157
158                 glEnd();
159         }
160 }
161
162 void OGL_DrawPatchLitAlpha(int x, int y, float light, float alpha, int lumpnum)
163 {
164         glColor4f(light, light, light, alpha);
165         OGL_DrawPatch_CS(x, y, lumpnum);
166 }
167
168 void OGL_DrawPatch(int x, int y, int lumpnum)
169 {
170         if(lumpnum < 0) return;
171         OGL_DrawPatchLitAlpha(x, y, 1, 1, lumpnum);
172 }
173
174 void OGL_DrawFuzzPatch(int x, int y, int lumpnum)
175 {
176         if(lumpnum < 0) return;
177         OGL_DrawPatchLitAlpha(x, y, 1, .333f, lumpnum);
178 }
179
180 void OGL_DrawAltFuzzPatch(int x, int y, int lumpnum)
181 {
182         if(lumpnum < 0) return;
183         OGL_DrawPatchLitAlpha(x, y, 1, .666f, lumpnum);
184 }
185
186 void OGL_DrawShadowedPatch(int x, int y, int lumpnum)
187 {
188         if(lumpnum < 0) return;
189         OGL_DrawPatchLitAlpha(x+2, y+2, 0, .4f, lumpnum);
190         OGL_DrawPatchLitAlpha(x, y, 1, 1, lumpnum);
191 }
192
193 extern void checkGLContext();
194 void OGL_DrawRect(float x, float y, float w, float h, float r, float g, float b, float a)
195 {
196         glColor4f(r, g, b, a);
197         glBegin(GL_QUADS);
198         glTexCoord2f(0, 0);
199         glVertex2f(x, y);
200         glTexCoord2f(1, 0);
201         glVertex2f(x+w, y);
202         glTexCoord2f(1, 1);
203         glVertex2f(x+w, y+h);
204         glTexCoord2f(0, 1);
205         glVertex2f(x, y+h);
206         glEnd();
207 }
208
209 void OGL_DrawRectTiled(int x, int y, int w, int h, int tw, int th)
210 {
211         glBegin(GL_QUADS);
212         glTexCoord2f(0, 0);
213         glVertex2i(x, y);
214         glTexCoord2f(w/(float)tw, 0);
215         glVertex2i(x+w, y);
216         glTexCoord2f(w/(float)tw, h/(float)th);
217         glVertex2i(x+w, y+h);
218         glTexCoord2f(0, h/(float)th);
219         glVertex2i(x, y+h);
220         glEnd();
221 }
222
223 // The cut rectangle must be inside the other one.
224 void OGL_DrawCutRectTiled(int x, int y, int w, int h, int tw, int th, 
225                                                   int cx, int cy, int cw, int ch)
226 {
227         float ftw = tw, fth = th;
228         // We'll draw at max four rectangles.
229         int     toph = cy-y, bottomh = y+h-(cy+ch), sideh = h-toph-bottomh,
230                 lefth = cx-x, righth = x+w-(cx+cw);
231         
232         glBegin(GL_QUADS);
233         if(toph > 0)
234         {
235                 // The top rectangle.
236                 glTexCoord2f(0, 0);
237                 glVertex2i(x, y);
238                 
239                 glTexCoord2f(w/ftw, 0);
240                 glVertex2i(x+w, y);
241
242                 glTexCoord2f(w/ftw, toph/fth);
243                 glVertex2i(x+w, y+toph);
244
245                 glTexCoord2f(0, toph/fth);
246                 glVertex2i(x, y+toph);
247         }
248         if(lefth > 0 && sideh > 0)
249         {
250                 float yoff = toph/fth;
251                 // The left rectangle.
252                 glTexCoord2f(0, yoff);
253                 glVertex2i(x, y+toph);
254
255                 glTexCoord2f(lefth/ftw, yoff);
256                 glVertex2i(x+lefth, y+toph);
257
258                 glTexCoord2f(lefth/ftw, yoff+sideh/fth);
259                 glVertex2i(x+lefth, y+toph+sideh);
260
261                 glTexCoord2f(0, yoff+sideh/fth);
262                 glVertex2i(x, y+toph+sideh);
263         }
264         if(righth > 0 && sideh > 0)
265         {
266                 int ox = x+lefth+cw;
267                 float xoff = (lefth+cw)/ftw;
268                 float yoff = toph/fth;
269                 // The left rectangle.
270                 glTexCoord2f(xoff, yoff);
271                 glVertex2i(ox, y+toph);
272
273                 glTexCoord2f(xoff+lefth/ftw, yoff);
274                 glVertex2i(ox+righth, y+toph);
275
276                 glTexCoord2f(xoff+lefth/ftw, yoff+sideh/fth);
277                 glVertex2i(ox+righth, y+toph+sideh);
278
279                 glTexCoord2f(xoff, yoff+sideh/fth);
280                 glVertex2i(ox, y+toph+sideh);
281         }
282         if(bottomh > 0)
283         {
284                 int oy = y+toph+sideh;
285                 float yoff = (toph+sideh)/fth;
286                 glTexCoord2f(0, yoff);
287                 glVertex2i(x, oy);
288                 
289                 glTexCoord2f(w/ftw, yoff);
290                 glVertex2i(x+w, oy);
291
292                 glTexCoord2f(w/ftw, yoff+bottomh/fth);
293                 glVertex2i(x+w, oy+bottomh);
294
295                 glTexCoord2f(0, yoff+bottomh/fth);
296                 glVertex2i(x, oy+bottomh);
297         }
298         glEnd();
299 }
300
301 void OGL_DrawLine(float x1, float y1, float x2, float y2, 
302                                   float r, float g, float b, float a)
303 {
304         glColor4f(r, g, b, a);
305         glBegin(GL_LINES);
306         glVertex2f(x1,y1);
307         glVertex2f(x2,y2);
308         glEnd();
309 }
310
311 void OGL_SetColor(int palidx)
312 {
313         byte rgb[3];
314         
315         if(palidx == -1)        // Invisible?
316                 glColor4f(0,0,0,0);
317         else
318         {
319                 PalIdxToRGB(W_CacheLumpNum(pallump,PU_CACHE), palidx, rgb);
320                 glColor3f(rgb[0]/255.0, rgb[1]/255.0, rgb[2]/255.0);
321         }
322 }
323
324 void OGL_SetColorAndAlpha(float r, float g, float b, float a)
325 {
326         glColor4f(r, g, b, a);
327 }
328
329 // Filters correspond the palettes in the wad.
330 void OGL_SetFilter(int filter)
331 {
332         curfilter = filter;     
333 }
334
335 // Returns nonzero if the filter was drawn.
336 int OGL_DrawFilter()
337 {
338         if(!curfilter) return 0;                // No filter needed.
339
340         // No texture, please.
341         //glBindTexture(GL_TEXTURE_2D, 0);
342         glDisable( GL_TEXTURE_2D );
343
344         // We have to choose the right color and alpha.
345         if(curfilter >= STARTREDPALS && curfilter < STARTREDPALS+NUMREDPALS) 
346                 // Red?
347                 glColor4f(1, 0, 0, curfilter/8.0);      // Full red with filter 8.
348         else if(curfilter >= STARTBONUSPALS && curfilter < STARTBONUSPALS+NUMBONUSPALS) 
349                 // Light Green?
350                 glColor4f(.5, 1, .5, (curfilter-STARTBONUSPALS+1)/12.0); 
351         else if(curfilter >= STARTPOISONPALS && curfilter < STARTPOISONPALS+NUMPOISONPALS)
352                 // Green?
353                 glColor4f(0, 1, 0, (curfilter-STARTPOISONPALS+1)/16.0);
354         else if(curfilter >= STARTSCOURGEPAL)
355                 // Orange?
356                 glColor4f(1, .5, 0, (STARTSCOURGEPAL+3-curfilter)/6.0);
357         else if(curfilter >= STARTHOLYPAL)
358                 // White?
359                 glColor4f(1, 1, 1, (STARTHOLYPAL+3-curfilter)/6.0);
360         else if(curfilter == STARTICEPAL)
361                 // Light blue?
362                 glColor4f(.5f, .5f, 1, .4f);
363         else
364                 I_Error("OGL_DrawFilter: Real strange filter number: %d.\n", curfilter);
365         
366         glBegin(GL_QUADS);
367         glVertex2f(0, 0);
368         glVertex2f(320, 0);
369         glVertex2f(320, 200);
370         glVertex2f(0, 200);
371         glEnd();
372
373         glEnable( GL_TEXTURE_2D );
374         return 1;
375 }
376