Skip to content

Instantly share code, notes, and snippets.

@rawrjustin
Created March 15, 2012 10:03
Show Gist options
  • Save rawrjustin/2043412 to your computer and use it in GitHub Desktop.
Save rawrjustin/2043412 to your computer and use it in GitHub Desktop.
asteroids
/**** Basic setup for defining and drawing objects ****/
// Moved to a header for the second and subsequent OpenGL programs
#ifndef __INCLUDEGEOMETRY
#define __INCLUDEGOEMETRY
const int numobjects = 2 ; // ** NEW ** number of objects for buffer
const int numperobj = 3 ;
const int ncolors = 4 ;
GLuint buffers[numperobj*numobjects+ncolors+1] ; // ** NEW ** List of buffers for geometric data
GLuint objects[numobjects] ; // ** NEW ** For each object
GLenum PrimType[numobjects] ;
GLsizei NumElems[numobjects] ;
// ** NEW ** Floor Geometry is specified with a vertex array
// ** NEW ** Same for other Geometry
// The Buffer Offset Macro is from Red Book, page 103, 106
#define BUFFER_OFFSET(bytes) ((GLubyte *) NULL + (bytes))
#define NumberOf(array) (sizeof(array)/sizeof(array[0]))
enum {Vertices, Colors, Elements} ; // For arrays for object
enum {FLOOR, CUBE} ; // For objects, for the floor
const GLubyte floorinds[1][37] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36} } ;
const GLfloat floortex[4][2] = {
{1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}
} ;
void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLfloat * col, GLint sizecol, GLubyte * inds, GLint sizeind, GLenum type) ;
void initobjectnocol(GLuint object, GLfloat * vert, GLint sizevert, GLubyte * inds, GLint sizeind, GLenum type) ;
void drawobject(GLuint object) ;
// This function takes in a vertex, color, index and type array
// And does the initialization for an object.
// The partner function below it draws the object
float random1 = ((float)(rand()%2+1))/10;
float random2 = ((float)(rand()%2+1))/10;
float random3 = ((float)(rand()%2+1))/10;
const GLfloat floorverts[37][3] = {
{.2, .2, 0.0},
{0.0, 0.3, 0.0},
{-.2, .2, 0.0},
{-.35, 0.0, 0.0},
{-.2, -.1, 0.0},
{0.2, -0.2, 0.0},
{.3, 0.0, 0.0},
{random2, 0.0, random1},
{.2, .2, 0.0},
{random2, 0.0, random1},
{0.07, 0.2, random3},
{0.0, 0.3, 0.0},
{0.0, 0.2, random3},
{-random1, 0.0, random2},
{-.2, .2, 0.0},
{-random1, 0.0, random2},
{-random3, random1, .3},
{-.2, -.1, 0.0},
{-random3, random1, .3},
{.13, random2, random3},
{.3, 0.0, 0.0},
{.13, random2, random3},
//negatives
{random2, 0.0, -random1},
{.2, .2, 0.0},
{random2, 0.0, -random1},
{0.07, 0.2, -random3},
{0.0, 0.3, 0.0},
{0.07, 0.2, -random3},
{-random1, 0.0, -random2},
{-.2, .2, 0.0},
{-random1, 0.0, -random2},
{-random3, random1, -.2},
{-.2, -.1, 0.0},
{-random3, random1, -.2},
{.13, random2, -random3},
{.3, 0.0, 0.0},
{.13, random2, -random3},
} ;
void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLubyte * inds, GLint sizeind, GLenum type) {
int offset = object * numperobj ;
glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;
glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;
glEnableClientState(GL_VERTEX_ARRAY) ;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds,GL_STATIC_DRAW);
PrimType[object] = type ;
NumElems[object] = sizeind ;
}
void drawobject(GLuint object) {
int offset = object * numperobj ;
glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ;
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;
glEnableClientState(GL_VERTEX_ARRAY) ;
/*
glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ;
glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ;
glEnableClientState(GL_COLOR_ARRAY) ;
*/
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE ) ;
glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)) ;
}
#endif
/***************************************************************************/
/* This is a simple demo program written for CS 184 by Ravi Ramamoorthi */
/* This program corresponds to the final OpenGL lecture on shading. */
/* */
/* This program draws some simple geometry, a plane with four pillars */
/* textures the ground plane, and adds in a teapot that moves */
/* Lighting effects are also included with fragment shaders */
/* The keyboard function should be clear about the keystrokes */
/* The mouse can be used to zoom into and out of the scene */
/***************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <GL/glut.h>
int mouseoldx, mouseoldy ; // For mouse motion
GLdouble eyeloc = 2.0 ; // Where to look from; initially 0 -2, 2
GLfloat teapotloc = -0.5 ; // ** NEW ** where the teapot is located
GLint animate = 0 ; // ** NEW ** whether to animate or not
GLuint vertexshader, fragmentshader, shaderprogram ; // shaders
GLubyte woodtexture[256][256][3] ; // ** NEW ** texture (from grsites.com)
GLuint texNames[1] ; // ** NEW ** texture buffer
GLuint istex ; // ** NEW ** blend parameter for texturing
GLuint islight ; // ** NEW ** for lighting
GLint texturing = 1 ; // ** NEW ** to turn on/off texturing
GLint lighting = 1 ; // ** NEW ** to turn on/off lighting
/* Variables to set uniform params for lighting fragment shader */
GLuint light0dirn ;
GLuint light0color ;
GLuint light1posn ;
GLuint light1color ;
GLuint ambient ;
GLuint diffuse ;
GLuint specular ;
GLuint shininess ;
const int DEMO = 5 ; // ** NEW ** To turn on and off features
#include "shaders.h"
#include "geometry3.h"
/* New helper transformation function to transform vector by modelview */
void transformvec (const GLfloat input[4], GLfloat output[4]) {
GLfloat modelview[16] ; // in column major order
glGetFloatv(GL_MODELVIEW_MATRIX, modelview) ;
for (int i = 0 ; i < 4 ; i++) {
output[i] = 0 ;
for (int j = 0 ; j < 4 ; j++)
output[i] += modelview[4*j+i] * input[j] ;
}
}
void display(void)
{
// clear all pixels
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
// draw white polygon (square) of unit length centered at the origin
// Note that vertices must generally go counterclockwise
// Change from the first program, in that I just made it white.
// The old OpenGL code of using glBegin... glEnd no longer appears.
// The new version uses vertex buffer objects from init.
// Does the order of drawing matter? What happens if I draw the ground
// after the pillars? I will show this in class
glUniform1i(islight,0) ; // Turn off lighting (except on teapot, later)
drawobject(FLOOR) ;
// Now draw several cubes with different transforms, colors
// I continue to use the deprecated push-pop and matrix mode
// Since it is convenient (or you have to write your own stack).
glMatrixMode(GL_MODELVIEW) ;
// Draw the glut teapot
// This is using deprecated old-style OpenGL certainly
/* New for Demo 3; add lighting effects */
{
const GLfloat one[] = {1, 1, 1, 1};
const GLfloat medium[] = {0.5, 0.5, 0.5, 1};
const GLfloat small[] = {0.2, 0.2, 0.2, 1};
const GLfloat high[] = {100} ;
const GLfloat zero[] = {0.0, 0.0, 0.0, 1.0} ;
const GLfloat light_specular[] = {1, 0.5, 0, 1};
const GLfloat light_specular1[] = {0, 0.5, 1, 1};
const GLfloat light_direction[] = {0.5, 0, 0, 0}; // Dir light 0 in w
const GLfloat light_position1[] = {0, -0.5, 0, 1};
GLfloat light0[4], light1[4] ;
// Set Light and Material properties for the teapot
// Lights are transformed by current modelview matrix.
// The shader can't do this globally.
// So we need to do so manually.
transformvec(light_direction, light0) ;
transformvec(light_position1, light1) ;
glUniform3fv(light0dirn, 1, light0) ;
glUniform4fv(light0color, 1, light_specular) ;
glUniform4fv(light1posn, 1, light1) ;
glUniform4fv(light1color, 1, light_specular1) ;
// glUniform4fv(light1color, 1, zero) ;
glUniform4fv(ambient,1,small) ;
glUniform4fv(diffuse,1,medium) ;
glUniform4fv(specular,1,one) ;
glUniform1fv(shininess,1,high) ;
// Enable and Disable everything around the teapot
// Generally, we would also need to define normals etc.
// But glut already does this for us
if (DEMO > 4)
glUniform1i(islight,lighting) ; // turn on lighting only for teapot.
}
// ** NEW ** Put a teapot in the middle that animates
glColor3f(0.0,1.0,1.0) ; // Deprecated command to set the color
glPushMatrix() ;
// I now transform by the teapot translation for animation
glTranslatef(teapotloc, 0.0, 0.0) ;
// The following two transforms set up and center the teapot
// Remember that transforms right-multiply the stack
glTranslatef(0.0,0.0,0.1) ;
glRotatef(90.0,1.0,0.0,0.0) ;
glUniform1i(islight,0) ; // turn off lighting
glPopMatrix() ;
// Does order of drawing matter?
// What happens if I draw the ground after the pillars?
// I will show this in class.
// drawobject(FLOOR) ;
// don't wait!
// start processing buffered OpenGL routines
glutSwapBuffers() ;
glFlush ();
}
// ** NEW ** in this assignment, is an animation of a teapot
// Hitting p will pause this animation; see keyboard callback
void animation(void) {
teapotloc = teapotloc + 0.0025 ;
if (teapotloc > 0.5) teapotloc = -0.5 ;
glutPostRedisplay() ;
}
// Defines a Mouse callback to zoom in and out
// This is done by modifying gluLookAt
// The actual motion is in mousedrag
// mouse simply sets state for mousedrag
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_UP) {
// Do Nothing ;
}
else if (state == GLUT_DOWN) {
mouseoldx = x ; mouseoldy = y ; // so we can move wrt x , y
}
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{ // Reset gluLookAt
eyeloc = 2.0 ;
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;
glutPostRedisplay() ;
}
}
void mousedrag(int x, int y) {
int yloc = y - mouseoldy ; // We will use the y coord to zoom in/out
eyeloc += 0.005*yloc ; // Where do we look from
if (eyeloc < 0) eyeloc = 0.0 ;
mouseoldy = y ;
/* Set the eye location */
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;
glutPostRedisplay() ;
}
// Defines what to do when various keys are pressed
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 27: // Escape to quit
exit(0) ;
break ;
case 'p': // ** NEW ** to pause/restart animation
animate = !animate ;
if (animate) glutIdleFunc(animation) ;
else glutIdleFunc(NULL) ;
break ;
case 't': // ** NEW ** to turn on/off texturing ;
texturing = !texturing ;
glutPostRedisplay() ;
break ;
case 's': // ** NEW ** to turn on/off shading (always smooth) ;
lighting = !lighting ;
glutPostRedisplay() ;
break ;
default:
break ;
}
}
/* Reshapes the window appropriately */
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Think about the rationale for this choice for gluPerspective
// What would happen if you changed near and far planes?
gluPerspective(30.0, (GLdouble)w/(GLdouble)h, 1.0, 10.0) ;
}
void init (void)
{
/* select clearing color */
glClearColor (0.0, 0.0, 0.0, 0.0);
/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Think about this. Why is the up vector not normalized?
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;
// Initialize the shaders
// vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/tex.vert") ;
// fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/tex.frag") ;
vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/light.vert.glsl") ;
fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/light.frag.glsl") ;
GLuint program = glCreateProgram() ;
shaderprogram = initprogram(vertexshader, fragmentshader) ;
GLint linked;
glGetProgramiv(shaderprogram, GL_LINK_STATUS, &linked) ;
// * NEW * Set up the shader parameter mappings properly for lighting.
islight = glGetUniformLocation(shaderprogram,"islight") ;
light0dirn = glGetUniformLocation(shaderprogram,"light0dirn") ;
light0color = glGetUniformLocation(shaderprogram,"light0color") ;
light1posn = glGetUniformLocation(shaderprogram,"light1posn") ;
light1color = glGetUniformLocation(shaderprogram,"light1color") ;
ambient = glGetUniformLocation(shaderprogram,"ambient") ;
diffuse = glGetUniformLocation(shaderprogram,"diffuse") ;
specular = glGetUniformLocation(shaderprogram,"specular") ;
shininess = glGetUniformLocation(shaderprogram,"shininess") ;
// Set up the Geometry for the scene.
// From OpenGL book pages 103-109
glGenBuffers(numperobj*numobjects+ncolors+1, buffers) ; // 1 for texcoords
initobject(FLOOR, (GLfloat *) floorverts, sizeof(floorverts), (GLubyte *) floorinds, sizeof (floorinds), GL_POLYGON) ;
// initobject(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLfloat *) cubecol, sizeof (cubecol), (GLubyte *) cubeinds, sizeof (cubeinds), GL_QUADS) ;
// Enable the depth test
glEnable(GL_DEPTH_TEST) ;
glDepthFunc (GL_LESS) ; // The default option
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
// Requests the type of buffers (Single, RGB).
// Think about what buffers you would need...
// Request the depth if needed, later swith to double buffer
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Simple Demo with Shaders");
init (); // Always initialize first
// Now, we define callbacks and functions for various tasks.
glutDisplayFunc(display);
glutReshapeFunc(reshape) ;
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse) ;
glutMotionFunc(mousedrag) ;
glutMainLoop(); // Start the main code
return 0; /* ANSI C requires main to return int. */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment