OpenGL Multicolor Tetrahedron (C++)
Contents
Description
This example shows how to use the OpenGL and GLUT frameworks on OS X. This is a simple application (one source file) that can be used as start-up code. To run this example:
- Create a C++Builder Console Application.
- Add the OS X platform to the application, and activate it.
- Associate a connection profile and an SDK with the application (using the OS X target platform).
- The code depends on the OpenGL and GLUT frameworks, so you need to include those in the SDK. See below.
- Copy the code below.
Adding the OpenGL and GLUT Frameworks to the SDK
When a software development kit (SDK) for OS X is installed, the OpenGL and GLUT frameworks are by default not included. To include them, open the SDK Manager panel and click the Add a new path item button from the right-hand side. In the Add Remote Path Item or Edit Remote Path Item dialog:
- For OpenGL, set the path on remote machine
/System/Library/Frameworks
, the file maskOpenGL
, and the path type Framework. - For GLUT, set the path on remote machine
/System/Library/Frameworks
, the file maskGLUT
, and the path type Framework.
Then, click Update Local File Cache so the new files are brought from the Mac.
Functions
rdtsc
. Reads the processor time stamp counter. For more information, see the RDTSC instruction.drawTetrahedron
. Draws a multicolor tetrahedron at a specific rotation angle.initLighting
. Sets the scene light.display
. The GLUT display function.reshape
. The GLUT reshape function.reshape
. The GLUT reshape function.keyboard
. The GLUT keyboard function. When ESCAPE is pressed, the application terminates.reshape
. The GLUT reshape function.
Global Variables
tetrahedronAngle
represents the tetrahedron rotation angle. The value is updated periodically using therdtsc
(read time stamp counter) function.
Code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <GLUT/glut.h>
#include <OpenGL/glext.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
static float tetrahedronAngle = 0.0f;
// read time stamp counter
// this instruction is available on x86, x64
// the result is stored in EDX:EAX
unsigned long long rdtsc()
{
__asm { rdtsc }
}
void drawTetrahedron() {
static const float tetrahedron[][3] = {
{0.0f, 1.0f, 0.0f}, {0.943f, -0.333f, 0.0f}, {-0.471f, -0.333f, 0.8165f
}, {-0.471f, -0.333f, -0.8165f}};
static const float materialAmbientColor[][3] = {
{1.0f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}};
static const float materialSpecularColor[][3] = {
{1.0f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}};
static const int point[] = {1, 2, 0, 3, 1}; // triangle strip
glPushMatrix();
glRotatef(tetrahedronAngle, 0.0f, 1.0f, 0.0f);
for (int i = 0; i < 3 /* sides */ ; i++) {
glBegin(GL_TRIANGLE_STRIP);
glMaterialfv(GL_FRONT, GL_AMBIENT, materialAmbientColor[i]);
glMaterialfv(GL_FRONT, GL_SPECULAR, materialSpecularColor[i]);
glVertex3fv(tetrahedron[point[i]]);
glVertex3fv(tetrahedron[point[i + 1]]);
glVertex3fv(tetrahedron[point[i + 2]]);
glEnd();
}
glPopMatrix();
}
void initLighting() {
const float lightPosition[][4] = { {0.0f, 25.0f, 0.0f, 1.0f}};
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition[0]);
const float lightAmbient[][3] = { {0.15f, 0.15f, 0.15f}};
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient[0]);
const float lightSpecular[][3] = { {0.05f, 0.05f, 0.05f}};
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular[0]);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1e-3);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 1e-3);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHTING);
glPushMatrix();
glTranslatef(0.0f, -1.5f, -7.5f); // observer position
// update tetrahedron angle
unsigned long long t = rdtsc();
printf("\n%ld", t);
tetrahedronAngle = ((long)(t >> 24/* scaling */)) % 360 /* degrees */ ;
drawTetrahedron();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLfloat)w / h, 0.125, 1e4);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 0x1b: // escape
exit(0);
break;
}
}
void idleFunc() {
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Multicolor tetrahedron");
glutFullScreen();
initLighting();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(idleFunc);
glutMainLoop();
return 0;
}
Result
This application creates a GLUT window, enters the full-screen mode, and displays a rotating multicolor tetrahedron.