00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CATOverlayOpenGL.h"
00014 #include "CATString.h"
00015
00016 #ifdef CAT_CONFIG_WIN32
00017 #include <gl/gl.h>
00018
00019
00020
00021 CATINTERCEPT_DLL_TABLE_ENTRY CATOverlayOpenGL::kOpenGLInterceptTable[] =
00022 {
00023 { "wglSwapBuffers", CATOverlayOpenGL::OnSwapBuffers, 5},
00024
00025
00026 {0,0,0}
00027 };
00028
00029 CATOverlayOpenGL::CATOverlayOpenGL()
00030 : CATOverlay()
00031 {
00032 fTexScaleX = 1.0f;
00033 fTexScaleY = 1.0f;
00034 fTexture = 0;
00035 fOpenGLDLL = ::LoadLibrary(L"opengl32.dll");
00036 }
00037
00038 CATOverlayOpenGL::~CATOverlayOpenGL()
00039 {
00040 RestoreAll();
00041 if (fOpenGLDLL)
00042 FreeLibrary(fOpenGLDLL);
00043 fOpenGLDLL = 0;
00044 }
00045
00046
00047 void CATOverlayOpenGL::DrawToScene(HDC hdc)
00048 {
00049
00050 fLock.Wait();
00051
00052
00053 CATInt32 retVals[4];
00054 glGetIntegerv(GL_VIEWPORT,&retVals[0]);
00055 fRect.Set(retVals[0],retVals[1],retVals[2]+retVals[0],retVals[3]+retVals[1]);
00056
00057
00058 if (!fOverlay)
00059 {
00060
00061 if (fOverlayDirty)
00062 {
00063 if (fTexture)
00064 glDeleteTextures(1,&fTexture);
00065 fTexture = 0;
00066 fOverlayDirty = false;
00067 }
00068 fLock.Release();
00069 return;
00070 }
00071
00072 if (fOverlayDirty)
00073 {
00074 if (fTexture)
00075 glDeleteTextures(1,&fTexture);
00076 fTexture = 0;
00077
00078
00079 CATInt32 tw = 2;
00080 while (tw < fOverlay->Width())
00081 tw*= 2;
00082 CATInt32 th = 2;
00083 while (th < fOverlay->Height())
00084 th*=2;
00085
00086
00087 glGenTextures(1,&fTexture);
00088 glBindTexture(GL_TEXTURE_2D,fTexture);
00089 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
00091
00092
00093 CATUInt8* buffer = new CATUInt8[tw*th*4];
00094 CATUInt8* srcBuf = fOverlay->GetRawDataPtr();
00095 CATUInt32 imgWidth = fOverlay->Width();
00096 memset(buffer,0,tw*th*4);
00097 for (int y = 0; y < fOverlay->Height(); y++)
00098 {
00099 memcpy(&buffer[y*tw*4],&srcBuf[y*imgWidth*4],4*imgWidth);
00100 }
00101
00102
00103 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,tw,th,0,GL_RGBA,GL_UNSIGNED_BYTE,buffer);
00104
00105
00106 fTexScaleX = (CATFloat32)fOverlay->Width() / (CATFloat32)tw;
00107 fTexScaleY = (CATFloat32)fOverlay->Height() / (CATFloat32)th;
00108
00109 delete [] buffer;
00110 }
00111
00112
00113 glPushAttrib(GL_ALL_ATTRIB_BITS);
00114
00115
00116
00117 glMatrixMode(GL_PROJECTION);
00118 glPushMatrix();
00119 glLoadIdentity();
00120 glOrtho(0, fRect.Width(), fRect.Height(), 0, -1, 1);
00121 glMatrixMode(GL_MODELVIEW);
00122 glPushMatrix();
00123 glLoadIdentity();
00124
00125
00126 glDisable(GL_DEPTH_TEST);
00127 glDisable(GL_LIGHTING);
00128 glDisable(GL_TEXTURE_1D);
00129 glShadeModel(GL_FLAT);
00130 glEnable (GL_TEXTURE_2D);
00131
00132 glBlendFunc(GL_ONE, GL_ZERO);
00133 glEnable(GL_BLEND);
00134
00135
00136 CATFloat32 scaleX = (CATFloat32)fRect.Width() / (CATFloat32)this->fRefScreenWidth;
00137 CATFloat32 scaleY = (CATFloat32)fRect.Height() / (CATFloat32)this->fRefScreenHeight;
00138
00139 if (fKeepAspect)
00140 {
00141 scaleY = scaleX = CATMin(scaleX,scaleY);
00142 }
00143
00144
00145 glBegin(GL_QUADS);
00146 {
00147 glColor4f (1.0f,1.0f,1.0f, 1.0f);
00148
00149 glTexCoord2f(0, 0);
00150
00151 glVertex3f( fOverlayRect.left * scaleX,
00152 fOverlayRect.top * scaleY, -1);
00153
00154 glTexCoord2f(fTexScaleX, 0);
00155
00156 glVertex3f( fOverlayRect.right * scaleX,
00157 fOverlayRect.top * scaleY, -1);
00158
00159 glTexCoord2f(fTexScaleX, fTexScaleY);
00160
00161 glVertex3f( fOverlayRect.right * scaleX,
00162 fOverlayRect.bottom * scaleY, -1);
00163
00164 glTexCoord2f(0, fTexScaleY);
00165
00166 glVertex3f( fOverlayRect.left * scaleX,
00167 fOverlayRect.bottom * scaleY, -1);
00168 }
00169 glEnd();
00170 glFlush();
00171
00172
00173
00174 glPopMatrix();
00175 glMatrixMode(GL_PROJECTION);
00176 glPopMatrix();
00177 glPopAttrib();
00178
00179 fLock.Release();
00180 }
00181
00182
00183 CATResult CATOverlayOpenGL::HookFunctions()
00184 {
00185 return this->InterceptDLL(fOpenGLDLL,&kOpenGLInterceptTable[0],this);
00186 }
00187
00188 CATHOOKFUNC void CATOverlayOpenGL::OnSwapBuffers( CATHOOK* hookInst,
00189 HDC hdc)
00190 {
00191 CATHOOK_PROLOGUE(1);
00192 ((CATOverlayOpenGL*)(hookInst->InterceptObj))->DrawToScene(hdc);
00193 CATHOOK_CALLORIGINAL_WINAPI(hookInst, 1);
00194 CATHOOK_EPILOGUE_WINAPI(1);
00195 }
00196
00197 #endif // CAT_CONFIG_WIN32