35 #define GLF_START_LIST 20000 
   40 #include <sysutils.hpp> 
   46                 m_glOptions(), 
glyphMetrics(), hDC(hDC_), outText(), clientWidth(
 
   47                                 clientWidth_), clientHeight(clientHeight_), mode(MoveNone), objectIndex(
 
   48                                 3), objectNumMajor(32), objectNumMinor(32)
 
   52         outText.push_back(
"Winamp");
 
   53         outText.push_back(
"Remote");
 
   54         outText.push_back(
"Control");
 
   59         hGLRC = wglCreateContext(hDC);
 
   60         wglMakeCurrent(hDC, hGLRC);
 
   63         startup = GetTickCount();
 
   71                 wglMakeCurrent(NULL, NULL);
 
   72                 wglDeleteContext(hGLRC);
 
   83         clientWidth = clientWidth_;
 
   84         clientHeight = clientHeight_;
 
   87 void AboutGLDisplay::CreateFontList()
 
   92         HFONT hFont, hOldFont;
 
   94         glMatrixMode(GL_MODELVIEW);
 
   97         memset(&lf, 0, 
sizeof(LOGFONT));
 
   99         lf.lfWeight = FW_BOLD;
 
  100         lf.lfCharSet = ANSI_CHARSET;
 
  101         lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
 
  102         lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
 
  103         lf.lfQuality = DEFAULT_QUALITY;
 
  104         lf.lfPitchAndFamily = FF_DONTCARE | DEFAULT_PITCH;
 
  105         lstrcpy(lf.lfFaceName, 
"Arial");
 
  107         hFont = CreateFontIndirect(&lf);
 
  108         hOldFont = SelectObject(hDC, hFont);
 
  134         glEnable(GL_CULL_FACE);
 
  138                         m_glOptions.
textExtrusion, WGL_FONT_POLYGONS, glyphMetrics)))
 
  140                 AnsiString error = AnsiString(
"wglUseFontOutlines failed!")
 
  141                                 + SysErrorMessage(GetLastError());
 
  142                 OutputDebugString(error.c_str());
 
  145         DeleteObject(SelectObject(hDC, hOldFont));
 
  149 void AboutGLDisplay::CreateDisplayLists(
void)
 
  152         glNewList(
CUBE, GL_COMPILE);
 
  157         glNormal3f(-1.0F, 0.0F, 0.0F);
 
  158         glTexCoord2f(0.0F, 1.0F);
 
  159         glVertex3f(-0.5F, -0.5F, -0.5F);
 
  160         glTexCoord2f(0.0F, 0.0F);
 
  161         glVertex3f(-0.5F, -0.5F, 0.5F);
 
  162         glTexCoord2f(1.0F, 0.0F);
 
  163         glVertex3f(-0.5F, 0.5F, 0.5F);
 
  164         glTexCoord2f(1.0F, 1.0F);
 
  165         glVertex3f(-0.5F, 0.5F, -0.5F);
 
  167         glNormal3f(1.0F, 0.0F, 0.0F);
 
  168         glTexCoord2f(1.0F, 1.0F);
 
  169         glVertex3f(0.5F, 0.5F, 0.5F);
 
  170         glTexCoord2f(0.0F, 1.0F);
 
  171         glVertex3f(0.5F, -0.5F, 0.5F);
 
  172         glTexCoord2f(0.0F, 0.0F);
 
  173         glVertex3f(0.5F, -0.5F, -0.5F);
 
  174         glTexCoord2f(1.0F, 0.0F);
 
  175         glVertex3f(0.5F, 0.5F, -0.5F);
 
  177         glNormal3f(0.0F, -1.0F, 0.0F);
 
  178         glTexCoord2f(0.0F, 1.0F);
 
  179         glVertex3f(-0.5F, -0.5F, -0.5F);
 
  180         glTexCoord2f(0.0F, 0.0F);
 
  181         glVertex3f(0.5F, -0.5F, -0.5F);
 
  182         glTexCoord2f(1.0F, 0.0F);
 
  183         glVertex3f(0.5F, -0.5F, 0.5F);
 
  184         glTexCoord2f(1.0F, 1.0F);
 
  185         glVertex3f(-0.5F, -0.5F, 0.5F);
 
  187         glNormal3f(0.0F, 1.0F, 0.0F);
 
  188         glTexCoord2f(1.0F, 1.0F);
 
  189         glVertex3f(0.5F, 0.5F, 0.5F);
 
  190         glTexCoord2f(0.0F, 1.0F);
 
  191         glVertex3f(0.5F, 0.5F, -0.5F);
 
  192         glTexCoord2f(0.0F, 0.0F);
 
  193         glVertex3f(-0.5F, 0.5F, -0.5F);
 
  194         glTexCoord2f(1.0F, 0.0F);
 
  195         glVertex3f(-0.5F, 0.5F, 0.5F);
 
  197         glNormal3f(0.0F, 0.0F, -1.0F);
 
  198         glTexCoord2f(0.0F, 1.0F);
 
  199         glVertex3f(-0.5F, -0.5F, -0.5F);
 
  200         glTexCoord2f(0.0F, 0.0F);
 
  201         glVertex3f(-0.5F, 0.5F, -0.5F);
 
  202         glTexCoord2f(1.0F, 0.0F);
 
  203         glVertex3f(0.5F, 0.5F, -0.5F);
 
  204         glTexCoord2f(1.0F, 1.0F);
 
  205         glVertex3f(0.5F, -0.5F, -0.5F);
 
  207         glNormal3f(0.0F, 0.0F, 1.0F);
 
  208         glTexCoord2f(1.0F, 1.0F);
 
  209         glVertex3f(0.5F, 0.5F, 0.5F);
 
  210         glTexCoord2f(0.0F, 1.0F);
 
  211         glVertex3f(-0.5F, 0.5F, 0.5F);
 
  212         glTexCoord2f(0.0F, 0.0F);
 
  213         glVertex3f(-0.5F, -0.5F, 0.5F);
 
  214         glTexCoord2f(1.0F, 0.0F);
 
  215         glVertex3f(0.5F, -0.5F, 0.5F);
 
  220         glNewList(
SPHERE, GL_COMPILE);
 
  224         glNewList(
TORUS, GL_COMPILE);
 
  229 void AboutGLDisplay::drawText(
void)
 const 
  232         unsigned int index, i;
 
  238         yoffset = glyphMetrics[0].gmfBlackBoxY;
 
  240         textIndex = ((GetTickCount() - startup) / 2000) % (outText.size());
 
  242         std::string text = outText[textIndex];
 
  243         for (i = 0; i < text.size(); i++)
 
  246                 index = (int) outText[textIndex].c_str()[i];
 
  247                 xoffset += glyphMetrics[index].gmfBlackBoxX;
 
  252         glTranslatef(-xoffset / 2, -yoffset / 2, m_glOptions.
textExtrusion / 2);
 
  254         glCallLists( static_cast<int> ( text.size() ), GL_UNSIGNED_BYTE, reinterpret_cast<const void *> (text.c_str()) );
 
  256         glTranslatef(xoffset / 2, yoffset / 2, -m_glOptions.
textExtrusion / 2);
 
  261 void AboutGLDisplay::drawCube(
void)
 const 
  270 void AboutGLDisplay::drawTorus(
void)
 const 
  279         int numVerts = (objectNumMajor + 1) * (objectNumMinor + 1);
 
  281                         m_glOptions.
halfObject ? objectNumMajor / 2 : objectNumMajor;
 
  282         int numPerStrip = 2 * (objectNumMinor + 1);
 
  283         int numElements = (objectNumMajor + 1) * numPerStrip;
 
  285         static struct vertex *vertexArray, *v;
 
  286         static GLuint *elementArray, *e;
 
  291         if (!vertexArray || numMajor != objectNumMajor
 
  292                         || numMinor != objectNumMinor)
 
  294                 float majorRadius = 0.6F;
 
  295                 float minorRadius = 0.2F;
 
  296                 double majorStep = 2.0F * M_PI / objectNumMajor;
 
  297                 double minorStep = 2.0F * M_PI / objectNumMinor;
 
  301                 vertexArray = (
struct vertex *) calloc(numVerts, 
sizeof(
struct vertex));
 
  305                 elementArray = (GLuint *) calloc(numElements, 
sizeof(GLuint));
 
  307                 numMajor = objectNumMajor;
 
  308                 numMinor = objectNumMinor;
 
  312                 for (i = 0; i <= numMajor; ++i)
 
  314                         double a = i * majorStep;
 
  315                         GLfloat x = (GLfloat) cos(a);
 
  316                         GLfloat y = (GLfloat) sin(a);
 
  318                         for (j = 0; j <= numMinor; ++j)
 
  320                                 double b = j * minorStep;
 
  321                                 GLfloat c = (GLfloat) cos(b);
 
  322                                 GLfloat r = minorRadius * c + majorRadius;
 
  323                                 GLfloat z = minorRadius * (GLfloat) sin(b);
 
  325                                 v->t[0] = i / (GLfloat) numMajor;
 
  326                                 v->t[1] = j / (GLfloat) numMinor;
 
  330                                 v->n[2] = z / minorRadius;
 
  338                                 *e++ = i * (numMinor + 1) + j;
 
  339                                 *e++ = (i + 1) * (numMinor + 1) + j;
 
  346                 glInterleavedArrays(GL_T2F_N3F_V3F, 0, vertexArray);
 
  348 #if defined(GL_SGI_compiled_vertex_array) 
  349                 if (useVertexLocking && LockArrays) LockArrays(0, numVerts);
 
  352                 for (i = 0, e = elementArray; i < numStrips; ++i, e += numPerStrip)
 
  354                         glDrawElements(GL_TRIANGLE_STRIP, numPerStrip, GL_UNSIGNED_INT, e);
 
  357 #if defined(GL_SGI_compiled_vertex_array) 
  358                 if (useVertexLocking && UnlockArrays) UnlockArrays();
 
  363                 for (i = 0, e = elementArray; i < numStrips; ++i, e += numPerStrip)
 
  365                         glBegin(GL_TRIANGLE_STRIP);
 
  366                         for (j = 0; j < numPerStrip; ++j)
 
  368                                 v = &vertexArray[e[j]];
 
  379 void AboutGLDisplay::drawSphere(
void)
 const 
  388         int numVerts = (objectNumMajor + 1) * (objectNumMinor + 1);
 
  390                         m_glOptions.
halfObject ? objectNumMajor / 2 : objectNumMajor;
 
  391         int numPerStrip = 2 * (objectNumMinor + 1);
 
  392         int numElements = (objectNumMajor + 1) * numPerStrip;
 
  394         static struct vertex *vertexArray, *v;
 
  395         static GLuint *elementArray, *e;
 
  400         if (!vertexArray || numMajor != objectNumMajor
 
  401                         || numMinor != objectNumMinor)
 
  404                 double majorStep = 2.0F * M_PI / objectNumMajor;
 
  405                 double minorStep = M_PI / objectNumMinor;
 
  409                 vertexArray = (
struct vertex *) calloc(numVerts, 
sizeof(
struct vertex));
 
  413                 elementArray = (GLuint *) calloc(numElements, 
sizeof(GLuint));
 
  415                 numMajor = objectNumMajor;
 
  416                 numMinor = objectNumMinor;
 
  420                 for (i = 0; i <= numMajor; ++i)
 
  422                         double a = i * majorStep;
 
  423                         GLfloat x = (GLfloat) cos(a);
 
  424                         GLfloat y = (GLfloat) sin(a);
 
  426                         for (j = 0; j <= numMinor; ++j)
 
  428                                 double b = j * minorStep;
 
  429                                 GLfloat c = (GLfloat) sin(b);
 
  430                                 GLfloat r = c * radius;
 
  431                                 GLfloat z = (GLfloat) cos(b);
 
  433                                 v->t[0] = i / (GLfloat) numMajor;
 
  434                                 v->t[1] = j / (GLfloat) numMinor;
 
  442                                 v->v[2] = z * radius;
 
  446                                 *e++ = (i + 1) * (numMinor + 1) + j;
 
  447                                 *e++ = i * (numMinor + 1) + j;
 
  454                 glInterleavedArrays(GL_T2F_N3F_V3F, 0, vertexArray);
 
  456 #if defined(GL_SGI_compiled_vertex_array) 
  457                 if (useVertexLocking && LockArrays) LockArrays(0, numVerts);
 
  460                 for (i = 0, e = elementArray; i < numStrips; ++i, e += numPerStrip)
 
  462                         glDrawElements(GL_TRIANGLE_STRIP, numPerStrip, GL_UNSIGNED_INT, e);
 
  465 #if defined(GL_SGI_compiled_vertex_array) 
  466                 if (useVertexLocking && UnlockArrays) UnlockArrays();
 
  471                 for (i = 0, e = elementArray; i < numStrips; ++i, e += numPerStrip)
 
  473                         glBegin(GL_TRIANGLE_STRIP);
 
  474                         for (j = 0; j < numPerStrip; ++j)
 
  476                                 v = &vertexArray[e[j]];
 
  487 void AboutGLDisplay::setCheckTexture(
void)
 const 
  491         GLubyte *texPixels, *p;
 
  495         texSize = texWidth * texHeight * 4 * 
sizeof(GLubyte);
 
  498                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
  502                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
  505         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
  506         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
  507         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
  508         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
  510         texPixels = (GLubyte *) malloc(texSize);
 
  511         if (texPixels == NULL)
 
  517         for (i = 0; i < texHeight; ++i)
 
  519                 for (j = 0; j < texWidth; ++j)
 
  539         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGBA,
 
  540                         GL_UNSIGNED_BYTE, texPixels);
 
  568         GLfloat aspect = (GLfloat) clientWidth / (GLfloat) clientHeight;
 
  570         glMatrixMode(GL_PROJECTION);
 
  576         glViewport(0, 0, clientWidth, clientHeight);
 
  578         glMatrixMode(GL_MODELVIEW);
 
  581 void AboutGLDisplay::setMaterial(
void)
 const 
  584         { 0.01F, 0.01F, 0.01F, 1.00F };
 
  586         { 0.45F, 0.05F, 0.65F, 0.60F };
 
  588         { 0.50F, 0.50F, 0.50F, 1.00F };
 
  589         GLfloat matShine = 20.00F;
 
  591         glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
 
  592         glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
 
  593         glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
 
  594         glMaterialf(GL_FRONT, GL_SHININESS, matShine);
 
  600         GLfloat light0Pos[4] =
 
  601         { 0.70F, 0.70F, 1.25F, 0.00F };
 
  602         GLfloat fogDensity = 1.35F * 0.180F;
 
  604         GLfloat fogColor[4] =
 
  609         0.0F, 0.0F, 0.0F, 1.0F,
 
  613 #if defined(GL_SGI_cull_vertex) 
  614         CullParameterfv = (PFNGLCULLPARAMETERFVSGIPROC)
 
  615         wglGetProcAddress(
"glCullParameterfvSGI");
 
  618 #if defined(GL_SGI_compiled_vertex_array) 
  619         LockArrays = (PFNGLLOCKARRAYSSGIPROC)
 
  620         wglGetProcAddress(
"glLockArraysSGI");
 
  621         UnlockArrays = (PFNGLUNLOCKARRAYSSGIPROC)
 
  622         wglGetProcAddress(
"glUnlockArraysSGI");
 
  625         glFogi(GL_FOG_MODE, GL_EXP2);
 
  626         glFogf(GL_FOG_DENSITY, fogDensity);
 
  627         glFogfv(GL_FOG_COLOR, fogColor);
 
  630         glTranslatef(0.0F, 0.0F, -2.0F);
 
  634         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
 
  635         glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
 
  643         CreateDisplayLists();
 
  646 void AboutGLDisplay::resize(
void)
 const 
  649         glViewport(0, 0, clientWidth, clientHeight);
 
  656                 glEnable(GL_DEPTH_TEST);
 
  657                 glEnable(GL_CULL_FACE);
 
  673                 glEnable(GL_POINT_SMOOTH);
 
  674                 glEnable(GL_LINE_SMOOTH);
 
  676                 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
 
  677                 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 
  679                 glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
 
  680                 glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
 
  686                         glClearColor(0.0F, 0.0F, 0.0F, 1.0F);
 
  692                         glClearColor(0.0F, 0.0F, 0.0F, 1.0F);
 
  696                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  699                 if (mode == MoveObject)
 
  703                         glRotatef( angle , axis[0], axis[1], axis[2]); glMultMatrixf((GLfloat *) objectXform);
 
  704                         glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform);
 
  710                         glEnable(GL_TEXTURE_2D);
 
  714                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
  716         #if defined(GL_SGI_cull_vertex) 
  719                         glEnable(GL_CULL_VERTEX_SGI);
 
  724                         glEnable(GL_CULL_FACE);
 
  728                         glEnable(GL_LIGHTING);
 
  730                 glEnable(GL_DEPTH_TEST);
 
  734                 glMultMatrixf((GLfloat *) objectXform);
 
  758                 glDisable(GL_TEXTURE_2D);
 
  759                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
  760         #if defined(GL_SGI_cull_vertex) 
  761                 glDisable(GL_CULL_VERTEX_SGI);
 
  763                 glDisable(GL_CULL_FACE);
 
  764                 glDisable(GL_LIGHTING);
 
  765                 glDisable(GL_DEPTH_TEST);
 
  776 void AboutGLDisplay::ptov(
int x, 
int y, 
int width, 
int height, 
float v[3])
 
  781         v[0] = (2.0F * x - width) / width;
 
  782         v[1] = (height - 2.0F * y) / height;
 
  783         d = (float) sqrt(v[0] * v[0] + v[1] * v[1]);
 
  784         v[2] = (float) cos((M_PI / 2.0F) * ((d < 1.0F) ? d : 1.0F));
 
  785         a = 1.0F / (float) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
 
  802         trackingMotion = TRUE;
 
  805         ptov(x, y, clientWidth, clientHeight, lastPos);
 
  810         if (button == 1 && mode == MoveObject)
 
  812                 trackingMotion = FALSE;
 
  819         if (startX != x || startY != y)
 
  832                 float curPos[3], dx, dy, dz;
 
  834                 ptov(x, y, clientWidth, clientHeight, curPos);
 
  836                 dx = curPos[0] - lastPos[0];
 
  837                 dy = curPos[1] - lastPos[1];
 
  838                 dz = curPos[2] - lastPos[2];
 
  839                 angle = 90.0F * (float) sqrt(dx * dx + dy * dy + dz * dz);
 
  841                 axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1];
 
  842                 axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2];
 
  843                 axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0];
 
  845                 lastPos[0] = curPos[0];
 
  846                 lastPos[1] = curPos[1];
 
  847                 lastPos[2] = curPos[2];
 
  851 void AboutGLDisplay::setupPalette()
  const 
  853         PIXELFORMATDESCRIPTOR pfd;
 
  855         int pixelFormat = GetPixelFormat(hDC);
 
  858         DescribePixelFormat(hDC, pixelFormat, 
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
 
  859         if (!((pfd.dwFlags & PFD_NEED_PALETTE)
 
  860                         || (pfd.iPixelType == PFD_TYPE_COLORINDEX)))
 
  865         paletteSize = 1 << pfd.cColorBits;
 
  866         pPal = (LOGPALETTE*) malloc(
 
  867                         sizeof(LOGPALETTE) + paletteSize * 
sizeof(PALETTEENTRY));
 
  868         pPal->palVersion = 0x300;
 
  869         pPal->palNumEntries = (WORD) paletteSize;
 
  872         (void) GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);
 
  876                 int redMask = (1 << pfd.cRedBits) - 1;
 
  877                 int greenMask = (1 << pfd.cGreenBits) - 1;
 
  878                 int blueMask = (1 << pfd.cBlueBits) - 1;
 
  881                 for (i = 0; i < paletteSize; ++i)
 
  883                         pPal->palPalEntry[i].peRed = (GLbyte) ((((i >> pfd.cRedShift)
 
  884                                         & redMask) * 255) / redMask);
 
  885                         pPal->palPalEntry[i].peGreen = (GLbyte) ((((i >> pfd.cGreenShift)
 
  886                                         & greenMask) * 255) / greenMask);
 
  887                         pPal->palPalEntry[i].peBlue = (GLbyte) ((((i >> pfd.cBlueShift)
 
  888                                         & blueMask) * 255) / blueMask);
 
  889                         pPal->palPalEntry[i].peFlags = 0;
 
  894         hPalette = CreatePalette(pPal);
 
  899                 SelectPalette(hDC, hPalette, FALSE);
 
  904 void AboutGLDisplay::setupPixelformat()
  const 
  906         PIXELFORMATDESCRIPTOR pfd =
 
  907         { 
sizeof(PIXELFORMATDESCRIPTOR), 
 
  925         int SelectedPixelFormat;
 
  930                 pfd.dwFlags |= PFD_DOUBLEBUFFER;
 
  938         SelectedPixelFormat = ChoosePixelFormat(hDC, &pfd);
 
  939         if (SelectedPixelFormat == 0)
 
  941                 throw "ChoosePixelFormat failed";
 
  944         retVal = SetPixelFormat(hDC, SelectedPixelFormat, &pfd);
 
  947                 MessageBox(WindowFromDC(hDC), 
"SetPixelFormat failed", 
"Error",
 
  948                                 MB_ICONERROR | MB_OK);