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
tetrahedronAnglerepresents 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.