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