TX Library Help – Version: 00173a, Revision: 174
 ALL  Windows graphics in a sandbox

TXGL.cpp

См. документацию.
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