Initial revision
[0ad:0ad.git] / terrain / Renderer.cpp
1 #include "Renderer.H"
2 #include "Matrix3D.H"
3 #include "Camera.H"
4
5 #include "types.h"
6 #include "ogl.h"
7 #include "tex.h"
8
9 #define         RENDER_STAGE_BASE               (1)
10 #define         RENDER_STAGE_TRANS              (2)
11
12 bool g_WireFrame = false;
13 unsigned int g_FrameCounter = 0;
14
15 CRenderer::CRenderer ()
16 {
17         m_Timer = 0;
18         m_CurrentSeason = 0;
19 }
20
21 CRenderer::~CRenderer ()
22 {
23 }
24
25         
26 bool CRenderer::Initialize (HWND hwnd, int width, int height, int depth)
27 {
28         m_Width = width;
29         m_Height = height;
30         m_Depth = depth;
31         return true;
32 }
33
34 void CRenderer::Shutdown ()
35 {
36
37 }
38 /*
39 struct Tile
40 {
41         u32 pri_tex : 5;
42         u32 sec_tex : 5;
43         u32 alpha_map : 6;
44 };
45
46
47 void render_terrain()
48 {
49         CMatrix3D view = camera->m_Orientation.GetTranspose();
50         CMatrix3D proj = camera->GetProjection();
51
52         float gl_view[16] = {view._11, view._21, view._31, view._41,
53                                                  view._12, view._22, view._32, view._42,
54                                                  view._13, view._23, view._33, view._43,
55                                                  view._14, view._24, view._34, view._44};
56
57         float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41,
58                                                  proj._12, proj._22, proj._32, proj._42,
59                                                  proj._13, proj._23, proj._33, proj._43,
60                                                  proj._14, proj._24, proj._34, proj._44};
61
62         glMatrixMode (GL_MODELVIEW);
63         glLoadMatrixf (gl_view);
64
65         glMatrixMode (GL_PROJECTION);
66         glLoadMatrixf (gl_proj);
67
68         SViewPort vp = camera->GetViewPort();
69         glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height);
70
71         if (g_WireFrame)
72                 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
73         else
74                 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
75
76
77         for (int j=0; j<NUM_PATCHES_PER_SIDE; j++)
78         {
79                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
80                 {
81                         if (camera->GetFustum().IsBoxVisible (CVector3D(0,0,0), terrain->m_Patches[j][i].m_Bounds))
82                                 terrain->m_Patches[j][i].m_LastVisFrame = g_FrameCounter;
83                 }
84         }
85
86         for (j=0; j<NUM_PATCHES_PER_SIDE; j++)
87         {
88                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
89                 {
90                         if (terrain->m_Patches[j][i].m_LastVisFrame == g_FrameCounter)
91                                 render_patch(&terrain->m_Patches[j][i]);
92                 }
93         }
94 }
95 */
96 void CRenderer::RenderTerrain (CTerrain *terrain, CCamera *camera)
97 {
98 //      m_Timer += 0.001f;
99
100         if (m_Timer > 1.0f)
101         {
102                 m_Timer = 0;
103                 
104                 if (m_CurrentSeason == 0)
105                         m_CurrentSeason = 1;
106                 else
107                         m_CurrentSeason = 0;
108         }
109
110         CMatrix3D view = camera->m_Orientation.GetTranspose();
111         CMatrix3D proj = camera->GetProjection();
112
113         float gl_view[16] = {view._11, view._21, view._31, view._41,
114                                                  view._12, view._22, view._32, view._42,
115                                                  view._13, view._23, view._33, view._43,
116                                                  view._14, view._24, view._34, view._44};
117
118         float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41,
119                                                  proj._12, proj._22, proj._32, proj._42,
120                                                  proj._13, proj._23, proj._33, proj._43,
121                                                  proj._14, proj._24, proj._34, proj._44};
122
123
124         glMatrixMode (GL_MODELVIEW);
125         glLoadMatrixf (gl_view);
126
127         glMatrixMode (GL_PROJECTION);
128         glLoadMatrixf (gl_proj);
129
130         SViewPort vp = camera->GetViewPort();
131         glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height);
132
133         if (g_WireFrame)
134                 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
135         else
136                 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
137
138
139         for (int j=0; j<NUM_PATCHES_PER_SIDE; j++)
140         {
141                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
142                 {
143                         if (camera->GetFustum().IsBoxVisible (CVector3D(0,0,0), terrain->m_Patches[j][i].m_Bounds))
144                                 terrain->m_Patches[j][i].m_LastVisFrame = g_FrameCounter;
145                 }
146         }
147
148         for (j=0; j<NUM_PATCHES_PER_SIDE; j++)
149         {
150                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
151                 {
152                         if (terrain->m_Patches[j][i].m_LastVisFrame == g_FrameCounter)
153                                 RenderPatchBase (&terrain->m_Patches[j][i]);
154                 }
155         }
156
157
158         for (j=0; j<NUM_PATCHES_PER_SIDE; j++)
159         {
160                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
161                 {
162                         if (terrain->m_Patches[j][i].m_LastVisFrame == g_FrameCounter)
163                                 RenderPatchTrans (&terrain->m_Patches[j][i]);
164
165                 }
166         }
167 }
168
169 void CRenderer::RenderPatchBase (CPatch *patch)
170 {
171         CMiniPatch *MPatch, *MPCurrent;
172
173         float StartU, StartV;
174         
175
176         for (int j=0; j<16; j++)
177         {
178                 for (int i=0; i<16; i++)
179                 {
180                         MPatch = &(patch->m_MiniPatches[j][i]);
181
182                         if (MPatch->m_LastRenderedFrame == g_FrameCounter)
183                                 continue;
184
185                         glActiveTexture (GL_TEXTURE0);
186                         glEnable(GL_TEXTURE_2D);
187
188 tex_bind(MPatch->Tex1);
189
190                         glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
191                         glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
192
193 /////////////////////////////////////
194                         glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
195
196                         glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
197                         glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
198                         glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
199                         glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
200                         glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
201
202                         glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
203                         glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
204                         glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
205 /////////////////////////////////////
206
207                         StartU = 0.125f * (float)(i%8);
208                         StartV = 0.125f * (float)(j%8);
209
210                         float tu[2], tv[2];
211                         tu[0] = tu[1] = StartU;
212                         tv[0] = StartV+0.125f;
213                         tv[1] = StartV;
214
215                         MPCurrent = MPatch;
216                         glBegin (GL_TRIANGLE_STRIP);
217
218                         int start = 0;
219
220                         while (MPCurrent)
221                         {
222                                 for (int x=start; x<2; x++)
223                                 {
224                                         int v1 = MAP_SIZE + x;
225                                         int v2 = x;
226
227                                         float factor = m_Timer;
228                                         if (m_CurrentSeason == 1)
229                                                 factor = 1.0f - factor;
230
231                                         float color1[3] = {MPCurrent->m_pVertices[v1].m_Color[0][0]*factor + MPCurrent->m_pVertices[v1].m_Color[1][0]*(1.0f-factor),
232                                                                            MPCurrent->m_pVertices[v1].m_Color[0][1]*factor + MPCurrent->m_pVertices[v1].m_Color[1][1]*(1.0f-factor),
233                                                                            MPCurrent->m_pVertices[v1].m_Color[0][2]*factor + MPCurrent->m_pVertices[v1].m_Color[1][2]*(1.0f-factor)};
234
235                                         float color2[3] = {MPCurrent->m_pVertices[v2].m_Color[0][0]*factor + MPCurrent->m_pVertices[v2].m_Color[1][0]*(1.0f-factor),
236                                                                            MPCurrent->m_pVertices[v2].m_Color[0][1]*factor + MPCurrent->m_pVertices[v2].m_Color[1][1]*(1.0f-factor),
237                                                                            MPCurrent->m_pVertices[v2].m_Color[0][2]*factor + MPCurrent->m_pVertices[v2].m_Color[1][2]*(1.0f-factor)};
238
239                                         glTexCoord2f (tu[0], tv[0]);
240
241                                         if (g_HillShading)
242                                                 glColor3f (color1[0],color1[1],color1[2]);
243                                         else
244                                                 glColor3f (1,1,1);
245
246                                         glVertex3f (MPCurrent->m_pVertices[v1].m_Position.X,
247                                                                 MPCurrent->m_pVertices[v1].m_Position.Y,
248                                                                 MPCurrent->m_pVertices[v1].m_Position.Z);
249
250                                         glTexCoord2f (tu[1], tv[1]);
251
252                                         if (g_HillShading)
253                                                 glColor3f (color2[0],color2[1],color2[2]);
254                                         else
255                                                 glColor3f (1,1,1);
256                                         
257                                         glVertex3f (MPCurrent->m_pVertices[v2].m_Position.X,
258                                                                 MPCurrent->m_pVertices[v2].m_Position.Y,
259                                                                 MPCurrent->m_pVertices[v2].m_Position.Z);
260
261                                         tu[0]+=0.125f;
262                                         tu[1]+=0.125f;
263                                 }
264
265                                 MPCurrent->m_LastRenderedFrame = g_FrameCounter;
266                                 MPCurrent->m_RenderStage = RENDER_STAGE_BASE;
267
268                                 if (!MPCurrent->m_pRightNeighbor)
269                                         break;
270                                 else
271                                 {
272                                         if (MPCurrent->m_pRightNeighbor->Tex1 != MPCurrent->Tex1 ||
273                                                 MPCurrent->m_pRightNeighbor->m_pParrent->m_LastVisFrame != g_FrameCounter)
274                                                 break;
275                                 }
276
277                                 MPCurrent = MPCurrent->m_pRightNeighbor;
278                                 start = 1;
279                         }
280
281                         glEnd ();
282                 }
283         }
284 }
285
286 void CRenderer::RenderPatchTrans (CPatch *patch)
287 {
288         CMiniPatch *MPatch, *MPCurrent;
289
290         float StartU, StartV;
291         
292         glEnable (GL_BLEND);
293         glDepthFunc (GL_EQUAL);
294         glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
295
296         for (int j=0; j<16; j++)
297         {
298                 for (int i=0; i<16; i++)
299                 {
300                         MPatch = &(patch->m_MiniPatches[j][i]);
301
302                         if (MPatch->m_LastRenderedFrame == g_FrameCounter &&
303                                 MPatch->m_RenderStage == RENDER_STAGE_TRANS)
304                                 continue;
305
306                         //now for transition
307                         if (MPatch->Tex2 && MPatch->m_AlphaMap)
308                         {
309
310                                 glActiveTexture (GL_TEXTURE0);
311                                 glEnable(GL_TEXTURE_2D);
312
313 tex_bind(MPatch->Tex2);
314
315                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
316                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
317
318 /////////////////////////////////////
319                                 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
320
321                                 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
322                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
323                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
324                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
325                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
326                                         
327                                 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
328                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
329                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
330 /////////////////////////////////////
331                                 
332
333                                 glActiveTexture (GL_TEXTURE1);
334                                 glEnable(GL_TEXTURE_2D);
335 tex_bind(MPatch->m_AlphaMap);                           
336                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
337                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
338 /////////////////////////////////////
339                                 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
340
341                                 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
342                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
343                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
344                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
345                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
346                                 
347                                 glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
348                                 glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
349                                 glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
350 /////////////////////////////////////
351
352                                 StartU = 0.125f * (float)(i%8);
353                                 StartV = 0.125f * (float)(j%8);
354
355                                 float tu[2], tv[2];
356                                 tu[0] = tu[1] = StartU;
357                                 tv[0] = StartV+0.125f;
358                                 tv[1] = StartV;
359                                 
360                                 glBegin (GL_TRIANGLE_STRIP);
361                                 MPCurrent = MPatch;
362
363                                 int start = 0;
364
365                                 while (MPCurrent)
366                                 {
367                                         for (int x=start; x<2; x++)
368                                         {
369                                                 int v1 = MAP_SIZE + x;
370                                                 int v2 = x;
371
372                                                 float factor = m_Timer;
373                                                 if (m_CurrentSeason == 1)
374                                                         factor = 1.0f - factor;
375                                                         
376                                                 float color1[3] = {MPCurrent->m_pVertices[v1].m_Color[0][0]*factor + MPCurrent->m_pVertices[v1].m_Color[1][0]*(1.0f-factor),
377                                                                                    MPCurrent->m_pVertices[v1].m_Color[0][1]*factor + MPCurrent->m_pVertices[v1].m_Color[1][1]*(1.0f-factor),
378                                                                                    MPCurrent->m_pVertices[v1].m_Color[0][2]*factor + MPCurrent->m_pVertices[v1].m_Color[1][2]*(1.0f-factor)};
379
380                                                 float color2[3] = {MPCurrent->m_pVertices[v2].m_Color[0][0]*factor + MPCurrent->m_pVertices[v2].m_Color[1][0]*(1.0f-factor),
381                                                                                    MPCurrent->m_pVertices[v2].m_Color[0][1]*factor + MPCurrent->m_pVertices[v2].m_Color[1][1]*(1.0f-factor),
382                                                                                    MPCurrent->m_pVertices[v2].m_Color[0][2]*factor + MPCurrent->m_pVertices[v2].m_Color[1][2]*(1.0f-factor)};
383
384                                                 glMultiTexCoord2f (GL_TEXTURE0_ARB, tu[0], tv[0]);
385                                                 glMultiTexCoord2f (GL_TEXTURE1_ARB, tu[0]*2, tv[0]*2);
386                                                 
387                                                 if (g_HillShading)
388                                                         glColor3f (color1[0],color1[1],color1[2]);
389                                                 else
390                                                         glColor3f (1,1,1);
391
392                                                 glVertex3f (MPCurrent->m_pVertices[v1].m_Position.X,
393                                                                         MPCurrent->m_pVertices[v1].m_Position.Y,
394                                                                         MPCurrent->m_pVertices[v1].m_Position.Z);
395
396                                                 glMultiTexCoord2f (GL_TEXTURE0_ARB, tu[1], tv[1]);
397                                                 glMultiTexCoord2f (GL_TEXTURE1_ARB, tu[1]*2, tv[1]*2);
398                                                 
399                                                 if (g_HillShading)
400                                                         glColor3f (color2[0],color2[1],color2[2]);
401                                                 else
402                                                         glColor3f (1,1,1);
403                                                 
404                                                 glVertex3f (MPCurrent->m_pVertices[v2].m_Position.X,
405                                                                         MPCurrent->m_pVertices[v2].m_Position.Y,
406                                                                         MPCurrent->m_pVertices[v2].m_Position.Z);
407
408                                                 tu[0]+=0.125f;
409                                                 tu[1]+=0.125f;
410                                         }
411
412                                         MPCurrent->m_LastRenderedFrame = g_FrameCounter;
413                                         MPCurrent->m_RenderStage = RENDER_STAGE_TRANS;
414
415                                         if (!MPCurrent->m_pRightNeighbor)
416                                                 break;
417                                         else
418                                         {
419                                                 if (MPCurrent->m_pRightNeighbor->Tex2 != MPCurrent->Tex2 ||
420                                                     MPCurrent->m_pRightNeighbor->m_AlphaMap != MPCurrent->m_AlphaMap ||
421                                                         MPCurrent->m_pRightNeighbor->m_pParrent->m_LastVisFrame != g_FrameCounter)
422                                                         break;
423                                         }
424
425                                         MPCurrent = MPCurrent->m_pRightNeighbor;
426                                         start=1;
427                                 }
428
429                                 glEnd ();
430                         }
431                 }
432         }
433
434         glDepthFunc (GL_LEQUAL);
435         glDisable (GL_BLEND);
436         glActiveTexture (GL_TEXTURE1);
437 glDisable(GL_TEXTURE_2D);
438 }
439
440 void CRenderer::RenderTileOutline (CMiniPatch *mpatch)
441 {
442 if(!mpatch->m_pVertices)
443 return;
444
445         glActiveTexture (GL_TEXTURE0);
446         glDisable (GL_DEPTH_TEST);
447         glDisable (GL_TEXTURE_2D);
448         glLineWidth (4);
449
450         STerrainVertex V[4];
451         V[0] = mpatch->m_pVertices[0];
452         V[1] = mpatch->m_pVertices[1];
453         V[2] = mpatch->m_pVertices[MAP_SIZE*1 + 1];
454         V[3] = mpatch->m_pVertices[MAP_SIZE*1];
455         
456         glColor3f (0,1.0f,0);
457
458         glBegin (GL_LINE_LOOP);
459                 
460                 for(int i = 0; i < 4; i++)
461                         glVertex3fv(&V[i].m_Position.X);
462
463         glEnd ();
464
465         glEnable (GL_DEPTH_TEST);
466         glEnable (GL_TEXTURE_2D);
467 }