Skip to content

Instantly share code, notes, and snippets.

@gszauer
Last active December 18, 2015 03:29
Show Gist options
  • Save gszauer/5718509 to your computer and use it in GitHub Desktop.
Save gszauer/5718509 to your computer and use it in GitHub Desktop.
#include <cmath>
#include <vector>
#include <map>
#include <iostream>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#include <sys/time.h>
#define WINFOW_TITLE "Window Template"
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define UPDATE_TIME 17 /* ((1 / 60) * 1000) rounded up */
#define X .525731112119133606
#define Z .850650808352039932
void Initialize();
void Shutdown();
void display();
void updateTimer(int windowId);
void reshape(int width, int height);
void keyDown(unsigned char key, int x, int y);
void keyUp(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void mouseDrag(int x, int y);
void mouseMove(int x, int y);
void glPerspective(float fov, float aspectRatio, float znear, float zfar);
void reshapeOrtho(int w, int h);
void reshapePerspective(int w, int h);
void (*activeReshape)(int,int) = reshapePerspective;
double GetMilliseconds();
void Normalize(GLfloat *a);
void DrawTriangle(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r);
void DrawSphere(int ndiv, float radius=1.0);
static GLfloat vdata[12][3] = {
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
static GLuint tindices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
};
const float lightDirection[] = {-1.0f, 0.0f, -1.0f, 0.0f};
static double prevTime = 0.0;
static float rotation = 0.0f;
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(WINDOW_WIDTH , WINDOW_HEIGHT);
glutCreateWindow(WINFOW_TITLE);
reshape(WINDOW_WIDTH, WINDOW_HEIGHT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyDown);
glutKeyboardUpFunc(keyUp);
glutMouseFunc(mouse);
glutMotionFunc(mouseDrag);
glutPassiveMotionFunc(mouseMove);
glutIgnoreKeyRepeat(false); // Key is continually held down
glutTimerFunc(UPDATE_TIME, updateTimer, glutGetWindow());
Initialize();
atexit(Shutdown);
prevTime = GetMilliseconds();
glutMainLoop();
return 0;
}
void Shutdown() {
// SHUTDOWN
}
void Initialize() {
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
const float noColor[] = {0.0f, 0.0f, 0.0f, 1.0f};
const float diffuseColor[] = {1.0f, 0.0f, 0.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, noColor);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, diffuseColor);
glLightfv(GL_LIGHT0, GL_POSITION, lightDirection);
const float ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f};
const float globalDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
const float materialShine = 0.0f;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, globalDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, noColor);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, noColor);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materialShine);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
void display() {
glClearColor(0.5f, 0.6f, 0.7f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glPushMatrix();
gluLookAt(-5.0f, 5.0f, -5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glRotatef(rotation, 0.0f, 1.0f, 0.0f);
glLightfv(GL_LIGHT0, GL_POSITION, lightDirection);
glColor3f(1.0f, 1.0f, 1.0f);
DrawSphere(5);
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(-2.0f, 0.0f, -2.0f);
glEnd();
glDisable(GL_DEPTH_TEST);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glPopMatrix();
glutSwapBuffers();
}
void updateTimer(int windowId) {
double curTime = GetMilliseconds();
double deltaTime = (curTime - prevTime) * 0.001;
// UPDATE
rotation += 60.0f * deltaTime;
while (rotation > 360.0f) {
rotation -= 360.0f;
}
prevTime = curTime;
glutTimerFunc(UPDATE_TIME, updateTimer, windowId);
glutPostRedisplay();
}
void reshape(int width, int height) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
activeReshape(width, height);
glMatrixMode(GL_MODELVIEW);
}
void keyDown(unsigned char key, int x, int y) {
}
void keyUp(unsigned char key, int x, int y) {
}
void mouseDrag(int x, int y) {
}
void mouseMove(int x, int y) {
}
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
} else /* GLUT_UP */ {
}
} else if (button == GLUT_RIGHT_BUTTON) {
if (state == GLUT_DOWN) {
} else /* GLUT_UP */ {
}
}
}
void reshapeOrtho(int w, int h) {
glOrtho(0.0f, 1.0f, 1.0f, 0.0f, -100.0f, 100.0f);
}
void reshapePerspective(int w, int h) {
glPerspective(60.0f, (float)w / (float)h, 0.01f, 1000.0f);
}
void glPerspective(float fov, float aspectRatio, float znear, float zfar) {
float ymax = znear * tanf(fov * M_PI / 360.0f);
float xmax = ymax * aspectRatio;
glFrustum(-xmax, xmax, -ymax, ymax, znear, zfar);
}
double GetMilliseconds() {
#if !WIN32
static timeval s_tTimeVal;
gettimeofday(&s_tTimeVal, NULL);
double time = s_tTimeVal.tv_sec * 1000.0; // sec to ms
time += s_tTimeVal.tv_usec / 1000.0; // us to ms
#else
double time = (double)GetTickCount() * 0.001;
#endif
return time;
}
void Normalize(GLfloat *a) {
GLfloat d=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
a[0]/=d; a[1]/=d; a[2]/=d;
}
void DrawTriangle(GLfloat *a, GLfloat *b, GLfloat *c, int div, float r) {
if (div<=0) {
glNormal3fv(b); glVertex3f(b[0]*r, b[1]*r, b[2]*r);
glNormal3fv(a); glVertex3f(a[0]*r, a[1]*r, a[2]*r);
glNormal3fv(c); glVertex3f(c[0]*r, c[1]*r, c[2]*r);
} else {
GLfloat ab[3], ac[3], bc[3];
for (int i=0;i<3;i++) {
ab[i]=(a[i]+b[i])/2;
ac[i]=(a[i]+c[i])/2;
bc[i]=(b[i]+c[i])/2;
}
Normalize(ab); Normalize(ac); Normalize(bc);
DrawTriangle(a, ab, ac, div-1, r);
DrawTriangle(b, bc, ab, div-1, r);
DrawTriangle(c, ac, bc, div-1, r);
DrawTriangle(ab, bc, ac, div-1, r); //<--Comment this line and sphere looks really cool!
}
}
void DrawSphere(int ndiv, float radius) {
glBegin(GL_TRIANGLES);
for (int i=0;i<20;i++) {
DrawTriangle(vdata[tindices[i][0]], vdata[tindices[i][1]], vdata[tindices[i][2]], ndiv, radius);
}
glEnd();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment