#include "OGL_Class.h" #include "SCENE.h" #define GL_TEXTURE_BASE_LEVEL 0x813C #define GL_TEXTURE_MAX_LEVEL 0x813D #define TileSizePo2 8 static u32 Tile[1<<(TileSizePo2*2)]; //#pragma optimize("",off) void ATI_OptimizerToGL_ConvertRaster(s32 *pSource , u32 *pDest , s32 *pSourceLast) { while (pSource < pSourceLast) { ((u8*)pDest)[0] = ((u8*)pSource)[2]; ((u8*)pDest)[2] = ((u8*)pSource)[0]; ((u8*)pDest)[0+4] = ((u8*)pSource)[2+4]; ((u8*)pDest)[2+4] = ((u8*)pSource)[0+4]; ((u8*)pDest)[0+8] = ((u8*)pSource)[2+8]; ((u8*)pDest)[2+8] = ((u8*)pSource)[0+8]; ((u8*)pDest)[0+12] = ((u8*)pSource)[2+12]; ((u8*)pDest)[2+12] = ((u8*)pSource)[0+12]; pDest+=4; pSource+=4; } } u32 ATI_OptimizerGetHash(MAP *pSrc) { s32 *B1; u32 Signature = 0; B1 = pSrc->GetBase(); for (int Y = 0 ; Y < pSrc->SY ; Y ++) { s32 *B1Last = B1 + pSrc->SX; while (B1 < B1Last) { Signature += *(B1++); } B1 += pSrc->PITCH - pSrc->SX; } return Signature; } void ATI_ComputeMipMap(u32 *pDST,u32 SizeX,u32 SizeY) { u32 *pDSTSave = pDST; /* Y / 2 */ SizeY += 1; SizeY &= ~ 1; SizeX += 1; SizeX &= ~ 1; for (u32 Y = 0 ; Y < SizeY >> 1 ; Y++) { for (u32 X = 0 ; X < SizeX ; X++) { *pDST = ((*(pDSTSave+SizeX) & 0xfefefefe)>>1) + ((*(pDSTSave) & 0xfefefefe)>>1); pDST ++; pDSTSave++; } pDSTSave += SizeX; } // X / 2 pDSTSave -= (SizeX * SizeY); pDST = pDSTSave; if (SizeX & 1) { u32 Counter = (SizeX * SizeY) >> 2; while (Counter--) { *pDST = ((*(pDSTSave+1) & 0xfefefefe)>>1) + ((*(pDSTSave) & 0xfefefefe)>>1); pDSTSave += 2; pDST ++; } } else { u32 Counter = (SizeX * SizeY) >> 2; while (Counter--) { *pDST = ((*(pDSTSave+1) & 0xfefefefe)>>1) + ((*(pDSTSave) & 0xfefefefe)>>1); pDSTSave += 2; pDST ++; } } } void ATI_OptimizerToGL(MAP *pSrc,u32 ComputeMipMap = 0) { /* Parse tiles */ s32 *pBASE = pSrc->GetBase(); for (int Y = 0 ; Y < pSrc->SY ; Y += 1<SY ? (1<SY - Y; for (int X = 0 ; X < pSrc->SX ; X += 1<SX ? (1<SX - X; u32 *pDest = Tile; s32 *pSource,*pSourceLasLine,*pSourceLast; pSource = pBASE + X + Y * pSrc->PITCH; pSourceLast = pSource + H * pSrc->PITCH ; while (pSource < pSourceLast) { pSourceLasLine = pSource + (W&(~3)); memcpy(pDest, pSource ,W*sizeof(s32)); ATI_OptimizerToGL_ConvertRaster(pSource , pDest , pSourceLasLine); pSource += (W&(~3)); pDest += (W&(~3)); pSourceLasLine = pSource + (W&3); while (pSource < pSourceLasLine) { u8 swap; ((u8*)pDest)[0] = ((u8*)pSource)[2]; ((u8*)pDest)[2] = ((u8*)pSource)[0]; pDest++; pSource++; } pSource -= W; pSource += pSrc->PITCH; } for (u32 Mp = 0 ; W>>Mp > 0 ; Mp ++ ) { glTexSubImage2D(GL_TEXTURE_2D, Mp,//level X>>Mp, Y>>Mp, W>>Mp,H>>Mp, GL_RGBA/*GL_BGRA_EXT*/, GL_UNSIGNED_BYTE, Tile); ATI_ComputeMipMap(Tile,W >> Mp,H>>Mp); if (ComputeMipMap == 0) Mp = 30; // Break loop } } } } void ATI_OptimizerFromGL(int x, int y, int sx, int sy, void *buffer) { glReadPixels(x, y, sx, sy, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer); return; glReadPixels(x, y, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, buffer); s32 *pSource,*pSourceLasLine,*pSourceLast; pSource = (s32 *)buffer; pSourceLast = pSource + sx * sy; for (;pSource < pSourceLast; pSource++) { u8 swap = ((u8*)pSource)[0]; ((u8*)pSource)[0] = ((u8*)pSource)[2]; ((u8*)pSource)[2] = swap; } } int SoftCopyTime = 0; // WAITTIME void CopyFrameBufferToTexture(int x, int y, int x2, int y2, int textW, int textH) { if (SoftCopyTime < (int)timeGetTime()) { glCopyTexSubImage2D(GL_TEXTURE_2D, 0 , x , y , x2 , y2, textW , textH); return; } /* Parse tiles */ for (int Y = 0 ; Y < textH ; Y += 1< 5000)) { /* Then Reload it */ CreateTexture(TextureIndex,AllRef[TextureIndex].ColorMode); } QuadRotation_ON = 0; ZBIas = 1.0f; memcpy(SavedCurrentViewport,CurrentViewport,sizeof(SavedCurrentViewport)); RenderTargetState = 1; RenderTargetBaseX = CurrentViewport[0]; RenderTargetBaseY = CurrentViewport[1]; if (RenderTargetBaseX + AllRef[TextureIndex].pExtRef->SX > FB_SX) RenderTargetBaseX = FB_SX - AllRef[TextureIndex].pExtRef->SX ; if (RenderTargetBaseY + AllRef[TextureIndex].pExtRef->SY > FB_SY) RenderTargetBaseY = FB_SY - AllRef[TextureIndex].pExtRef->SY ; if (RenderTargetBaseX < 0) RenderTargetBaseX = 0; if (RenderTargetBaseY < 0) RenderTargetBaseY = 0; SetViewport(RenderTargetBaseX,RenderTargetBaseY,AllRef[TextureIndex].pExtRef->SX,AllRef[TextureIndex].pExtRef->SY); if (MotherClass) MotherClass->PickReportCurrent.PickFrozed++; /* Save front buffer */ if (SaveFrontBuffer) { RenderTargetState |= 2; ValidateLayer(NUMBER_OF_WORKING_REF - 3); CopyFrameBufferToTexture(0, 0, RenderTargetBaseX , RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); //YTEST glCopyTexSubImage2D(GL_TEXTURE_2D, 0 , 0 , 0 , RenderTargetBaseX , RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); } /* Reload Texture */ SetBackGround(TextureIndex); glViewport(RenderTargetBaseX, RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); glScissor(RenderTargetBaseX, RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY);//*/ ActivRect.left = RenderTargetBaseX; ActivRect.top = RenderTargetBaseY; ActivRect.right = AllRef[TextureIndex].pExtRef->SX + RenderTargetBaseX; ActivRect.bottom = AllRef[TextureIndex].pExtRef->SY + RenderTargetBaseY; AllRef[TextureIndex].IsMipMapped = 0; /* Save front buffer */ CurrentRect.left = CurrentRect.top = 0; CurrentRect.right = AllRef[TextureIndex].pExtRef->SX; CurrentRect.bottom = AllRef[TextureIndex].pExtRef->SY;//*/ } void OGL_DI::EndTextureTarget(u32 TextureIndex,u32 bUpdateSoftBuffer) { QuadRotation_ON = 0; glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef); AllRef[TextureIndex].IsMipMapped = 0; glEnable(GL_TEXTURE_2D); CopyFrameBufferToTexture(0, 0, RenderTargetBaseX , RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); //YTEST glCopyTexSubImage2D(GL_TEXTURE_2D, 0 , 0 , 0 , RenderTargetBaseX , RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); if (bUpdateSoftBuffer && !(MotherClass && MotherClass->SkipFunctions & SKIP_GLREAD)) ATI_OptimizerFromGL(RenderTargetBaseX,RenderTargetBaseY,AllRef[TextureIndex].pExtRef->PITCH, AllRef[TextureIndex].pExtRef->SY, AllRef[TextureIndex].pExtRef->GetBase()); // restore front buffer if (RenderTargetState & 2) { LayerOperation(5,NUMBER_OF_WORKING_REF - 3,0xffffffff,0.0f,0.0f) ; } CurrentRect = hDCRect; SetViewport(SavedCurrentViewport[0],SavedCurrentViewport[1],SavedCurrentViewport[2],SavedCurrentViewport[3]); RenderTargetBaseX = RenderTargetBaseY = RenderTargetState = 0; if (MotherClass && MotherClass->PickReportCurrent.PickFrozed) MotherClass->PickReportCurrent.PickFrozed--; ZBIas = 1.0f; } void OGL_DI::ValidateLayer(u32 Index) { Index %= NUMBER_OF_OGL_WORKING_REF; if (OGLWorkingRef[Index] != -1) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, OGLWorkingRef[Index]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); /* if (((FrameNumber + Index ) & 8191) == 0) { GLint param; glGetTexParameteriv(GL_TEXTURE_2D ,GL_TEXTURE_RESIDENT,¶m); if (!param) { // ForceReload glDeleteTextures(1, &OGLWorkingRef[Index]); OGLWorkingRef[Index] = -1; } }//*/ } if (OGLWorkingRef[Index] == -1) { glGenTextures(1, &OGLWorkingRef[Index]); glBindTexture(GL_TEXTURE_2D, OGLWorkingRef[Index]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER,0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_2D); if (Index == NUMBER_OF_OGL_WORKING_REF-1) //glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE, 0 , 0 , OGLTextureSizeX, OGLTextureSizeY, 0); glTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE , OGLTextureSizeX, OGLTextureSizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); else //glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, 0 , 0 , OGLTextureSizeX, OGLTextureSizeY, 0); glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, OGLTextureSizeX, OGLTextureSizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } } u32 OGL_DI::GetTexFreeIndex() { static u32 Counter = MaxOglTexture; while (Counter--) { if (AllRef[Counter].OGLRef == 0xffffffff) return Counter; } Counter = MaxOglTexture; while (Counter--) { if (AllRef[Counter].OGLRef == 0xffffffff) return Counter; } return -1; } void OGL_DI::DrawLine(u32 Color,Vector *A,Vector *B, int Lenght) { if (Lenght) { glLineWidth((float)Lenght); glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_WIDTH); } else glLineWidth(1.0); glBegin(GL_LINE_STRIP); glColor4ubv((GLubyte *) &Color); glTexCoord2f(0.0f,0.0f); glVertex3fv((GLfloat *)A); glTexCoord2f(1.0f,1.0f); glVertex3fv((GLfloat *)B); glEnd( ); if (Lenght) { glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_WIDTH); glLineWidth(1.0); } } void OGL_DI::ReadFrameBuffer(s32 X,s32 Y,s32 SX,s32 SY, MAP *dest) { if (!(MotherClass && MotherClass->SkipFunctions & SKIP_GLREAD)) //glReadPixels(X,Y,SX,SY,GL_BGRA_EXT,GL_UNSIGNED_BYTE, dest->GetBase()); ATI_OptimizerFromGL(X,Y,SX,SY,dest->GetBase()); } void OGL_DI::UpdateTexture_BM_2_HW(u32 TextureIndex, bool isDynamic) { if (MotherClass && MotherClass->SkipFunctions & SKIP_GLWRITE) return; glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef); glEnable(GL_TEXTURE_2D); if (AllRef[TextureIndex].pExtRef->GetBase()) { u32 NewHash = ATI_OptimizerGetHash(AllRef[TextureIndex].pExtRef); if (AllRef[TextureIndex].LastHash != NewHash) ATI_OptimizerToGL(AllRef[TextureIndex].pExtRef,AllRef[TextureIndex].IsMipMapped); AllRef[TextureIndex].LastHash = NewHash; //glTexSubImage2D(GL_TEXTURE_2D,0,0,0,AllRef[TextureIndex].pExtRef->PITCH,AllRef[TextureIndex].pExtRef->SY,GL_RGBA/*GL_BGRA_EXT*/,GL_UNSIGNED_BYTE,AllRef[TextureIndex].pExtRef->GetBase());//*/ } }; void OGL_DI::UpdateTexture_HW_2_BM(u32 TextureIndex,u32 bUpdateSoftBuffer,s32 X, s32 Y) { glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef); glEnable(GL_TEXTURE_2D); AllRef[TextureIndex].IsMipMapped = 0; CopyFrameBufferToTexture(0, 0, X , Y, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); //YTEST glCopyTexSubImage2D(GL_TEXTURE_2D, 0 , 0 , 0 , X , Y, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY); if (bUpdateSoftBuffer && !(MotherClass && MotherClass->SkipFunctions & SKIP_GLREAD)) //glReadPixels(X,Y,AllRef[TextureIndex].pExtRef->PITCH, AllRef[TextureIndex].pExtRef->SY,GL_BGRA_EXT,GL_UNSIGNED_BYTE,AllRef[TextureIndex].pExtRef->GetBase()); ATI_OptimizerFromGL(X,Y,AllRef[TextureIndex].pExtRef->PITCH, AllRef[TextureIndex].pExtRef->SY,AllRef[TextureIndex].pExtRef->GetBase()); }; void OGL_DI::SetTextureColorMode(u32 Index,u32 ColorMode) { if (Index != -1) { if (ColorMode != AllRef[Index].ColorMode) { if (AllRef[Index].pExtRef) { if (AllRef[Index].OGLRef != -1) { glDeleteTextures(1, &AllRef[Index].OGLRef); AllRef[Index].LastHash = -1; CreateTexture(Index,ColorMode); } } } } } void OGL_DI::CreateTexture(u32 IndexToCreate,u32 ColorMode) { glGenTextures(1, &AllRef[IndexToCreate].OGLRef); //GLenum truffe = glGetError(); //if (truffe != GL_NO_ERROR) // MessageBox(NULL, "EEEERRRRR", "YouUp", MB_OK | MB_ICONWARNING); //} AllRef[IndexToCreate].ColorMode = ColorMode; // RGBA AllRef[IndexToCreate].ClampMode = 0; AllRef[IndexToCreate].LayerIndex = -1; AllRef[IndexToCreate].CacheCounter = 0; AllRef[IndexToCreate].LastHash = -1; AllRef[IndexToCreate].IsMipMapped = 1; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, AllRef[IndexToCreate].OGLRef); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER,0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//*/ switch (ColorMode) { case 1://glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE, 0 , 0 , GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY), 0);break; for (u32 Clk = 0 ; (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX)>>Clk > 0) && (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY)>>Clk > 0); Clk ++) glTexImage2D(GL_TEXTURE_2D, Clk , GL_LUMINANCE, GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY)>>Clk, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; default://glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, 0 , 0 , GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY), 0);break; for (u32 Clk = 0 ; (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX)>>Clk > 0) && (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY)>>Clk > 0); Clk ++) glTexImage2D(GL_TEXTURE_2D, Clk , GL_RGBA, GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX)>>Clk, GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY)>>Clk, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; } /* Fill in black */ if ( (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX) > 16) && (GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY) > 16) ) { u32 BlackMap[16 * 16]; memset(BlackMap,0,sizeof(BlackMap)); for (u32 XC = 0 ; XC < GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX) ; XC += 16) for (u32 YC = 0 ; YC < GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY) ; YC += 16) for (u32 Mp = 0 ; Mp < 8 ; Mp++) glTexSubImage2D(GL_TEXTURE_2D,Mp ,XC>>Mp ,YC>>Mp ,16>>Mp ,16>>Mp ,GL_RGBA,GL_UNSIGNED_BYTE,BlackMap); } //*/ UpdateTexture_BM_2_HW(IndexToCreate); } u32 OGL_DI::CreateTexture(MAP *pExternalReferenceRGBA,u32 ColorMode, bool forceCreation) { u32 Index = GetTexFreeIndex(); if (Index == -1) return -1; AllRef[Index].pExtRef = pExternalReferenceRGBA; if (forceCreation) { CreateTexture(Index,ColorMode); } else { AllRef[Index].CacheCounter = 5001; AllRef[Index].OGLRef = -2; } return Index; } u32 OGL_DI::CreateLayerTexture(MAP *pExternalReferenceRGBA,u32 LayerIndex) { u32 Index = GetTexFreeIndex(); if (Index == -1) return -1; AllRef[Index].CacheCounter = 0; AllRef[Index].pExtRef = pExternalReferenceRGBA; AllRef[Index].ColorMode = 0; // RGBA ValidateLayer(LayerIndex % NUMBER_OF_OGL_WORKING_REF); AllRef[Index].OGLRef = OGLWorkingRef[LayerIndex % NUMBER_OF_OGL_WORKING_REF]; AllRef[Index].ClampMode = 0; AllRef[Index].LayerIndex = LayerIndex; AllRef[Index].IsMipMapped = 0; return Index; } void OGL_DI::DestroyLayerTexture(u32 TextureIndex) { if ((TextureIndex != -1) && (AllRef[TextureIndex].OGLRef != -1)) { AllRef[TextureIndex].OGLRef = -1; // NOT DESTROY IN HARD !! } }; void OGL_DI::DestroyTexture(u32 TextureIndex) { if ((TextureIndex != -1) && (AllRef[TextureIndex].OGLRef != -1)) { glDeleteTextures(1, &AllRef[TextureIndex].OGLRef); AllRef[TextureIndex].OGLRef = -1; AllRef[TextureIndex].LastHash = -1; // AllRef[TextureIndex].pExtRef = NULL; } }; void OGL_DI::Setexture(u32 TextureIndex,float *UVMatrix) { /* if not used since a long time */ if ((TextureIndex != -1) && (AllRef[TextureIndex].CacheCounter > 5000)) { /* Then Reload it */ CreateTexture(TextureIndex,AllRef[TextureIndex].ColorMode); } if ((TextureIndex == -1) || (AllRef[TextureIndex].OGLRef == -1)) { glDisable(GL_TEXTURE_2D); ulCurrentTexture = -1; } else { float FakeUVMatrix[] = {1,0,0,1,0,0}; float BorderCorectionUVMatrix[] = {1,0,0,1,0,0}; if (UVMatrix == NULL) UVMatrix = (float*)&FakeUVMatrix; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef); AllRef[TextureIndex].CacheCounter = 0; if (((FrameNumber + TextureIndex ) & 8191) == 0) { GLint param; glGetTexParameteriv(GL_TEXTURE_2D ,GL_TEXTURE_RESIDENT,¶m); if (!param) { // Force Re-create glDeleteTextures(1, &AllRef[TextureIndex].OGLRef); AllRef[TextureIndex].LastHash = -1; CreateTexture(TextureIndex,0); glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef); } }//*/ ulCurrentTexture = TextureIndex; if (ulCurrentTexture != -1) { float CX,CY,YC; //(float)AllRef[ulCurrentTexture].pExtRef->SX / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX) CX = (float)AllRef[ulCurrentTexture].pExtRef->SX / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX); CY = (float)AllRef[ulCurrentTexture].pExtRef->SY / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SY); if ((CX != 1.0f) || (CY != 1.0f)) { float BCX,BCY; memcpy(BorderCorectionUVMatrix,UVMatrix,sizeof(BorderCorectionUVMatrix)); if (CX != 1.0f) { BCX = ((float)(AllRef[ulCurrentTexture].pExtRef->SX - 1) / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX)) / CX; BorderCorectionUVMatrix[0] *= BCX; BorderCorectionUVMatrix[2] *= BCX; BorderCorectionUVMatrix[4] *= BCX; } if (CY != 1.0f) { BCY = ((float)(AllRef[ulCurrentTexture].pExtRef->SY - 1) / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SY)) / CY; BorderCorectionUVMatrix[1] *= BCY; BorderCorectionUVMatrix[3] *= BCY; BorderCorectionUVMatrix[5] *= BCY; UVMatrix = (float *)BorderCorectionUVMatrix; } } GLfloat Persp2[16]= { CX*UVMatrix[0], CY*UVMatrix[1], 0, 0, CX*UVMatrix[2], CY*UVMatrix[3], 0, 0, 0, 0, 1, 0, CX*UVMatrix[4], CY*UVMatrix[5], 0, 1, }; SetMatrix(GL_TEXTURE,Persp2); } } } void OGL_DI::Perspective(float f) { float AX,AY; AX = ActivRect.right - ActivRect.left; AY = ActivRect.bottom - ActivRect.top; if (f < 0.0f) { GLfloat _4x4[16] = { -2.0f/f,0, 0, 0, 0, -2.0f/f*AX/AY, 0, 0, 0, 0, -0.1, 0, 0, 0, 0, 1, }; SetMatrix(GL_PROJECTION,_4x4); } else { GLfloat _4x4[16] = { f, 0, 0, 0, 0,f*AX/AY, 0, 0, 0, 0, 0, 1, 0, 0, 0.1, 0, }; SetMatrix(GL_PROJECTION,_4x4); } fFocUsed = f; } void OGL_DI::Holographic(Vector *pUP,float wx) { float AX,AY; float f; AX = ActivRect.right - ActivRect.left; AY = ActivRect.bottom - ActivRect.top; f = pUP->z / wx ; float Xp = (pUP->x ); float Yp = (pUP->y ); float Zp = (-pUP->z ); GLfloat _4x4[16] = { -f, 0, 0, 0, 0, -f*AX/AY, 0, 0, Xp/wx, Yp/wx*AX/AY, -pUP->z * 0.025, 1, 0, 0, 0.1, pUP->z, }; SetMatrix(GL_PROJECTION,_4x4); } #define MACRO_OrthoMat(l,r,b,t,n,f)\ {\ 2/(r-l),0, 0, -(r+l)/(r-l),\ 0, 2/(t-b),0, -(t+b)/(t-b),\ 0, 0, -2/(f-n), -(f+n)/(f-n),\ 0, 0, 0, 1,\ }; void OGL_DI::Ortho() // PIXEL mode ortho (ex Draw point 10,10 mean pixel 10,10) { float AreaX,AreaY; AreaX = CurrentRect.right - CurrentRect.left; AreaY = CurrentRect.bottom - CurrentRect.top; GLfloat _4x4[16] = MACRO_OrthoMat((-1.0), (1.0f), (AreaY/AreaX), (-AreaY/AreaX), (-1.0), (1.0)); SetMatrix(GL_PROJECTION,_4x4); fFocUsed = 0; } void OGL_DI::Clear(u32 Color) { MousePickingCurrentZ = -100000000.0f; glDepthMask(GL_TRUE); if (QuadHideColor & 1) glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,(QuadHideColor & 2) ? GL_FALSE : GL_TRUE); else glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, (QuadHideColor & 2) ? GL_FALSE : GL_TRUE); glClearDepth(0); glClearColor((float)((Color>>0)&0xff)/256.0f,(float)((Color>>8)&0xff)/256.0f,(float)((Color>>16)&0xff)/256.0f,(float)((Color>>24)&0xff)/256.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); ZBIas = 1.0f; FORCE_RENDER_FLAG |= 4; }; void OGL_DI::ClearZ() { MousePickingCurrentZ = -100000000.0f; glDepthMask(GL_TRUE); glClearDepth(0); glClear(GL_DEPTH_BUFFER_BIT); ZBIas = 1.0f; FORCE_RENDER_FLAG |= 4; }; void OGL_DI::Matrix(MATRIX *MatrixToSet) { if (MatrixToSet) { GLfloat _4x4[16]; memset(_4x4,0,sizeof(_4x4)); *(Vector *)&_4x4[0] = MatrixToSet->I; *(Vector *)&_4x4[4] = MatrixToSet->J; *(Vector *)&_4x4[8] = MatrixToSet->K; *(Vector *)&_4x4[12] = MatrixToSet->T; _4x4[15] = 1.0f; SetMatrix(GL_MODELVIEW,_4x4); } else { SetMatrix(GL_MODELVIEW,NULL); } } #define ENABLE(a,b) { b!=0 ? glEnable(a) : glDisable(a); } //#pragma optimize ("",off) void OGL_DI::SetRS(RS *RM1,u32 TextureIndex) { RS LocalRM; START_RASTER(SetRenderState); LocalRM = *RM1; if (MotherClass) { u8 *pBase,*pEnd,*pOr,*pAnd; pBase = (u8*)&LocalRM; pEnd = pBase + sizeof(RS); pOr = (u8*)&(MotherClass->MaterialOr.RenderState); pAnd = (u8*)&(MotherClass->MaterialAnd.RenderState); while (pBase < pEnd) *(pBase++) = (*(pBase) & *(pAnd++)) | *(pOr++); TextureIndex = ( TextureIndex & MotherClass->MaterialAnd.TextureMediaIndex) | MotherClass->MaterialOr.TextureMediaIndex; } if (FORCE_RENDER_FLAG & (4+8)) { LastRS = LocalRM; u8 Xor,*pBase,*pEnd; pBase = (u8*)&LastRS; pEnd = pBase + sizeof(RS); while (pBase < pEnd) *(pBase++) ^= 0xff; FORCE_RENDER_FLAG &= ~4; } if (LastRS.BACKFACE != LocalRM.BACKFACE) { if (LocalRM.BACKFACE) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } } if (FORCE_RENDER_FLAG & 2) { ENABLE(GL_DEPTH_TEST,0); } else { if (LastRS.NOZTEST != LocalRM.NOZTEST) ENABLE(GL_DEPTH_TEST,(LocalRM.NOZTEST^1)); } if (LastRS.WIRED != LocalRM.WIRED) { LocalRM.WIRED == 0 ? glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if (FORCE_RENDER_FLAG & 1) glDepthMask(GL_FALSE); else { if (LastRS.NOZWRITE != LocalRM.NOZWRITE) LocalRM.NOZWRITE == 0 ? glDepthMask(GL_TRUE) : glDepthMask(GL_FALSE); } if (LastRS.BACKFACE_INVERT != LocalRM.BACKFACE_INVERT) { LocalRM.BACKFACE_INVERT == 0 ? glCullFace(GL_FRONT) : glCullFace(GL_BACK); } if (LastRS.TEXTURED != LocalRM.TEXTURED) ENABLE(GL_TEXTURE_2D,LocalRM.TEXTURED); if (LastRS.BlendingMode != LocalRM.BlendingMode) { if (LocalRM.BlendingMode) { glEnable(GL_BLEND); switch (LocalRM.BlendingMode) { case 1://Alpha //LocalRM.AlphaThreshold = 5; if (LocalRM.INVERTALPHA) glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA); else glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); break; case 2://add glBlendFunc(GL_ONE,GL_ONE); break; case 3://Alpha premult if (LocalRM.INVERTALPHA) glBlendFunc(GL_ONE,GL_SRC_ALPHA); else glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); break; case 4://PREVIOUS ALPHA if (LocalRM.INVERTALPHA) glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA); else glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA); break; case 5://Multiply glBlendFunc(GL_DST_COLOR,GL_ZERO); break; case 6://Multiply Invert glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR); break; case 7://Multiply x2 glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR); break; } }else { glDisable(GL_BLEND); glBlendFunc(GL_ONE,GL_ZERO); } } if (LastRS.AlphaThreshold != LocalRM.AlphaThreshold) { if (LocalRM.AlphaThreshold) { glAlphaFunc(GL_GEQUAL,(float)LocalRM.AlphaThreshold / 255.0f); glEnable(GL_ALPHA_TEST); } else glDisable(GL_ALPHA_TEST); } if (/*LocalRM.AnimFPS && */(LocalRM.AnimNbX != 1 || LocalRM.AnimNbY != 1)) { float NewUVMatrix[6]; u16 TextureIdx, XTextureIdx, YTextureIdx; NewUVMatrix[0] = LocalRM.UVMATRIX[0]/LocalRM.AnimNbX; NewUVMatrix[1] = LocalRM.UVMATRIX[1]/LocalRM.AnimNbX; NewUVMatrix[2] = LocalRM.UVMATRIX[2]/LocalRM.AnimNbY; NewUVMatrix[3] = LocalRM.UVMATRIX[3]/LocalRM.AnimNbY; if (LocalRM.AnimTime) { TextureIdx = ((int)((double)(timeGetTime() - LocalRM.AnimTime) *LocalRM.AnimFPS / 1000)) % (LocalRM.AnimNbX*LocalRM.AnimNbY); XTextureIdx = TextureIdx % LocalRM.AnimNbX; YTextureIdx = TextureIdx / LocalRM.AnimNbX; YTextureIdx = LocalRM.AnimNbY - YTextureIdx - 1; } else { XTextureIdx = 0; YTextureIdx = LocalRM.AnimNbY - 1; } NewUVMatrix[4] = (LocalRM.UVMATRIX[0] + LocalRM.UVMATRIX[1])*XTextureIdx/LocalRM.AnimNbX + LocalRM.UVMATRIX[4]; NewUVMatrix[5] = (LocalRM.UVMATRIX[2] + LocalRM.UVMATRIX[3])*YTextureIdx/LocalRM.AnimNbY + LocalRM.UVMATRIX[5]; Setexture(TextureIndex, NewUVMatrix); } else Setexture(TextureIndex,LocalRM.UVMATRIX); if (LocalRM.TEXTUREREPEAT_U) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); if (LocalRM.TEXTUREREPEAT_V) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if (LocalRM.TEXTUREBILINEAR) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if ((TextureIndex == -1) || AllRef[TextureIndex].IsMipMapped) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if ((TextureIndex == -1) || AllRef[TextureIndex].IsMipMapped) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } } GLenum ZFonc = GL_GEQUAL; u32 ZNeedUpdate = 0; if (LastRS.ZEQUAL != LocalRM.ZEQUAL) { ZNeedUpdate = 1; if (LocalRM.ZEQUAL) ZFonc = GL_EQUAL; } if (LastRS.ZPASS != LocalRM.ZPASS) { ZNeedUpdate = 1; if (LocalRM.ZPASS) ZFonc = GL_ALWAYS; } if (ZNeedUpdate) glDepthFunc(ZFonc); if (LastRS.HIDECOLOR != LocalRM.HIDECOLOR) { if (LocalRM.HIDECOLOR) glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,LocalRM.HIDEALPHA ? GL_FALSE : GL_TRUE); else glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,LocalRM.HIDEALPHA ? GL_FALSE : GL_TRUE); } //if (LastRS.MappingMode != LocalRM.MappingMode) { switch (LocalRM.MappingMode) { default: if (LastRS.MappingMode != 0) { glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q); } break; case 1: //chrome { /*GLfloat _4x4_Persp[16]; GLfloat _4x4_Model[16]; GLfloat _4x4_Texture[16]; glGetFloatv(GL_PROJECTION_MATRIX,_4x4_Persp); glGetFloatv(GL_MODELVIEW_MATRIX,_4x4_Model); glGetFloatv(GL_TEXTURE_MATRIX,_4x4_Texture); _4x4_Model[12] = _4x4_Model[13] = _4x4_Model[14] = 0.0f; _4x4_Model[14] = 0.0f; glMatrixMode(GL_TEXTURE); glTranslatef(0.5,0.5,-1 ); glMultMatrixf( _4x4_Model ); glScalef(-0.5,-0.5,-0.5); /**/ GLfloat _4x4_Persp[16]; GLfloat _4x4_Model[16]; GLfloat _4x4_Texture[16]; GetMatrix(GL_PROJECTION_MATRIX,_4x4_Persp); GetMatrix(GL_MODELVIEW_MATRIX,_4x4_Model); GetMatrix(GL_TEXTURE_MATRIX,_4x4_Texture); _4x4_Model[12] = _4x4_Model[13] = _4x4_Model[14] = 0.0f; _4x4_Model[14] = 0.0f; glMatrixMode(GL_TEXTURE); glTranslatef(0.5,0.5,-1 ); glMultMatrixf( _4x4_Model ); glScalef(-0.5,-0.5,-0.5); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q);//*/ } break; case 2: //Planar Z { GLfloat P0123_S[] = {1,0,0,0}; GLfloat P0123_T[] = {0,1,0,0}; GLfloat P0123_R[] = {0,0,1,0}; GLfloat P0123_Q[] = {0,0,0,1}; glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGenfv(GL_S,GL_OBJECT_PLANE,(GLfloat *)P0123_S); glTexGenfv(GL_T,GL_OBJECT_PLANE,(GLfloat *)P0123_T); glTexGenfv(GL_R,GL_OBJECT_PLANE,(GLfloat *)P0123_R); glTexGenfv(GL_Q,GL_OBJECT_PLANE,(GLfloat *)P0123_Q); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_Q); } break; case 3: //Screen { GLfloat P0123_S[] = {1,0,0,0}; GLfloat P0123_T[] = {0,1,0,0}; GLfloat P0123_R[] = {0,0,1,0}; GLfloat P0123_Q[] = {0,0,0,1}; glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGenfv(GL_S,GL_OBJECT_PLANE,(GLfloat *)P0123_S); glTexGenfv(GL_T,GL_OBJECT_PLANE,(GLfloat *)P0123_T); glTexGenfv(GL_R,GL_OBJECT_PLANE,(GLfloat *)P0123_R); glTexGenfv(GL_Q,GL_OBJECT_PLANE,(GLfloat *)P0123_Q); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_Q); GLfloat _4x4_Persp[16]; GLfloat _4x4_Model[16]; GLfloat _4x4_Texture[16]; GetMatrix(GL_PROJECTION_MATRIX,_4x4_Persp); GetMatrix(GL_MODELVIEW_MATRIX,_4x4_Model); GetMatrix(GL_TEXTURE_MATRIX,_4x4_Texture); glMatrixMode(GL_TEXTURE); // glLoadIdentity(); glTranslatef(0.5,0.5,0); if (TextureIndex != -1) glScalef(0.5f, 0.5f * ((float)FB_SY / (float)FB_SX) * (float)AllRef[TextureIndex].pExtRef->SX/(float)AllRef[TextureIndex].pExtRef->SY,1); glMultMatrixf( _4x4_Persp ); glMultMatrixf( _4x4_Model ); } break; } }//*/ CurrentRS = LocalRM; LastRS = LocalRM; if (FORCE_RENDER_FLAG & 2) { LastRS.NOZTEST = 1; } if (FORCE_RENDER_FLAG & 1) { LastRS.NOZWRITE = 1; } STOP_RASTER(SetRenderState); } void OGL_DI::GetMatrix(u32 Mode,float *pDest) { switch (Mode) { case 0://Projection case GL_PROJECTION: case GL_PROJECTION_MATRIX: memcpy(pDest,OPTIM_4x4_Persp,sizeof(OPTIM_4x4_Persp)); break; case 1://Model case GL_MODELVIEW: case GL_MODELVIEW_MATRIX: memcpy(pDest,OPTIM_4x4_Model,sizeof(OPTIM_4x4_Model)); break; case 2://Texture case GL_TEXTURE: case GL_TEXTURE_MATRIX: memcpy(pDest,OPTIM_4x4_Texture,sizeof(OPTIM_4x4_Texture)); break; } } void OGL_DI::SetMatrix(u32 Mode,float *pDest) { float Identity[16]; if (pDest == NULL) { memset(Identity,0,sizeof(Identity)); Identity[0] = Identity[5] = Identity[10] = Identity[15] = 1.0f; pDest = Identity; } switch (Mode) { case 0://Projection case GL_PROJECTION:// case GL_PROJECTION_MATRIX: memcpy(OPTIM_4x4_Persp,pDest,sizeof(OPTIM_4x4_Persp)); glMatrixMode(GL_PROJECTION); glLoadMatrixf(pDest); break; case 1://Model case GL_MODELVIEW:// case GL_MODELVIEW_MATRIX: memcpy(OPTIM_4x4_Model,pDest,sizeof(OPTIM_4x4_Model)); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(pDest); break; case 2://Texture case GL_TEXTURE:// case GL_TEXTURE_MATRIX: memcpy(OPTIM_4x4_Texture,pDest,sizeof(OPTIM_4x4_Texture)); glMatrixMode(GL_TEXTURE); glLoadMatrixf(pDest); break; } }