OpenGL Multicolor Tetrahedron (C++)

From RAD Studio Code Examples
Jump to: navigation, search

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:

  1. Create a C++Builder Console Application.
  2. Add the OS X platform to the application, and activate it.
  3. 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.
  4. 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 mask OpenGL, and the path type Framework.
  • For GLUT, set the path on remote machine /System/Library/Frameworks, the file mask GLUT, 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 the rdtsc (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.

See Also