//FIXME DOCS PARAMETERS vec3 ParticleFieldFunctions::tornado(vec4 pos, Parameters* parameters) { TornadoParameters *theParams = (TornadoParameters *) parameters; float a = theParams->a() ; float b = theParams->b() ; float c = theParams->c() ; vec4 retVal; double theta = getTheta(pos); retVal = vec4( -sin(theta)/a /*100.0*/, 0.001, cos(theta)/b /*100.0*/, 1.0 ) ; retVal = retVal * Angel::RotateY(-M_PI/c /*4.0*/); return xyz(retVal); }
int main(int argc, char** argv) { // If no arguments passed, print usage and exit if (argc == 1) { printf("Usage: %s scenefile.glsf filename.obj [filename.obj, ...]\n\n", argv[0]); exit(0); } // Print the help message each time the program is run. // This provides users with a list of keyboard commands to use. printf("%s", help_msg); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); glutInitContextVersion (3, 2); glutInitContextFlags (GLUT_FORWARD_COMPATIBLE); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(500, 300); glutCreateWindow("Simple Open GL Program"); printf("%s\n%s\n", glGetString(GL_RENDERER), glGetString(GL_VERSION)); glewExperimental = GL_TRUE; glewInit(); SceneState camera; ss = &camera; // Read and parse the scene file readSceneFilename(argv); // Read and parse each object file passed in readObjFilenames(argc, argv); // Add plane to list of objects. Mesh plane("plane.obj", vec4(0.3, 0.3, 0.3, 1.0)); plane.ss = ss; objects.push_back(plane); // Initialize Shaders uniform_color = InitShader("vshader.glsl", "singlecolor.glsl"); glUniform1i(glGetUniformLocation(uniform_color, "disks" ), disks); cel_shading = InitShader("celshader.glsl", "celfragment.glsl"); shadow_shader = InitShader("vshadow.glsl", "fshadow.glsl"); phong_illumination = InitShader("vshader.glsl", "fshader.glsl"); // TODO: Add simple depth shader for rendering shadow texture. cur_program = phong_illumination; // Create manipulators Mesh unit_x("unit_cube.obj", vec4(1.0, 0.0, 0.0, 1.0)); Mesh unit_y(UNIT_CUBE, vec4(0.0, 1.0, 0.0, 1.0)); Mesh unit_z(UNIT_CUBE, vec4(0.0, 0.0, 1.0, 1.0)); // Scale unit_x.scale = unit_y.scale = unit_z.scale = Angel::Scale(0.5, 0.5, 0.5); // Translate unit_x.offset *= Angel::Translate(vec4(0.75, 0.0, 0.0, 0.0)); unit_y.offset *= Angel::Translate(vec4(0.0, 0.75, 0.0, 0.0)); unit_z.offset *= Angel::Translate(vec4(0.0, 0.0, 0.75, 0.0)); // Camera unit_x.ss = ss; unit_y.ss = ss; unit_z.ss = ss; manipulator.push_back(unit_x); manipulator.push_back(unit_y); manipulator.push_back(unit_z); glEnable(GL_DEPTH_TEST); // TODO: Start Shadow Buffers glGenTextures(1, &shadow_texture); glBindTexture(GL_TEXTURE_2D, shadow_texture); // Reserve texture memory glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glGenFramebuffers(1, &shadow_buffer); glBindFramebuffer(GL_FRAMEBUFFER, shadow_buffer); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_texture, 0 ); glDrawBuffer(GL_NONE); // Make sure the frame buffer is good-to-go if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("Framebuffer not OK!\n"); } // Unbind framebuffer until we need to render to it. glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); // TODO: End Shadow Buffers glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); // Print the number of objects 'init-ed' printf("Initialized: %ld objects\n\n", objects.size()); //NOTE: callbacks must go after window is created!!! glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(mouseMotion); glutDisplayFunc(display); if (ss->lens.size() == 4) { glutReshapeFunc(myPerspectiveReshape); } else { glutReshapeFunc(myOrthoReshape); } glutMainLoop(); return(0); }
/* * Handle dragging of mouse for transformations */ void mouseMotion(int x, int y) { GLint dx = (x - start_pos[0]); GLint dy = (start_pos[1] - y); vec4 world_vec = inverse(ss->mv) * vec4(dx, dy, 0.0, 0.0); for (unsigned int i = 0; i < objects.size(); ++i) { if (wireframe_vao == i && new_axis != -1) { switch (mode) { case Translate: switch (axis) { case X: objects[i].translate *= Angel::Translate( 0.01f * world_vec * vec3(1.0, 0.0, 0.0) // X-mask ); break; case Y: objects[i].translate *= Angel::Translate( 0.01f * world_vec * vec3(0.0, 1.0, 0.0) // Y-mask ); break; case Z: objects[i].translate *= Angel::Translate( 0.01f * world_vec * vec3(0.0, 0.0, -1.0) // Z-mask ); break; } for (unsigned int j = 0; j < manipulator.size(); ++j) { manipulator[j].translate = objects[i].translate; } break; case Rotate: switch (axis) { case X: objects[i].rotate = Angel::RotateX( world_vec[0] ) * objects[i].rotate; break; case Y: objects[i].rotate = Angel::RotateY( world_vec[1] ) * objects[i].rotate; break; case Z: objects[i].rotate = Angel::RotateZ( world_vec[2] ) * objects[i].rotate; break; } break; case Scale: vec4 scale = world_vec * 0.005f; vec3 scale_vec = vec3(scale.x, scale.y, scale.z); switch (axis) { case X: objects[i].scale[0][0] += scale_vec[0]; break; case Y: objects[i].scale[1][1] += scale_vec[1]; break; case Z: objects[i].scale[2][2] -= scale_vec[2]; break; } for (short j = 0; j < 3; ++j) { if (objects[i].scale[j][j] < 1.0f) { objects[i].scale[j][j] = 1.0f; } } break; } } } if (mode != Scale) { start_pos[0] = x; start_pos[1] = y; } glutPostRedisplay(); }
void display( void ) { glClearColor( 1.0, 1.0, 1.0, 1.0 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); GLfloat time = (GLfloat) (glutGet(GLUT_ELAPSED_TIME)/1000.0f); light_pos.x = 1.5f + (sin(time) * 2.0f); light_pos.z = 2.0f + (cos(time) / 0.5f); glUniform4fv(glGetUniformLocation(cur_program, "vLight"), 1, light_pos); // Enable the Shadow Framebuffer glBindFramebuffer(GL_FRAMEBUFFER, shadow_buffer); glBindTexture(GL_TEXTURE_2D, shadow_texture); // Move camera to light position, do an orthographic projection. SceneState ls; ls.proj = Ortho(-2.0, 2.0, -2.0, 2.0, 0.01, 10.0); ls.at = vec3(0.0, 0.0, 0.0); ls.up = vec3(0.0, 1.0, 0.0); ls.eye = vec3(light_pos.x, light_pos.y, light_pos.z); ls.mv = LookAt( light_pos, vec4(ls.at, 1.0f), vec4(ls.up, 0.0f) ); //printSceneState(&ls); // Render scene with all objects. for (unsigned int i = 0; i < objects.size(); ++i) { objects[i].ss = &ls; objects[i].draw(shadow_shader); objects[i].ss = ss; } // Disable the Shadow Framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); //glBindTexture(GL_TEXTURE_2D, 0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); // Pass ortho proj of light to shader. Multiplied by bias matrix. // See we want to look up information about vertices in a texture, // but that texture is defined from 0 to height and 0 to width. We // want this in projection bounds. // Pass texture to shader. mat4 bias( 0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0 ); glUniformMatrix4fv( glGetUniformLocation(cur_program, "ShadowView"), 1, GL_TRUE, ls.mv ); glUniformMatrix4fv( glGetUniformLocation(cur_program, "BiasedShadowProjection"), 1, GL_TRUE, bias*ls.proj ); glUniform1i(glGetUniformLocation(cur_program, "shadowMap"), shadow_texture); ss->mv = LookAt( vec4(ss->eye, 1.0f), vec4(ss->at, 1.0f), vec4(ss->up, 0.0f) ); glUniform1i(glGetUniformLocation(cur_program, "disks" ), disks); // Render each loaded object file. for (unsigned int i = 0; i < objects.size(); ++i) { if (wireframe_vao == i) { objects[i].wireframe(uniform_color); // Draw manipulator for (unsigned int j = 0; j < manipulator.size(); ++j) { manipulator[j].translate = objects[i].translate; manipulator[j].draw(uniform_color); } } else { objects[i].draw(cur_program); } } glutSwapBuffers(); }
typedef Angel::vec4 color4; typedef Angel::vec4 point4; GLuint phong_illumination; GLuint uniform_color; GLuint cel_shading; GLuint shadow_shader; GLuint cur_program; GLuint shadow_buffer; GLuint shadow_texture; int disks = 2; vec4 light_pos = vec4(1.5, 1.5, 2.0, 1.0); GLuint wireframe_vao = -1; GLint new_axis = -1; enum Axis { X = 1, Y, Z }; enum Mode { Translate = 1, Rotate, Scale };
/** * Legacy function until I make everything suck less: * Loads a single model from an OBJ and stores it into * a single Object instance. * FIXME: Make object loading suck less. (John Huston) * * @param object The object to add the geometry into. * @param filename the OBJ file to load. */ void loadModelFromFile( Object *object, const char *filename ) { std::string relativePath = Util::getRelativePath(filename); // file input stream std::ifstream in( relativePath.c_str(), std::ios::in ); if ( !in ) { throw std::runtime_error( "Could not open file." ); } vector< vec4 > raw_vertices; vector< vec3 > raw_normals; vector< vec2 > raw_textureUVs; string line; short unsigned numObjects = 0; // parse the .obj file for its data while ( getline( in, line ) ) { // lines beginning with 'v ' have vertices if ( line.substr( 0, 2 ) == "v " ) { raw_vertices.push_back( parseVertex( line ) ); } // 'o ' or 'g ' signify a new object is starting else if ( line.substr( 0, 1 ) == "o" || line.substr( 0, 1 ) == "g" ) { if ( ++numObjects > 1 ) break; } // lines beginning with 'f ' have elements else if ( line.substr( 0, 2 ) == "f " ) { // parse the elements from the .obj line vector< vector< int > > faceElements = parseFaceElements( line ); // put the vertices described by the element vector into the main vertex vector for ( uint i = 0; i < faceElements.at( 0 ).size(); i++ ) { object->_vertices.push_back( raw_vertices.at( faceElements.at( 0 ).at( i ) - 1 ) ); } // do the same for texture elements for ( uint i = 0; i < faceElements.at( 1 ).size(); i++ ) { object->_texUVs.push_back( raw_textureUVs.at( faceElements.at( 1 ).at( i ) - 1 ) ); } // and finally for normal elements for ( uint i = 0; i < faceElements.at( 2 ).size(); i++ ) { object->_normals.push_back( raw_normals.at( faceElements.at( 2 ).at( i ) - 1 ) ); } } // lines beginning with 'vt ' will have UV coords else if ( line.substr( 0, 3 ) == "vt " ) { raw_textureUVs.push_back( parseTextureUV( line ) ); } // lines beginning with 'vn ' will have _normals else if ( line.substr( 0, 3 ) == "vn " ) { raw_normals.push_back( parseNormal( line ) ); } else if ( line[0] == '#' ) { /* ignore comments */ } } if ( object->_texUVs.size() < object->_vertices.size() ) for ( size_t i = 0; i < object->_vertices.size(); ++i ) { object->_colors.push_back(vec4( RAND_FLOAT, RAND_FLOAT, RAND_FLOAT, 1.0 ) ); } for ( size_t i = 0; i < object->_texUVs.size(); ++i ) { Angel::vec2 &txy = object->_texUVs[i]; if ((txy.x < 0.0) || (txy.x > 1.0) || (txy.y < 0.0) || (txy.y > 1.0)) gprint( PRINT_WARNING, "WARNING: Texture UV is out of bounds. (%f,%f)\n", txy.x, txy.y ); if (txy.x < 0.0) txy.x = 0.0; if (txy.x > 1.0) txy.x = 1.0; if (txy.y < 0.0) txy.y = 0.0; if (txy.y > 1.0) txy.y = 1.0; } } // End Object Loader