// glut_example.c // Stanford University, CS248, Fall 2000 // // Demonstrates basic use of GLUT toolkit for CS248 video game assignment. // More GLUT details at http://reality.sgi.com/mjk_asd/spec3/spec3.html // Here you'll find examples of initialization, basic viewing transformations, // mouse and keyboard callbacks, menus, some rendering primitives, lighting, // double buffering, Z buffering, and texturing. // // Matt Ginzton -- magi@cs.stanford.edu #include #include #include #include #include const char *vertex_shader_source = "attribute vec4 in_position; \n" "attribute vec4 in_color; \n" "\n" "varying vec4 vVaryingColor; \n" " \n" "void main() \n" "{ \n" " gl_Position = in_position;\n" " vVaryingColor = in_color;\n" "} \n"; const char *fragment_shader_source = "precision mediump float; \n" " \n" "varying vec4 vVaryingColor; \n" " \n" "void main() \n" "{ \n" " gl_FragColor = vVaryingColor; \n" "} \n"; GLfloat vVertices[] = { // front -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f, // point magenta -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white }; GLfloat vColors[] = { // front 0.0f, 0.0f, 1.0f, // blue 1.0f, 0.0f, 1.0f, // magenta 0.0f, 1.0f, 1.0f, // cyan 1.0f, 1.0f, 1.0f, // white }; #define VERTEX_BUFFER_SIZE 0x60000 #define COMPONENTS_PER_VERTEX (3) #define NUM_VERTICES (4) GLint modelviewmatrix_handle; GLint modelviewprojectionmatrix_handle; GLint normalmatrix_handle; GLuint vertex_shader; GLuint fragment_shader; GLuint program; #define VIEWING_DISTANCE_MIN 3.0 #define TEXTURE_ID_CUBE 1 enum { MENU_LIGHTING = 1, MENU_POLYMODE, MENU_TEXTURING, MENU_EXIT }; typedef int BOOL; #define TRUE 1 #define FALSE 0 static BOOL g_bLightingEnabled = TRUE; static BOOL g_bFillPolygons = TRUE; static BOOL g_bTexture = FALSE; static BOOL g_bButton1Down = FALSE; static GLfloat g_fTeapotAngle = 0.0; static GLfloat g_fTeapotAngle2 = 0.0; static GLfloat g_fViewDistance = 3 * VIEWING_DISTANCE_MIN; static GLfloat g_nearPlane = 1; static GLfloat g_farPlane = 1000; static int g_Width = 600; // Initial window width static int g_Height = 600; // Initial window height static int g_yClick = 0; static float g_lightPos[4] = { 10, 10, -100, 1 }; // Position of light #ifdef _WIN32 static DWORD last_idle_time; #else static struct timeval last_idle_time; #endif void DrawCubeFace(float fSize) { fSize /= 2.0; glBegin(GL_QUADS); glVertex3f(-fSize, -fSize, fSize); glTexCoord2f (0, 0); glVertex3f(fSize, -fSize, fSize); glTexCoord2f (1, 0); glVertex3f(fSize, fSize, fSize); glTexCoord2f (1, 1); glVertex3f(-fSize, fSize, fSize); glTexCoord2f (0, 1); glEnd(); } void DrawCubeWithTextureCoords (float fSize) { glPushMatrix(); DrawCubeFace (fSize); glRotatef (90, 1, 0, 0); DrawCubeFace (fSize); glRotatef (90, 1, 0, 0); DrawCubeFace (fSize); glRotatef (90, 1, 0, 0); DrawCubeFace (fSize); glRotatef (90, 0, 1, 0); DrawCubeFace (fSize); glRotatef (180, 0, 1, 0); DrawCubeFace (fSize); glPopMatrix(); } void RenderObjects(void) { float colorBronzeDiff[4] = { 0.8, 0.6, 0.0, 1.0 }; float colorBronzeSpec[4] = { 1.0, 1.0, 0.4, 1.0 }; float colorBlue[4] = { 0.0, 0.2, 1.0, 1.0 }; float colorNone[4] = { 0.0, 0.0, 0.0, 0.0 }; glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Main object (cube) ... transform to its coordinates, and render glRotatef(15, 1, 0, 0); glRotatef(45, 0, 1, 0); glRotatef(g_fTeapotAngle, 0, 0, 1); glMaterialfv(GL_FRONT, GL_DIFFUSE, colorBlue); glMaterialfv(GL_FRONT, GL_SPECULAR, colorNone); glColor4fv(colorBlue); glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_CUBE); DrawCubeWithTextureCoords(1.0); // Child object (teapot) ... relative transform, and render glPushMatrix(); glTranslatef(2, 0, 0); glRotatef(g_fTeapotAngle2, 1, 1, 0); glMaterialfv(GL_FRONT, GL_DIFFUSE, colorBronzeDiff); glMaterialfv(GL_FRONT, GL_SPECULAR, colorBronzeSpec); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); glColor4fv(colorBronzeDiff); glBindTexture(GL_TEXTURE_2D, 0); glutSolidTeapot(0.3); glPopMatrix(); glPopMatrix(); } void display(void) { // Clear frame buffer and depth buffer glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_CULL_FACE); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); glDrawArrays(GL_TRIANGLE_STRIP, 8, 4); glDrawArrays(GL_TRIANGLE_STRIP, 12, 4); glDrawArrays(GL_TRIANGLE_STRIP, 16, 4); glDrawArrays(GL_TRIANGLE_STRIP, 20, 4); // Make sure changes appear onscreen glutSwapBuffers(); } void reshape(GLint width, GLint height) { g_Width = width; g_Height = height; glViewport(0, 0, g_Width, g_Height); } void InitGraphics(void) { GLint ret; printf("GL Extensions \"%s\"\n", glGetString(GL_EXTENSIONS)); vertex_shader = glCreateShader(GL_VERTEX_SHADER); if (!vertex_shader) { exit(1); } glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); glCompileShader(vertex_shader); glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &ret); if (!ret) { char *log; printf("Error: vertex shader compilation failed!:\n"); glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &ret); if (ret > 1) { log = malloc(ret); glGetShaderInfoLog(vertex_shader, ret, NULL, log); printf("%s", log); } exit(1); } else printf("Vertex shader compilation succeeded!\n"); fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); if (!fragment_shader) { exit(1); } glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); glCompileShader(fragment_shader); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &ret); if (!ret) { char *log; printf("Error: fragment shader compilation failed!:\n"); glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &ret); if (ret > 1) { log = malloc(ret); glGetShaderInfoLog(fragment_shader, ret, NULL, log); printf("%s", log); } exit(-1); } else printf("Fragment shader compilation succeeded!\n"); program = glCreateProgram(); if (!program) { printf("Error: failed to create program!\n"); exit(-1); } glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glBindAttribLocation(program, 0, "in_position"); glBindAttribLocation(program, 1, "in_color"); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &ret); if (!ret) { char *log; printf("Error: program linking failed!:\n"); glGetProgramiv(program, GL_INFO_LOG_LENGTH, &ret); if (ret > 1) { log = malloc(ret); glGetProgramInfoLog(program, ret, NULL, log); printf("%s", log); } exit(-1); } else printf("program linking succeeded!\n"); glUseProgram(program); /* Make vertex buffer object */ float vtx_logical[NUM_VERTICES * COMPONENTS_PER_VERTEX * 3]; size_t stride = COMPONENTS_PER_VERTEX * 3; for(int vert=0; vert