File indexing completed on 2024-04-28 07:54:41
0001 /* 0002 SPDX-FileCopyrightText: 2008 Ian Wadham <iandw.au@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 // Local includes 0008 #include "gameglview.h" 0009 0010 // Qt includes 0011 #include <QOpenGLTexture> 0012 #include <QDir> 0013 #include <QImage> 0014 #include <QPainter> 0015 #include <QPoint> 0016 #include <QStandardPaths> 0017 #include <QStringList> 0018 #include <QSvgRenderer> 0019 0020 #include "kubrick_debug.h" 0021 // C++ includes 0022 #include <iostream> 0023 0024 GameGLView::GameGLView(Game * g, QWidget * parent) 0025 : QOpenGLWidget(parent), 0026 bgColor (QColor (0, 0, 35)) 0027 { 0028 // Save a pointer to the Game object that controls everything. 0029 game = g; 0030 0031 this->setMinimumSize (450, 300); 0032 0033 // Set the amount of bevelling on a cubie's edge to its default value. 0034 bevelAmount = 0.125; 0035 0036 // Set colors to full intensity (no blinking). 0037 blinkIntensity = 1.0; 0038 0039 // Note: Do not use OpenGL functions here. 0040 // Initialize OpenGL in initializeGL() instead! 0041 0042 const GLubyte * v = glGetString(GL_VERSION); 0043 printf ("GL Version %s\n", v); 0044 } 0045 0046 0047 void GameGLView::initializeGL() 0048 { 0049 // Look for themes in files "---/share/apps/kubrick/themes/*.desktop". 0050 // IDW - This is temporary code for KDE 4.1. Do themes properly in KDE 4.2. 0051 QStringList themeFilepaths; 0052 const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("themes"), QStandardPaths::LocateDirectory); 0053 for (const QString& dir : dirs) { 0054 const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.svgz")); // Find files. 0055 for (const QString& file : fileNames) { 0056 themeFilepaths.append(dir + QLatin1Char('/') + file); 0057 } 0058 } 0059 if (! themeFilepaths.isEmpty()) { 0060 backgroundType = PICTURE; // Use a picture for the background. 0061 loadBackground (themeFilepaths.first()); 0062 } 0063 else { 0064 backgroundType = NO_LOAD; // Use a 4-way color gradient. 0065 } 0066 0067 // Make glClear() clear to a deep-blue background. 0068 glClearColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF(), bgColor.alphaF()); 0069 0070 // Disable dithering which is usually not needed. 0071 glDisable(GL_DITHER); 0072 0073 // Set up fixed lighting. 0074 glMatrixMode(GL_MODELVIEW); 0075 glLoadIdentity(); 0076 turnOnLighting(); 0077 } 0078 0079 0080 // IDW - Key K for switching the background (temporary) - FIX IT FOR KDE 4.2. 0081 void GameGLView::changeBackground() 0082 { 0083 if (backgroundType != NO_LOAD) { 0084 backgroundType = (backgroundType == PICTURE) ? GRADIENT : PICTURE; 0085 } 0086 } 0087 0088 0089 void GameGLView::loadBackground (const QString & filepath) 0090 { 0091 // NOTE: Size 1024 gave a significantly sharper picture, compared to 512. 0092 int bgTextureSize = 1024; // Size of background texture. 0093 QImage tex (bgTextureSize, bgTextureSize, QImage::Format_ARGB32); 0094 tex.fill (bgColor.rgba()); 0095 0096 QString bg (QStringLiteral("background")); 0097 GLdouble bgWidth = bgTextureSize; 0098 GLdouble bgHeight = bgTextureSize; 0099 bgAspect = 1.0; 0100 0101 QSvgRenderer svg; 0102 svg.load (filepath); 0103 0104 if (svg.isValid()) { 0105 QRectF r = svg.boundsOnElement (bg); 0106 0107 bgAspect = r.width() / r.height(); 0108 bool landscape = (bgAspect >= 1.0); 0109 0110 bgWidth = landscape ? bgTextureSize : bgTextureSize * bgAspect; 0111 bgHeight = landscape ? bgTextureSize / bgAspect : bgTextureSize; 0112 0113 // Render the drawing at the bottom left of the texture's QImage. 0114 QRectF bounds (0, bgTextureSize - bgHeight, bgWidth, bgHeight); 0115 QPainter p; 0116 p.begin (&tex); 0117 svg.render (&p, bg, bounds); 0118 p.end(); 0119 } 0120 else { 0121 backgroundType = NO_LOAD; // Use a 4-way color gradient. 0122 } 0123 0124 bgTexture.reset(new QOpenGLTexture(tex.mirrored())); 0125 txWidth = bgWidth / (GLfloat) bgTextureSize; 0126 txHeight = bgHeight / (GLfloat) bgTextureSize; 0127 } 0128 0129 0130 void GameGLView::resizeGL(int w, int h) 0131 { 0132 // Make use of the whole view. 0133 glViewport (0, 0, w, h); 0134 glAspect = (GLdouble) w / (GLdouble) h; 0135 0136 // Set the perspective projection. 0137 glMatrixMode (GL_PROJECTION); 0138 glLoadIdentity(); 0139 gluPerspective (viewAngle, glAspect, minZ, maxZ); 0140 glMatrixMode (GL_MODELVIEW); 0141 0142 // Calculate the depth and size of the background rectangle. 0143 bgRectZ = 2.0 * cubeCentreZ; 0144 bgRectY = -bgRectZ * tan (3.14159 * viewAngle / 360.0); 0145 bgRectX = glAspect * bgRectY; 0146 0147 if (backgroundType == PICTURE) { 0148 // Make the aspect ratio the same as for the original SVG picture. 0149 if (glAspect > bgAspect) { 0150 // Fit background to full width: OpenGL will trim top and bottom. 0151 bgRectY = bgRectX / bgAspect; // Stretch the height. 0152 } 0153 else { 0154 // Fit background to full height: OpenGL will trim left and right. 0155 bgRectX = bgRectY * bgAspect; // Stretch the width. 0156 } 0157 } 0158 0159 // Re-position the view-labels. 0160 game->setSceneLabels(); 0161 } 0162 0163 0164 float GameGLView::colors [7] [3] = { 0165 {0.2, 0.2, 0.2}, // Dark grey. 0166 {0.7, 0.0, 0.0}, // Red. 0167 {1.0, 0.5, 0.1}, // Orange. 0168 {0.0, 0.0, 0.8}, // Blue. 0169 {0.0, 0.5, 0.0}, // Green. 0170 {1.0, 1.0, 0.0}, // Yellow. 0171 {0.9, 0.9, 0.8} // Off-white. 0172 }; 0173 0174 0175 void GameGLView::paintGL() 0176 { 0177 // Clear the view. 0178 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 0179 0180 // Reset the modelview matrix. By doing so we also reset the "camera" that 0181 // is the eye position, so that it is now at (0,0,0), which is also the 0182 // center of the screen. We are looking down the negative Z axis, towards 0183 // (0,0,-1), with "up" being at (0,1,0). 0184 glLoadIdentity(); 0185 glEnable (GL_DEPTH_TEST); 0186 0187 if (checkGLError()) { 0188 std::cerr << "OpenGL error detected before drawScene()" << std::endl; 0189 } 0190 0191 // Draw the background. 0192 glDisable (GL_LIGHTING); 0193 switch (backgroundType) { 0194 case PICTURE: 0195 drawPictureBackground(); 0196 break; 0197 case GRADIENT: 0198 case NO_LOAD: 0199 draw4WayGradientBackground(); 0200 break; 0201 } 0202 glEnable (GL_LIGHTING); 0203 0204 // Draw the cube(s). 0205 game->drawScene (); 0206 0207 if (checkGLError()) { 0208 std::cerr << "OpenGL error detected after drawScene()" << std::endl; 0209 } 0210 } 0211 0212 0213 void GameGLView::drawPictureBackground() 0214 { 0215 glEnable (GL_TEXTURE_2D); 0216 glBindTexture (GL_TEXTURE_2D, bgTexture->textureId()); 0217 0218 // Draw the background picture behind the cubes, filling the view. 0219 glBegin (GL_QUADS); 0220 glTexCoord2f (0.0, 0.0); 0221 glVertex3f (-bgRectX, -bgRectY, bgRectZ); 0222 0223 glTexCoord2f (txWidth, 0.0); 0224 glVertex3f ( bgRectX, -bgRectY, bgRectZ); 0225 0226 glTexCoord2f (txWidth, txHeight); 0227 glVertex3f ( bgRectX, bgRectY, bgRectZ); 0228 0229 glTexCoord2f (0.0, txHeight); 0230 glVertex3f (-bgRectX, bgRectY, bgRectZ); 0231 glEnd(); 0232 0233 glDisable (GL_TEXTURE_2D); 0234 } 0235 0236 0237 void GameGLView::draw4WayGradientBackground() 0238 { 0239 glShadeModel (GL_SMOOTH); 0240 0241 // Draw the 4-way color-gradient behind the cubes, filling the view. 0242 glBegin(GL_QUADS); 0243 glColor3f (0.0, 0.0, 0.5); 0244 glVertex3f (-bgRectX, -bgRectY, bgRectZ); 0245 0246 glColor3f (0.8, 0.3, 0.6); 0247 glVertex3f ( bgRectX, -bgRectY, bgRectZ); 0248 0249 glColor3f (0.5, 0.8, 1.0); 0250 glVertex3f ( bgRectX, bgRectY, bgRectZ); 0251 0252 glColor3f (0.2, 0.2, 0.9); 0253 glVertex3f (-bgRectX, bgRectY, bgRectZ); 0254 glEnd(); 0255 0256 glShadeModel (GL_FLAT); 0257 } 0258 0259 0260 void GameGLView::dumpExtensions() 0261 { 0262 // OpenGL Extension detection. 0263 QString s = QLatin1String(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))) 0264 + QLatin1Char(' ') 0265 + QLatin1String(reinterpret_cast<const char*>(gluGetString(GLU_EXTENSIONS))); 0266 QStringList extensions = s.split (QLatin1Char(' '), Qt::SkipEmptyParts); 0267 for (int i = 0; i < extensions.count(); i++) 0268 { 0269 std::cout << extensions[i].toLatin1().data() << std::endl; 0270 } 0271 } 0272 0273 static float ambient[] = {0.0, 0.0, 0.0, 1.0}; 0274 static float diffuse[] = {1.0, 1.0, 1.0, 1.0}; 0275 0276 // Directional light, at infinity (parameter 4, w=0.0), shining 0277 // towards -Z. No attenuation. Diffuse, no spotlight effect. 0278 static float position0[] = {0.0, 0.0, 1.0, 0.0}; 0279 0280 // With lights off, 100% ambient gives a flat, dull, fairly well-lit picture. 0281 // With lights on, it makes little difference to specular effect, but makes 0282 // the strong colors of stickers look a bit washed out. So choose 60%. 0283 static float lmodel_ambient[] = {0.6, 0.6, 0.6, 1.0}; 0284 0285 // Controls SPREAD of specular reflections (128.0 = small highlight). 0286 static float material_shininess = 60.0; 0287 0288 // Controls intensity and color of specular reflections. 0289 static float material_specular[] = {0.5, 0.6, 0.5, 1.0}; 0290 0291 // Trying to light the insides of the cubies is a waste of time. 0292 static float lmodel_twoside[] = {GL_FALSE}; 0293 0294 void GameGLView::turnOnLighting () 0295 { 0296 // There is just one light. 0297 glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); 0298 glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); 0299 glLightfv (GL_LIGHT0, GL_POSITION, position0); 0300 0301 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 0302 glLightModelfv (GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); 0303 0304 // This gives a rolling-sheen effect to the specularity. 0305 // Not all stickers on a face light up at once. 0306 glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 0307 0308 glEnable (GL_LIGHTING); 0309 glEnable (GL_LIGHT0); 0310 0311 glEnable (GL_DEPTH_TEST); 0312 glEnable (GL_NORMALIZE); 0313 0314 // Do not render the backs (interiors) of cubie and sticker faces. The 0315 // "front" faces are those for which the order of drawing of the vertices 0316 // is anti-clockwise, as seen from the outside looking towards the centre. 0317 glEnable (GL_CULL_FACE); 0318 0319 glShadeModel (GL_FLAT); 0320 glMaterialf (GL_FRONT, GL_SHININESS, material_shininess); 0321 glMaterialfv (GL_FRONT, GL_SPECULAR, material_specular); 0322 0323 // This tracks color CHANGES and updates the corresponding glMaterial*. 0324 glEnable (GL_COLOR_MATERIAL); 0325 glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE); 0326 } 0327 0328 0329 QPoint GameGLView::getMousePosition () 0330 { 0331 QPoint p; 0332 p = mapFromGlobal (QCursor::pos()); // Convert to window co-ordinates. 0333 0334 // Convert Y co-ordinate to OpenGL convention (zero at bottom of window). 0335 p.setY (height() - p.y()); 0336 return p; 0337 } 0338 0339 0340 void GameGLView::pushGLMatrix () 0341 { 0342 glPushMatrix(); 0343 } 0344 0345 0346 void GameGLView::moveGLView (float xChange, float yChange, float zChange) 0347 { 0348 glTranslatef (xChange, yChange, zChange); 0349 } 0350 0351 0352 void GameGLView::rotateGLView (float degrees, float x, float y, float z) 0353 { 0354 glRotatef (degrees, x, y, z); 0355 } 0356 0357 0358 void GameGLView::popGLMatrix () 0359 { 0360 glPopMatrix(); 0361 } 0362 0363 0364 void GameGLView::setBevelAmount (int bevelPerCent) 0365 { 0366 bevelAmount = ((float) bevelPerCent)/100.0; 0367 } 0368 0369 0370 void GameGLView::drawACubie (float size, float centre[], int axis, int angle) 0371 { 0372 float lenA = 0.5 * size; // Half of a cubie's outside dimension. 0373 float bevel = bevelAmount * lenA; // The size of the bevel at the edges. 0374 float lenB = lenA - bevel; // Half of a face's inside dimension. 0375 0376 float p[nAxes]; // The point to be drawn currently. 0377 float normal[nAxes]; // The current normal vector (used in lighting). 0378 // Needs to be of length 1 for best results. 0379 float r2 = 0.7071067; // (1 / sqrt (2.0)), used for bevel normals. 0380 float r3 = 0.5773502; // (1 / sqrt (3.0)), used for corner normals. 0381 0382 // If the cubie is moving, rotate it around the required axis of the cube. 0383 if (angle != 0) { 0384 GLfloat v [nAxes] = {0.0, 0.0, 0.0}; 0385 v [axis] = 1.0; 0386 glPushMatrix(); 0387 glRotatef ((GLfloat) (-angle), v[0], v[1], v[2]); 0388 } 0389 0390 glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); 0391 glPushMatrix(); 0392 0393 glColor3fv (colors [0]); // The base color of a cubie, without stickers. 0394 0395 // Bring the centre to the origin during drawing. 0396 glTranslatef ((GLfloat) centre[X], 0397 (GLfloat) centre[Y], 0398 (GLfloat) centre[Z]); 0399 0400 // Draw three pairs of faces of the cubie and twelve bevelled edges. 0401 glBegin(GL_QUADS); 0402 LOOP (axis, 3) { 0403 0404 // The coordinate on the axis thru the face does not change, but we must 0405 // work out what the other two coordinates are, in cyclical order: i.e. 0406 // X-axis (0) --> Y,Z (coordinates 1 and 2 change), 0407 // Y-axis (1) --> Z,X (coordinates 2 and 0 change), 0408 // Z-axis (2) --> X,Y (coordinates 0 and 1 change). 0409 // 0410 int coord1 = 0; 0411 int coord2 = 0; 0412 0413 // Draw two opposite faces of the cubie and two bevelled edges each. 0414 LOOP (face, 2) { 0415 0416 // Draw one face of the cubie. 0417 // For (i,j) = (0,0), (0,1), (1,0) and (1,1), we will get values 0418 // (i,k) = (0,0), (0,1), (1,1) and (1,0) and will be drawing 0419 // vertices going around a square face of the cubie. 0420 0421 normal[coord1] = 0.0; 0422 normal[coord2] = 0.0; 0423 normal[axis] = (2*face -1) * 1.0; // -1.0 or +1.0. 0424 glNormal3fv (normal); // Used by lighting. 0425 0426 p[axis] = (2*face-1) * lenA; // Value -lenA or +lenA. 0427 // The axes are chosen so that the vertices go in "GL front face" 0428 // order (ie. anti-clockwise), as viewed from outside the cubie. 0429 if (p[axis] > 0.0) { 0430 coord1 = (axis + 2) % 3; 0431 coord2 = (axis + 1) % 3; 0432 } 0433 else { 0434 coord1 = (axis + 1) % 3; 0435 coord2 = (axis + 2) % 3; 0436 } 0437 0438 LOOP (i, 2) { 0439 p[coord1] = (2*i-1) * lenB; // Value -lenB or +lenB. 0440 LOOP (j, 2) { 0441 int k = (i + j) % 2; // Takes values 0 1 1 0. 0442 p[coord2] = (2*k-1) * lenB; // Value -lenB or +lenB. 0443 glVertex3fv (p); // Draw one of 4 vertices. 0444 } 0445 } 0446 0447 // Draw two of this face's bevelled edges. 0448 // Eventually, for 6 faces, all 12 edges will have been drawn. 0449 coord1 = (axis + 1) % 3; 0450 coord2 = (axis + 2) % 3; 0451 normal[axis] = (2*face -1) * r2; 0452 LOOP (edge, 2) { 0453 normal[coord1] = (2*edge -1) * r2; 0454 normal[coord2] = 0.0; 0455 glNormal3fv (normal); // Used by lighting. 0456 0457 LOOP (i, 2) { 0458 p[axis] = (2*face-1) * (lenA - ((edge + i)%2) * bevel); 0459 p[coord1] = (2*edge-1) * lenB + (edge - i) * bevel; 0460 LOOP (j, 2) { 0461 int k = (i + j) % 2; // Takes values 0 1 1 0. 0462 // p[coord2] = -lenB, +lenB, +lenB, -lenB on the + face 0463 // and = +lenB, -lenB, -lenB, +lenB on the - face, 0464 // thus ensuring anti-clockwise drawing of all 4 bevels 0465 // as you view each face from the outside looking in. 0466 p[coord2] = (2*face -1) * (2*k-1) * lenB; 0467 glVertex3fv (p); // Draw 1 of 4 vertices. 0468 } 0469 } 0470 } // END (edge, 2) 0471 0472 } // END (face, 2) 0473 0474 } // END (axis, 3) 0475 0476 glEnd(); 0477 0478 // Draw the 8 chiselled corners on the back and front faces of the cubie. 0479 glBegin(GL_TRIANGLES); 0480 LOOP (face, 2) { 0481 float z = ((float) 2*face-1); // Z direction: +r3 or -r3. 0482 LOOP (i, 2) { 0483 float x = ((float) 2*i-1); // X direction: +r3 or -r3. 0484 LOOP (j, 2) { 0485 float y = ((float) 2*j-1); // Y direction: +r3 or -r3. 0486 0487 glNormal3f (x*r3, y*r3, z*r3); // Used by lighting. 0488 0489 // Draw the triangular facet at this corner of the face. 0490 // The vertices must go in "GL front face" order (ie. anti- 0491 // clockwise), as viewed from outside the cubie. 0492 0493 if ((x * y * z) > 0.0) { 0494 // If 0 or 2 negatives, go round the vertices one way. 0495 glVertex3f (x*lenA, y*lenB, z*lenB); // A 0496 glVertex3f (x*lenB, y*lenA, z*lenB); // B 0497 glVertex3f (x*lenB, y*lenB, z*lenA); // C 0498 } 0499 else { 0500 // If 1 or 3 negatives, go round the vertices the other way. 0501 glVertex3f (x*lenA, y*lenB, z*lenB); // A 0502 glVertex3f (x*lenB, y*lenB, z*lenA); // C 0503 glVertex3f (x*lenB, y*lenA, z*lenB); // B 0504 } 0505 } 0506 } 0507 } // END (face, 2) 0508 0509 glEnd(); 0510 0511 glPopAttrib(); 0512 glPopMatrix(); 0513 checkGLError(); 0514 } 0515 0516 0517 void GameGLView::finishCubie () 0518 { 0519 // If the cubie just drawn is moving, restore the OpenGL co-ordinate axes. 0520 glPopMatrix(); 0521 } 0522 0523 0524 void GameGLView::drawASticker (float size, int color, bool blinking, 0525 int faceNormal[], float faceCentre []) 0526 { 0527 float lenA = 0.5 * size; // Half of a cubie's outside dimension. 0528 float bevel = bevelAmount * lenA; // The size of the bevel at the edges. 0529 float lenB = lenA - bevel; // Half the sticker's dimension. 0530 0531 float p[nAxes]; // The point to be drawn currently. 0532 float normal[nAxes]; // The normal vector (used in lighting). 0533 0534 int axis1 = 0, axis2 = 1; // Two axes in the plane of the sticker. 0535 0536 float mColor [3]; 0537 0538 glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); 0539 glPushMatrix(); 0540 0541 // Set the color of this sticker. 0542 if (blinking) { 0543 LOOP (i, 3) { 0544 mColor [i] = blinkIntensity * colors [color] [i]; 0545 } 0546 glColor3fv (mColor); // Dimmed color. 0547 } 0548 else { 0549 glColor3fv (colors [color]); // Normal color. 0550 } 0551 0552 // Bring the centre of the sticker to the origin during drawing. 0553 glTranslatef ((GLfloat) faceCentre[X], 0554 (GLfloat) faceCentre[Y], 0555 (GLfloat) faceCentre[Z]); 0556 0557 LOOP (axis, 3) { 0558 normal [axis] = 0.0; 0559 if (faceNormal [axis] != 0) { 0560 // One component of the faceNormal vector is 1: the others are zero. 0561 normal [axis] = (float) faceNormal [axis]; 0562 0563 // The sticker is offset from the cubie's face, along the normal. 0564 p [axis] = 0.01 * size * normal [axis]; 0565 0566 // The coordinate on the normal does not change, but we must work 0567 // out what the other two coordinates are, in cyclical order: i.e. 0568 // X-axis (0) --> Y,Z (coordinates 1 and 2 change), 0569 // Y-axis (1) --> Z,X (coordinates 2 and 0 change), 0570 // Z-axis (2) --> X,Y (coordinates 0 and 1 change). 0571 // 0572 // Ensure that the outside face of the sticker is drawn in 0573 // anti-clockwise sequence, so GL_CULL_FACE culls the inside one. 0574 0575 if (faceNormal [axis] > 0) { 0576 axis1 = (axis + 1) % 3; 0577 axis2 = (axis + 2) % 3; 0578 } 0579 else { 0580 axis2 = (axis + 1) % 3; 0581 axis1 = (axis + 2) % 3; 0582 } 0583 } 0584 } 0585 0586 glBegin(GL_QUADS); 0587 glNormal3fv (normal); // Used by lighting. 0588 0589 p [axis1] = + lenB; // Set the first vertex of the sticker. 0590 p [axis2] = + lenB; 0591 glVertex3fv (p); // Draw the first vertex, eg. (+X,+Y) quadrant. 0592 p [axis1] = - lenB; 0593 glVertex3fv (p); // Draw the second vertex, eg. (+X,-Y) quadrant. 0594 p [axis2] = - lenB; 0595 glVertex3fv (p); // Draw the third vertex, eg. (-X,-Y) quadrant. 0596 p [axis1] = + lenB; 0597 glVertex3fv (p); // Draw the fourth vertex, eg. (+X,-Y) quadrant. 0598 0599 glEnd(); 0600 0601 glPopAttrib(); 0602 glPopMatrix(); 0603 checkGLError(); 0604 } 0605 0606 0607 void GameGLView::setBlinkIntensity (float intensity) 0608 { 0609 blinkIntensity = intensity; 0610 } 0611 0612 0613 bool GameGLView::checkGLError() 0614 { 0615 GLenum error = glGetError(); 0616 if (error != GL_NO_ERROR) 0617 { 0618 // std::cerr << "An OpenGL error occurred" << std::endl; 0619 return true; 0620 } 0621 return false; 0622 } 0623 0624 0625 void GameGLView::mousePressEvent(QMouseEvent* e) 0626 { 0627 // ensure our context outside of paint event when querying scene data 0628 makeCurrent(); 0629 // Convert Y co-ordinate to OpenGL convention (zero at bottom of window). 0630 game->handleMouseEvent (ButtonDown, e->button(), 0631 e->pos().x(), height() - e->pos().y()); 0632 } 0633 0634 0635 void GameGLView::mouseReleaseEvent(QMouseEvent* e) 0636 { 0637 // ensure our context outside of paint event when querying scene data 0638 makeCurrent(); 0639 // Convert Y co-ordinate to OpenGL convention (zero at bottom of window). 0640 game->handleMouseEvent (ButtonUp, e->button(), 0641 e->pos().x(), height() - e->pos().y()); 0642 } 0643 0644 // End gameglview.cpp 0645 0646