![]() |
TX Library Help – Version: 00173a, Revision: 174
|
00001 //{================================================================================================================ 00013 // $Copyright: (C) Ded (Ilya Dedinsky, http://txlib.ru) <mail@txlib.ru> $ 00014 //}================================================================================================================ 00015 00016 #include "TXLib.h" 00017 00018 #include "GL\gl.h" 00019 #include "GL\glu.h" 00020 00021 #if !defined (_TX_VER) || (_TX_VER < 0x173a0165) 00022 #error Must use TXLib.h version >= 1.73 and revision >= 165 to compile this. -- Ded 00023 #endif 00024 00025 //================================================================================================================= 00026 //{ OpenGL support 00028 //================================================================================================================= 00029 00030 typedef float vec4f[4]; 00031 00032 const vec4f TX_GL_BLACK = {0, 0, 0, 1}, 00033 TX_GL_RED = {1, 0, 0, 1}, 00034 TX_GL_GREEN = {0, 1, 0, 1}, 00035 TX_GL_BLUE = {0, 0.25, 1, 1}, 00036 TX_GL_WHITE = {1, 1, 1, 1}; 00037 00038 HGLRC txglCreateContext (HDC dc); 00039 bool txglDeleteContext (HGLRC rc); 00040 bool txglSetDefaults(); 00041 void txglSwapBuffers(); 00042 00043 void txglClear (double red, double green, double blue, double alpha = 0); 00044 void txgluSphere (double radius, int slices = 100, int stacks = 100); 00045 void txgluDisk (double innerRadius, double outerRadius, int slices = 100, int loops = 100); 00046 void txgluCylinder (double baseRadius, double topRadius, double height, int slices = 100, int stacks = 100); 00047 void txglTextOut (double x, double y, const char* text); 00048 00049 bool txglLight (int light, double x, double y, double z, 00050 double ambient, double diffuse, double specular); 00051 bool txglMaterial (double specular, double emittance, double shining); 00052 bool txglSetCamera (POINT size, bool perspective = true); 00053 00054 //----------------------------------------------------------------------------------------------------------------- 00055 00056 namespace { namespace TX { namespace Win32 { 00057 00058 _TX_DLLIMPORT ("OpenGL32", void, glBlendFunc, (int sFactor, int dFactor)); 00059 _TX_DLLIMPORT ("OpenGL32", void, glClear, (GLbitfield mask)); 00060 _TX_DLLIMPORT ("OpenGL32", void, glClearAccum, (float red, float green, float blue, float alpha)); 00061 _TX_DLLIMPORT ("OpenGL32", void, glClearColor, (float red, float green, float blue, float alpha)); 00062 _TX_DLLIMPORT ("OpenGL32", void, glClearDepth, (double depth)); 00063 _TX_DLLIMPORT ("OpenGL32", void, glClearIndex, (float color)); 00064 _TX_DLLIMPORT ("OpenGL32", void, glClearStencil, (int stencil)); 00065 _TX_DLLIMPORT ("OpenGL32", void, glColor3d, (double red, double green, double blue)); 00066 _TX_DLLIMPORT ("OpenGL32", void, glColor3dv, (const double* color)); 00067 _TX_DLLIMPORT ("OpenGL32", void, glColor4d, (double red, double green, double blue, double alpha)); 00068 _TX_DLLIMPORT ("OpenGL32", void, glColor4dv, (const double* color)); 00069 _TX_DLLIMPORT ("OpenGL32", void, glDepthFunc, (int func)); 00070 _TX_DLLIMPORT ("OpenGL32", void, glDisable, (int cap)); 00071 _TX_DLLIMPORT ("OpenGL32", void, glDisableClientState,(int array)); 00072 _TX_DLLIMPORT ("OpenGL32", void, glEnable, (int cap)); 00073 _TX_DLLIMPORT ("OpenGL32", void, glEnableClientState, (int array)); 00074 _TX_DLLIMPORT ("OpenGL32", void, glHint, (int target, int mode)); 00075 _TX_DLLIMPORT ("OpenGL32", void, glLightfv, (int light, int name, const float* params)); 00076 _TX_DLLIMPORT ("OpenGL32", void, glLoadIdentity, (void)); 00077 _TX_DLLIMPORT ("OpenGL32", void, glMaterialf, (int face, int name, float param)); 00078 _TX_DLLIMPORT ("OpenGL32", void, glMaterialfv, (int face, int name, const float* params)); 00079 _TX_DLLIMPORT ("OpenGL32", void, glMatrixMode, (int mode)); 00080 _TX_DLLIMPORT ("OpenGL32", void, glOrtho, (double left, double right, double bottom, double top, double zNear, double zFar)); 00081 _TX_DLLIMPORT ("OpenGL32", void, glPixelStorei, (int pName, int param)); 00082 _TX_DLLIMPORT ("OpenGL32", void, glPixelZoom, (float xFactor, float yFactor)); 00083 _TX_DLLIMPORT ("OpenGL32", void, glPointSize, (float size)); 00084 _TX_DLLIMPORT ("OpenGL32", void, glShadeModel, (int mode)); 00085 _TX_DLLIMPORT ("OpenGL32", void, glCallLists, (unsigned size, int type, const void* lists)); 00086 _TX_DLLIMPORT ("OpenGL32", void, glDeleteLists, (unsigned list, int range)); 00087 _TX_DLLIMPORT ("OpenGL32", void, glFlush, (void)); 00088 _TX_DLLIMPORT ("OpenGL32", void, glListBase, (unsigned base)); 00089 _TX_DLLIMPORT ("OpenGL32", void, glMateriali, (int face, int name, int param)); 00090 _TX_DLLIMPORT ("OpenGL32", void, glRasterPos2d, (double x, double y)); 00091 _TX_DLLIMPORT ("OpenGL32", void, glRotated, (double angle, double x, double y, double z)); 00092 _TX_DLLIMPORT ("OpenGL32", void, glTranslated, (double x, double y, double z)); 00093 _TX_DLLIMPORT ("OpenGL32", void, glViewport, (int x, int y, int width, int height)); 00094 _TX_DLLIMPORT ("OpenGL32", HGLRC, wglCreateContext, (HDC dc)); 00095 _TX_DLLIMPORT ("OpenGL32", bool, wglDeleteContext, (HGLRC context)); 00096 _TX_DLLIMPORT ("OpenGL32", bool, wglMakeCurrent, (HDC dc, HGLRC context)); 00097 _TX_DLLIMPORT ("OpenGL32", bool, wglUseFontBitmapsA, (HDC dc, DWORD first, DWORD count, DWORD listBase)); 00098 00099 _TX_DLLIMPORT ("GLU32", GLUquadric*, gluNewQuadric, (void)); 00100 _TX_DLLIMPORT ("GLU32", void, gluDeleteQuadric, (GLUquadric* state)); 00101 _TX_DLLIMPORT ("GLU32", void, gluCylinder, (GLUquadric *obj, double baseRadius, double topRadius, double height, int slices, int stacks)); 00102 _TX_DLLIMPORT ("GLU32", void, gluDisk, (GLUquadric* obj, double innerRadius, double outerRadius, int slices, int loops)); 00103 _TX_DLLIMPORT ("GLU32", void, gluSphere, (GLUquadric* obj, double radius, int slices, int stacks)); 00104 _TX_DLLIMPORT ("GLU32", void, gluLookAt, (double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ)); 00105 _TX_DLLIMPORT ("GLU32", void, gluPerspective, (double fovy, double aspect, double zNear, double zFar)); 00106 00107 _TX_DLLIMPORT ("GDI32", int, ChoosePixelFormat, (HDC dc, const PIXELFORMATDESCRIPTOR* pPfd)); 00108 _TX_DLLIMPORT ("GDI32", int, DescribePixelFormat, (HDC dc, int numPfd, unsigned szPfd, const PIXELFORMATDESCRIPTOR* pfd)); 00109 _TX_DLLIMPORT ("GDI32", bool, SetPixelFormat, (HDC dc, int numPfd, const PIXELFORMATDESCRIPTOR* pfd)); 00110 _TX_DLLIMPORT ("GDI32", bool, SwapBuffers, (HDC dc)); 00111 00112 }}} 00113 00114 //================================================================================================================= 00115 00116 HGLRC txglCreateContext (HDC dc) 00117 { 00118 PIXELFORMATDESCRIPTOR pfd = {0}; 00119 00120 pfd.nSize = (WORD) sizeof (pfd); 00121 pfd.nVersion = 1; 00122 00123 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 00124 00125 pfd.iLayerType = PFD_MAIN_PLANE; 00126 pfd.iPixelType = PFD_TYPE_RGBA; 00127 pfd.cColorBits = 24; 00128 pfd.cDepthBits = 32; 00129 00130 pfd.cAuxBuffers = 0; 00131 00132 int index = Win32::ChoosePixelFormat (dc, &pfd); 00133 00134 if (!index) index = 1; 00135 00136 if (!Win32::DescribePixelFormat (dc, index, sizeof (pfd), &pfd)) return 0; 00137 if (!Win32::SetPixelFormat (dc, index, &pfd)) return 0; 00138 00139 HGLRC rc = Win32::wglCreateContext (dc); rc asserted; 00140 Win32::wglMakeCurrent (dc, rc) asserted; 00141 00142 txglSetDefaults(); 00143 txglSetCamera (txGetExtent (dc), false); 00144 00145 return rc; 00146 } 00147 00148 //----------------------------------------------------------------------------------------------------------------- 00149 00150 bool txglDeleteContext (HGLRC rc) 00151 { 00152 if (!rc) return false; 00153 00154 Win32::glDeleteLists (0, INT_MAX); 00155 00156 Win32::wglMakeCurrent (NULL, NULL) asserted; 00157 Win32::wglDeleteContext (rc) asserted; 00158 00159 return true; 00160 } 00161 00162 //----------------------------------------------------------------------------------------------------------------- 00163 00164 bool txglSetDefaults() 00165 { 00166 Win32::glEnable (GL_DEPTH_TEST); !tx_glGetError() asserted; 00167 Win32::glEnable (GL_ALPHA_TEST); !tx_glGetError() asserted; 00168 Win32::glEnable (GL_BLEND); !tx_glGetError() asserted; 00169 Win32::glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); !tx_glGetError() asserted; 00170 00171 Win32::glEnable (GL_POINT_SMOOTH); !tx_glGetError() asserted; 00172 Win32::glEnable (GL_LINE_SMOOTH); !tx_glGetError() asserted; 00173 Win32::glShadeModel (GL_SMOOTH); !tx_glGetError() asserted; 00174 00175 Win32::glPixelStorei (GL_UNPACK_ALIGNMENT, 1); !tx_glGetError() asserted; 00176 00177 Win32::glPointSize (2); !tx_glGetError() asserted; 00178 00179 Win32::wglUseFontBitmaps (txDC(), 0, 256, 1000); 00180 Win32::glListBase (1000); 00181 00182 txglMaterial (0.6, 0.1, 0.5) asserted; 00183 00184 txglLight (0, 1000, 1000, 1000, 0.2, 0.4, 0.6) asserted; 00185 txglLight (1, -1000, 100, -500, 0.1, 0.4, 0.2) asserted; 00186 txglLight (2, 500, 500, -1000, 0.0, 0.8, 0.0) asserted; 00187 00188 return true; 00189 } 00190 00191 //----------------------------------------------------------------------------------------------------------------- 00192 00193 bool txglLight (int light, double x, double y, double z, 00194 double ambient, double diffuse, double specular) 00195 { 00196 Win32::glEnable (GL_LIGHTING); !tx_glGetError() asserted; 00197 Win32::glEnable (GL_LIGHT0 + light); !tx_glGetError() asserted; 00198 00199 float pos[4] = {(float)x, (float)y, (float)z}; 00200 float amb[4] = {(float)ambient, (float)ambient, (float)ambient}; 00201 float diff[4] = {(float)diffuse, (float)diffuse, (float)diffuse}; 00202 float spec[4] = {(float)specular, (float)specular, (float)specular}; 00203 00204 Win32::glLightfv (GL_LIGHT0 + light, GL_POSITION, pos); !tx_glGetError() asserted; 00205 Win32::glLightfv (GL_LIGHT0 + light, GL_AMBIENT, amb); !tx_glGetError() asserted; 00206 Win32::glLightfv (GL_LIGHT0 + light, GL_DIFFUSE, diff); !tx_glGetError() asserted; 00207 Win32::glLightfv (GL_LIGHT0 + light, GL_SPECULAR, spec); !tx_glGetError() asserted; 00208 00209 return true; 00210 } 00211 00212 //----------------------------------------------------------------------------------------------------------------- 00213 00214 bool txglMaterial (double specular, double emittance, double shining) 00215 { 00216 Win32::glEnable (GL_COLOR_MATERIAL); !tx_glGetError() asserted; 00217 00218 float spec[4] = {(float)specular, (float)specular, (float)specular, 1.0f}; 00219 float emit[4] = {(float)emittance, (float)emittance, (float)emittance, 1.0f}; 00220 00221 Win32::glMateriali (GL_FRONT_AND_BACK, GL_SHININESS, (int) (shining*128)); !tx_glGetError() asserted; 00222 Win32::glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, spec); !tx_glGetError() asserted; 00223 Win32::glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emit); !tx_glGetError() asserted; 00224 00225 return true; 00226 } 00227 00228 //----------------------------------------------------------------------------------------------------------------- 00229 00230 bool txglSetCamera (POINT size, bool perspective /*= true*/) 00231 { 00232 Win32::glViewport (0, 0, size.x, size.y); !tx_glGetError() asserted; 00233 00234 Win32::glMatrixMode (GL_PROJECTION); !tx_glGetError() asserted; 00235 Win32::glLoadIdentity(); !tx_glGetError() asserted; 00236 00237 if (perspective) { Win32::gluPerspective (40, 1.0*size.x/size.y, 1, 1001); !tx_glGetError() asserted; } 00238 else { Win32::glOrtho (-size.x/2, size.x/2, -size.y/2, size.y/2, -1000, 1000); !tx_glGetError() asserted; } 00239 00240 Win32::gluLookAt (0,0,500, 0,0,0, 0,1,0); !tx_glGetError() asserted; 00241 00242 Win32::glMatrixMode (GL_MODELVIEW); !tx_glGetError() asserted; 00243 00244 return true; 00245 } 00246 00247 //----------------------------------------------------------------------------------------------------------------- 00248 00249 void txglClear (double red, double green, double blue, double alpha /*= 0*/) 00250 { 00251 Win32::glClearColor ((float) red, (float) green, (float) blue, (float) alpha); 00252 00253 Win32::glClear (GL_COLOR_BUFFER_BIT); 00254 Win32::glClear (GL_DEPTH_BUFFER_BIT); 00255 } 00256 00257 //----------------------------------------------------------------------------------------------------------------- 00258 00259 void txgluSphere (double radius, int slices /*= 100*/, int stacks /*= 100*/) 00260 { 00261 GLUquadricObj* obj = Win32::gluNewQuadric(); 00262 Win32::gluSphere (obj, radius, slices, stacks); 00263 Win32::gluDeleteQuadric (obj); 00264 } 00265 00266 //----------------------------------------------------------------------------------------------------------------- 00267 00268 void txgluCylinder (double baseRadius, double topRadius, double height, int slices /*= 100*/, int stacks /*= 100*/) 00269 { 00270 GLUquadricObj* obj = Win32::gluNewQuadric(); 00271 Win32::gluCylinder (obj, baseRadius, topRadius, height, slices, stacks); 00272 Win32::gluDeleteQuadric (obj); 00273 } 00274 00275 //----------------------------------------------------------------------------------------------------------------- 00276 00277 void txgluDisk (double innerRadius, double outerRadius, int slices /*= 100*/, int loops /*= 100*/) 00278 { 00279 GLUquadricObj* obj = Win32::gluNewQuadric(); 00280 Win32::gluDisk (obj, innerRadius, outerRadius, slices, loops); 00281 Win32::gluDeleteQuadric (obj); 00282 } 00283 00284 //----------------------------------------------------------------------------------------------------------------- 00285 00286 void txglTextOut (double x, double y, const char* text) 00287 { 00288 Win32::glRasterPos2d (x, y); 00289 Win32::glCallLists ((unsigned) strlen (text), GL_UNSIGNED_BYTE, text); 00290 } 00291 00292 //----------------------------------------------------------------------------------------------------------------- 00293 00294 void txglSwapBuffers() 00295 { 00296 Win32::glFlush(); 00297 Win32::SwapBuffers (Win32::wglGetCurrentDC()); 00298 } 00299 00300 //} 00301 //================================================================================================================= 00302 00303 void DrawBackgr (int mode); 00304 void DrawBackgr (int mode) 00305 { 00306 COLORREF white = RGB (24, 24, 32), red = RGB (32, 0, 0), blue = RGB ( 0, 0, 32); 00307 POINT sz = txGetExtent(); 00308 00309 // For tests only. Do not use for brexit() purposes 00310 00311 if (mode == 1) 00312 { 00313 txSetColor (TX_NULL); txSetFillColor (blue); txRectangle (0, 0, sz.x, sz.y); 00314 txSetColor (white, 75); txLine (0, 0, sz.x, sz.y); txLine (0, sz.y, sz.x, 0); 00315 txSetColor (red, 25); txLine (0, 0, sz.x, sz.y); txLine (0, sz.y, sz.x, 0); 00316 } 00317 else 00318 { 00319 txSetColor (white, 100); txLine (0, sz.y/2, sz.x, sz.y/2); txLine (sz.x/2, 0, sz.x/2, sz.y); 00320 txSetColor (red, 50); txLine (0, sz.y/2, sz.x, sz.y/2); txLine (sz.x/2, 0, sz.x/2, sz.y); 00321 } 00322 } 00323 00324 //----------------------------------------------------------------------------------------------------------------- 00325 00326 void DrawModel (double rotation); 00327 void DrawModel (double rotation) 00328 { 00329 txglClear (0, 0, 0); 00330 00331 Win32::glLoadIdentity(); 00332 Win32::glRotated (rotation, 1, 0, 1); 00333 00334 Win32::glTranslated (0, 0, -50); 00335 00336 Win32::glColor3d (1, 0, 0); 00337 txgluSphere (75); 00338 00339 Win32::glColor3d (0, 0, 1); 00340 txgluCylinder (50, 50, 150); 00341 txgluCylinder (40, 40, 150); 00342 txgluDisk (40, 50); 00343 00344 Win32::glTranslated (0, 0, 150); 00345 00346 txgluDisk (40, 50); 00347 00348 Win32::glLoadIdentity(); 00349 00350 Win32::glColor3d (1, 1, 0); 00351 txglTextOut (-100, +250, "Это кто? (Who?)"); 00352 txglTextOut (-120, +220, "Это тестовый объект."); 00353 txglTextOut (- 70, +190, "Cats rules."); 00354 00355 Win32::glColor3d (0, 1, 0); 00356 txglTextOut (-250, -220, "A quick brown fox jums over the lazy dog."); 00357 txglTextOut (-330, -250, "В чащах юга жил-был цитрус, да, но фальшивый экземпляр."); 00358 txglTextOut (- 30, -280, "Meow."); 00359 } 00360 00361 //----------------------------------------------------------------------------------------------------------------- 00362 00363 int main() 00364 { 00365 txCreateWindow (800, 600); 00366 00367 txBegin(); 00368 txLock(); 00369 00370 DrawBackgr (1); 00371 00372 HDC dc = GetDC (txWindow()); 00373 HGLRC rc = txglCreateContext (dc); rc asserted; 00374 00375 for (double rotation = 0; !txGetAsyncKeyState (VK_ESCAPE); ) 00376 { 00377 DrawBackgr (2); 00378 00379 double fps = txGetFPS(); 00380 if (fps > 0) rotation += 50/fps; 00381 00382 DrawModel (rotation); 00383 00384 if (fps > 0) txglSwapBuffers(); 00385 Sleep (50); 00386 } 00387 00388 txUnlock(); 00389 txEnd(); 00390 00391 txglDeleteContext (rc) asserted; 00392 ReleaseDC (txWindow(), dc); 00393 } 00394