00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <windows.h>
00021 #include <gl/gl.h>
00022
00023 #include "Render.h"
00024 #include "OglDrv.h"
00025 #include "OglMisc.h"
00026 #include "THandle.h"
00027 #include "Win32.h"
00028
00029
00030 DRV_RENDER_MODE RenderMode = RENDER_NONE;
00031 uint32 Render_HardwareFlags = 0;
00032
00033 GLint boundTexture = -1;
00034 GLint boundTexture2 = -1;
00035
00036 GLint decalTexObj = -1;
00037
00038
00039
00040
00041
00042 void Render_WorldPolyRegular(DRV_TLVertex *Pnts, int32 NumPoints, geRDriver_THandle *THandle,
00043 DRV_LInfo *LInfo, GLfloat shiftU, GLfloat shiftV,
00044 GLfloat scaleU, GLfloat scaleV,
00045 GLubyte alpha)
00046 {
00047 DRV_TLVertex *pPnt;
00048 GLfloat zRecip;
00049 GLfloat tu, tv;
00050 GLint i;
00051
00052 #ifdef USE_LIGHTMAPS
00053 if(LInfo != NULL)
00054 {
00055 glDepthMask(GL_FALSE);
00056 }
00057 #endif
00058
00059 pPnt = Pnts;
00060
00061 glBegin(GL_TRIANGLE_FAN);
00062
00063 for(i = 0; i < NumPoints; i++)
00064 {
00065 zRecip = 1.0f / pPnt->z;
00066
00067 tu = (pPnt->u * scaleU + shiftU);
00068 tv = (pPnt->v * scaleV + shiftV);
00069
00070 glColor4ub((GLubyte)pPnt->r, (GLubyte)pPnt->g, (GLubyte)pPnt->b, alpha);
00071
00072 glTexCoord4f(tu * THandle->InvScale * zRecip,
00073 tv * THandle->InvScale * zRecip, 0.0f, zRecip);
00074
00075 glVertex3f(pPnt->x, pPnt->y, -1.0f + zRecip);
00076
00077 pPnt++;
00078 }
00079
00080 glEnd();
00081
00082 #ifdef USE_LIGHTMAPS
00083 if(LInfo != NULL)
00084 {
00085 glDepthMask(GL_TRUE);
00086
00087 glBlendFunc(GL_DST_COLOR,GL_ZERO);
00088
00089 pPnt = Pnts;
00090
00091 if(boundTexture != LInfo->THandle->TextureID)
00092 {
00093 glBindTexture(GL_TEXTURE_2D, LInfo->THandle->TextureID);
00094 boundTexture = LInfo->THandle->TextureID;
00095 }
00096
00097 if(LInfo->THandle->Flags & THANDLE_UPDATE)
00098 {
00099 THandle_Update(LInfo->THandle);
00100 }
00101
00102 shiftU = (GLfloat)LInfo->MinU - 8.0f;
00103 shiftV = (GLfloat)LInfo->MinV - 8.0f;
00104
00105 glColor4ub(255, 255, 255, 255);
00106
00107 glBegin(GL_TRIANGLE_FAN);
00108
00109 for(i = 0; i < NumPoints; i++)
00110 {
00111 zRecip = 1.0f / pPnt->z;
00112
00113 tu = pPnt->u - shiftU;
00114 tv = pPnt->v - shiftV;
00115
00116 glTexCoord4f(tu * LInfo->THandle->InvScale * zRecip,
00117 tv * LInfo->THandle->InvScale * zRecip, 0.0f, zRecip);
00118
00119 glVertex3f(pPnt->x, pPnt->y, -1.0f + zRecip);
00120
00121 pPnt++;
00122 }
00123
00124 glEnd();
00125
00126 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00127 }
00128 #endif
00129 }
00130
00131
00132
00133 void Render_WorldPolyMultitexture(DRV_TLVertex *Pnts, int32 NumPoints, geRDriver_THandle *THandle,
00134 DRV_LInfo *LInfo, GLfloat shiftU, GLfloat shiftV,
00135 GLfloat scaleU, GLfloat scaleV,
00136 GLubyte alpha)
00137 {
00138 DRV_TLVertex *pPnt;
00139 GLfloat zRecip;
00140 GLfloat tu, tv, lu, lv;
00141 GLfloat shiftU2, shiftV2;
00142 GLint i;
00143
00144
00145 if(LInfo != NULL)
00146 {
00147 glActiveTextureARB(GL_TEXTURE1_ARB);
00148 glEnable(GL_TEXTURE_2D);
00149
00150 if(boundTexture2 != LInfo->THandle->TextureID)
00151 {
00152 glBindTexture(GL_TEXTURE_2D, LInfo->THandle->TextureID);
00153 boundTexture2 = LInfo->THandle->TextureID;
00154 }
00155
00156 if(LInfo->THandle->Flags & THANDLE_UPDATE)
00157 {
00158 THandle_Update(LInfo->THandle);
00159 }
00160
00161 shiftU2 = (GLfloat)LInfo->MinU - 8.0f;
00162 shiftV2 = (GLfloat)LInfo->MinV - 8.0f;
00163 }
00164
00165 pPnt = Pnts;
00166
00167 glBegin(GL_TRIANGLE_FAN);
00168
00169 for(i = 0; i < NumPoints; i++)
00170 {
00171 zRecip = 1.0f / pPnt->z;
00172
00173 tu = (pPnt->u * scaleU + shiftU);
00174 tv = (pPnt->v * scaleV + shiftV);
00175
00176 glColor4ub((GLubyte)pPnt->r, (GLubyte)pPnt->g, (GLubyte)pPnt->b, alpha);
00177
00178 glMultiTexCoord4fARB(GL_TEXTURE0_ARB, tu * THandle->InvScale * zRecip,
00179 tv * THandle->InvScale * zRecip, 0.0f, zRecip);
00180
00181 if(LInfo)
00182 {
00183 lu = pPnt->u - shiftU2;
00184 lv = pPnt->v - shiftV2;
00185
00186 glMultiTexCoord4fARB(GL_TEXTURE1_ARB, lu * LInfo->THandle->InvScale * zRecip,
00187 lv * LInfo->THandle->InvScale * zRecip, 0.0f, zRecip);
00188 }
00189
00190 glVertex3f(pPnt->x, pPnt->y, -1.0f + zRecip);
00191
00192 pPnt++;
00193 }
00194
00195 glEnd();
00196
00197 if(LInfo != NULL)
00198 {
00199 glDisable(GL_TEXTURE_2D);
00200 glActiveTextureARB(GL_TEXTURE0_ARB);
00201 }
00202 }
00203
00204
00205
00206
00207 geBoolean DRIVERCC Render_WorldPoly(DRV_TLVertex *Pnts, int32 NumPoints, geRDriver_THandle *THandle,
00208 DRV_TexInfo *TexInfo, DRV_LInfo *LInfo, uint32 Flags)
00209 {
00210 GLfloat shiftU, shiftV, scaleU, scaleV;
00211 DRV_TLVertex *pPnt = Pnts;
00212 GLubyte alpha;
00213 BOOL Dynamic = 0;
00214
00215
00216 if(Flags & DRV_RENDER_ALPHA)
00217 {
00218 alpha = (GLubyte)Pnts->a;
00219 }
00220 else
00221 {
00222 alpha = 255;
00223 }
00224
00225
00226 shiftU = TexInfo->ShiftU;
00227 shiftV = TexInfo->ShiftV;
00228 scaleU = 1.0f / TexInfo->DrawScaleU;
00229 scaleV = 1.0f / TexInfo->DrawScaleV;
00230
00231 if(boundTexture != THandle->TextureID)
00232 {
00233 glBindTexture(GL_TEXTURE_2D, THandle->TextureID);
00234 boundTexture = THandle->TextureID;
00235 }
00236
00237 if(THandle->Flags & THANDLE_UPDATE)
00238 {
00239 THandle_Update(THandle);
00240 }
00241
00242 if(LInfo != NULL)
00243 {
00244 OGLDRV.SetupLightmap(LInfo, &Dynamic);
00245
00246 if(Dynamic || LInfo->THandle->Flags & THANDLE_UPDATE_LM)
00247 {
00248 THandle_DownloadLightmap(LInfo);
00249
00250 if(Dynamic)
00251 {
00252 LInfo->THandle->Flags |= THANDLE_UPDATE_LM;
00253 }
00254 else
00255 {
00256 LInfo->THandle->Flags &= ~THANDLE_UPDATE_LM;
00257 }
00258 }
00259 }
00260
00261
00262 if(multitexture)
00263 {
00264
00265 Render_WorldPolyMultitexture(Pnts, NumPoints, THandle, LInfo, shiftU, shiftV,
00266 scaleU, scaleV, alpha);
00267 }
00268 else
00269 {
00270
00271 Render_WorldPolyRegular(Pnts, NumPoints, THandle, LInfo, shiftU, shiftV,
00272 scaleU, scaleV, alpha);
00273 }
00274
00275 OGLDRV.NumRenderedPolys++;
00276
00277 return GE_TRUE;
00278 }
00279
00280
00281
00282 geBoolean DRIVERCC Render_GouraudPoly(DRV_TLVertex *Pnts, int32 NumPoints, uint32 Flags)
00283 {
00284 GLint i;
00285 GLfloat zRecip;
00286 DRV_TLVertex *pPnt = Pnts;
00287 GLubyte alpha;
00288
00289 if(Flags & DRV_RENDER_ALPHA)
00290 {
00291 alpha = (GLubyte)Pnts->a;
00292 }
00293 else
00294 {
00295 alpha = 255;
00296 }
00297
00298 glDisable(GL_TEXTURE_2D);
00299
00300 glBegin(GL_TRIANGLE_FAN);
00301
00302 for(i = 0; i < NumPoints; i++)
00303 {
00304 zRecip = 1.0f / pPnt->z;
00305
00306 glColor4ub((GLubyte)pPnt->r, (GLubyte)pPnt->g, (GLubyte)pPnt->b, alpha);
00307
00308 glVertex3f(pPnt->x, pPnt->y, -1.0f + zRecip);
00309
00310 pPnt++;
00311 }
00312
00313 glEnd();
00314
00315 glEnable(GL_TEXTURE_2D);
00316
00317 OGLDRV.NumRenderedPolys++;
00318
00319 return GE_TRUE;
00320 }
00321
00322
00323
00324 geBoolean DRIVERCC Render_MiscTexturePoly(DRV_TLVertex *Pnts, int32 NumPoints,
00325 geRDriver_THandle *THandle, uint32 Flags)
00326 {
00327 GLint i;
00328 GLfloat zRecip;
00329 DRV_TLVertex *pPnt = Pnts;
00330 GLubyte alpha;
00331
00332
00333 if(Flags & DRV_RENDER_ALPHA)
00334 {
00335 alpha = (GLubyte)Pnts->a;
00336 }
00337 else
00338 {
00339 alpha = 255;
00340 }
00341
00342 if(boundTexture != THandle->TextureID)
00343 {
00344 glBindTexture(GL_TEXTURE_2D, THandle->TextureID);
00345 boundTexture = THandle->TextureID;
00346 }
00347
00348 if(THandle->Flags & THANDLE_UPDATE)
00349 {
00350 THandle_Update(THandle);
00351 }
00352
00353 if(Flags & DRV_RENDER_NO_ZMASK)
00354 {
00355 glDisable(GL_DEPTH_TEST);
00356 }
00357
00358 glBegin(GL_TRIANGLE_FAN);
00359
00360 for(i = 0; i < NumPoints; i++)
00361 {
00362 zRecip = 1.0f / pPnt->z;
00363
00364 glColor4ub((GLubyte)pPnt->r, (GLubyte)pPnt->g, (GLubyte)pPnt->b, alpha);
00365
00366 glTexCoord4f(pPnt->u * zRecip, pPnt->v * zRecip, 0.0f, zRecip);
00367
00368 glVertex3f(pPnt->x, pPnt->y, -1.0f + zRecip);
00369
00370 pPnt++;
00371 }
00372
00373 glEnd();
00374
00375 if(Flags & DRV_RENDER_NO_ZMASK)
00376 {
00377 glEnable(GL_DEPTH_TEST);
00378 }
00379
00380 return GE_TRUE;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 geBoolean DRIVERCC DrawDecal(geRDriver_THandle *THandle, RECT *SRect, int32 x, int32 y)
00401 {
00402 RECT tmpRect, *srcRect;
00403 GLint width, height;
00404 GLfloat uClamp, vClamp;
00405 GLfloat uDiff = 1.0f, vDiff = 1.0f;
00406
00407 if(!SRect)
00408 {
00409 tmpRect.left = 0;
00410 tmpRect.right = THandle->Width;
00411 tmpRect.top = 0;
00412 tmpRect.bottom = THandle->Height;
00413
00414 srcRect = &tmpRect;
00415 width = (THandle->Width);
00416 height = (THandle->Height);
00417 }
00418 else
00419 {
00420 srcRect = SRect;
00421 width = (srcRect->right - srcRect->left);
00422 height = (srcRect->bottom - srcRect->top);
00423 }
00424
00425 if(x + width <= 0 || y + height <= 0 || x >= ClientWindow.Width || y >= ClientWindow.Height)
00426 {
00427 return GE_TRUE;
00428 }
00429
00430 if(x + width >= (ClientWindow.Width - 1))
00431 {
00432 srcRect->right -= ((x + width) - (ClientWindow.Width - 1));
00433 }
00434
00435 if(y + height >= (ClientWindow.Height - 1))
00436 {
00437 srcRect->bottom -= ((y + height) - (ClientWindow.Height - 1));
00438 }
00439
00440 if(x < 0)
00441 {
00442 srcRect->left += -x;
00443 x = 0;
00444 }
00445
00446 if(y < 0)
00447 {
00448 srcRect->top += -y;
00449 y = 0;
00450 }
00451
00452 if(boundTexture != THandle->TextureID)
00453 {
00454 glBindTexture(GL_TEXTURE_2D, THandle->TextureID);
00455 boundTexture = THandle->TextureID;
00456 }
00457
00458 if(THandle->Flags & THANDLE_UPDATE)
00459 {
00460 THandle_Update(THandle);
00461 }
00462
00463 glDisable(GL_DEPTH_TEST);
00464
00465 glColor4f(1.0, 1.0, 1.0, 1.0);
00466
00467 glShadeModel(GL_FLAT);
00468
00469 if(THandle->Data[1] == NULL)
00470 {
00471 uClamp = width / (GLfloat)THandle->PaddedWidth;
00472 vClamp = height / (GLfloat)THandle->PaddedHeight;
00473
00474 glMatrixMode(GL_TEXTURE);
00475 glPushMatrix();
00476 glLoadIdentity();
00477 glTranslatef(srcRect->left / (GLfloat)THandle->PaddedWidth,
00478 srcRect->top / (GLfloat)THandle->PaddedHeight, 0.0f);
00479
00480 glBegin(GL_QUADS);
00481
00482 glTexCoord2f(0.0f, 0.0);
00483 glVertex2i(x, y);
00484
00485 glTexCoord2f(uClamp, 0.0f);
00486 glVertex2i(x + width, y);
00487
00488 glTexCoord2f(uClamp, vClamp);
00489 glVertex2i(x + width, y + height);
00490
00491 glTexCoord2f(0.0f, vClamp);
00492 glVertex2i(x, y + height);
00493
00494 glEnd();
00495
00496 glPopMatrix();
00497 glMatrixMode(GL_MODELVIEW);
00498 }
00499 else
00500 {
00501
00502 glPixelStorei(GL_UNPACK_ROW_LENGTH, THandle->Width);
00503 glPixelStorei(GL_UNPACK_SKIP_PIXELS, srcRect->left);
00504 glPixelStorei(GL_UNPACK_SKIP_ROWS, srcRect->top);
00505
00506 glPixelZoom(1.0, -1.0);
00507
00508 if(width <= maxTextureSize && height <= maxTextureSize &&
00509 width == SnapToPower2(width) && height == SnapToPower2(height))
00510 {
00511
00512
00513
00514
00515
00516
00517 if(decalTexObj == -1)
00518 {
00519 glGenTextures(1, &decalTexObj);
00520 }
00521
00522 glBindTexture(GL_TEXTURE_2D, decalTexObj);
00523 boundTexture = decalTexObj;
00524
00525 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height,
00526 0, GL_RGBA, GL_UNSIGNED_BYTE, THandle->Data[1]);
00527
00528 glBegin(GL_QUADS);
00529
00530 glTexCoord2f(0.0f, 0.0);
00531 glVertex2i(x, y);
00532
00533 glTexCoord2f(1.0f, 0.0f);
00534 glVertex2i(x + width, y);
00535
00536 glTexCoord2f(1.0f, 1.0f);
00537 glVertex2i(x + width, y + height);
00538
00539 glTexCoord2f(0.0f, 1.0f);
00540 glVertex2i(x, y + height);
00541
00542 glEnd();
00543 }
00544 else
00545 {
00546 glPixelZoom(1.0, -1.0);
00547
00548 glRasterPos2i(x, y);
00549 glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, THandle->Data[1]);
00550 }
00551
00552 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00553 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00554 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00555 }
00556
00557 glShadeModel(GL_SMOOTH);
00558
00559 glEnable(GL_DEPTH_TEST);
00560
00561 return GE_TRUE;
00562 }
00563
00564
00565 geBoolean DRIVERCC BeginScene(geBoolean Clear, geBoolean ClearZ, RECT *WorldRect)
00566 {
00567
00568 if(Clear)
00569 {
00570 glClear(GL_COLOR_BUFFER_BIT);
00571 }
00572
00573 if(ClearZ)
00574 {
00575 glClear(GL_DEPTH_BUFFER_BIT);
00576 }
00577
00578 OGLDRV.NumRenderedPolys = 0;
00579
00580 return GE_TRUE;
00581 }
00582
00583
00584 geBoolean DRIVERCC EndScene(void)
00585 {
00586 FlipGLBuffers();
00587
00588 return GE_TRUE;
00589 }
00590
00591
00592 geBoolean DRIVERCC BeginWorld(void)
00593 {
00594 RenderMode = RENDER_WORLD;
00595
00596 OGLDRV.NumWorldPixels = 0;
00597 OGLDRV.NumWorldSpans = 0;
00598
00599 return TRUE;
00600 }
00601
00602
00603 geBoolean DRIVERCC EndWorld(void)
00604 {
00605 RenderMode = RENDER_NONE;
00606
00607
00608 return TRUE;
00609 }
00610
00611
00612 geBoolean DRIVERCC BeginMeshes(void)
00613 {
00614 RenderMode = RENDER_MESHES;
00615
00616 return TRUE;
00617 }
00618
00619
00620 geBoolean DRIVERCC EndMeshes(void)
00621 {
00622 RenderMode = RENDER_NONE;
00623
00624 return TRUE;
00625 }
00626
00627
00628 geBoolean DRIVERCC BeginModels(void)
00629 {
00630 RenderMode = RENDER_MODELS;
00631
00632 return TRUE;
00633 }
00634
00635
00636 geBoolean DRIVERCC EndModels(void)
00637 {
00638 RenderMode = RENDER_NONE;
00639
00640 return TRUE;
00641 }