Rev 125 | Go to most recent revision | Blame | Last modification | View Log | RSS feed
#include <fstream>
#include "Graphics/GLViewController.h"
#include "Graphics/gel_glut.h"
#include <glui.h>
#include <stack>
#include <iostream>
#include "Util/Timer.h"
#include "Util/ResourceManager.h"
#include "IMesh/TriMesh.h"
#include "IMesh/TriMeshBuilder.h"
#include "IMeshUtil/x3d_load.h"
using namespace std;
using namespace IMesh;
using namespace IMeshUtil;
using namespace Util;
using namespace CGLA;
using namespace GFX;
namespace
{
GLViewController* view_ctrl;
int WINX=800, WINY=800;
int main_window;
int light_follows_cam=true;
float lights_rot[16]={1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
Vec4f light0_pos(0,0,1,0);
int smooth_iter = 8;
ResourcePtr<TriMesh> my_mesh;
class MyClass
{
int x;
public:
MyClass() {}
MyClass(int _x): x(_x) {}
void print() const
{
cout << x << endl;
}
};
}
void draw_imesh(const ResourcePtr<TriMesh>& imesh)
{
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glBegin(GL_TRIANGLES);
glColor3f(0.8,0.8,.2);
for(int i=0;i<imesh->no_faces();++i)
{
glNormal3fv(imesh->vnorm(i,0).get());
glVertex3fv(imesh->vpos(i,0).get());
glNormal3fv(imesh->vnorm(i,1).get());
glVertex3fv(imesh->vpos(i,1).get());
glNormal3fv(imesh->vnorm(i,2).get());
glVertex3fv(imesh->vpos(i,2).get());
}
glEnd();
}
ResourcePtr<TriMesh> create_box()
{
IMesh::TriMeshBuilder bldr;
// Test that clearing is ok
bldr.clear();
// Add all vertices
bldr.add_vpos(Vec3f(0, 0, 0));
bldr.add_vpos(Vec3f(1, 0, 0));
bldr.add_vpos(Vec3f(0, 1, 0));
bldr.add_vpos(Vec3f(1, 1, 0));
bldr.add_vpos(Vec3f(0, 0, 1));
bldr.add_vpos(Vec3f(1, 0, 1));
bldr.add_vpos(Vec3f(0, 1, 1));
bldr.add_vpos(Vec3f(1, 1, 1));
// Add all faces.
bldr.add_face(Vec3i(0, 2, 3));
bldr.add_face(Vec3i(0, 3, 1));
bldr.add_face(Vec3i(5, 7, 6));
bldr.add_face(Vec3i(5, 6, 4));
bldr.add_face(Vec3i(0, 1, 5));
bldr.add_face(Vec3i(0, 5, 4));
bldr.add_face(Vec3i(2, 6, 7));
bldr.add_face(Vec3i(2, 7, 3));
bldr.add_face(Vec3i(0, 4, 6));
bldr.add_face(Vec3i(0, 6, 2));
bldr.add_face(Vec3i(1, 3, 7));
bldr.add_face(Vec3i(1, 7, 5));
// Compute face normals
compute_face_normals(bldr);
// Add smoothing group attributes to all faces.
AttrHandle<int> attrib;
bldr.register_face_attribute("smoothing_group", attrib);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 2);
bldr.add_fattr(attrib, 2);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 8);
bldr.add_fattr(attrib, 8);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 1);
bldr.add_fattr(attrib, 32);
bldr.add_fattr(attrib, 32);
// Compute vertex normals using the smoothing groups
compute_vertex_normals(bldr, attrib);
// Create a new vertex attribute registered to a new face set.
AttrHandle<MyClass> myhandle;
int mfs = bldr.register_face_set();
bldr.register_vertex_attribute("MyClass",myhandle, mfs);
for(int i=0;i<8;++i)
bldr.add_vattr(myhandle, MyClass(i));
// Return a resource pointer to the new trimesh.
ResourcePtr<TriMesh> res_ptr =
register_dynamic_resource("cube", bldr.get_trimesh());
return res_ptr;
}
ResourcePtr<TriMesh> load_mesh(const string& fname)
{
ResourcePtr<TriMesh> res_ptr;
TriMeshBuilder bldr;
if(x3d_load(fname, bldr))
{
compute_face_normals(bldr);
compute_vertex_normals(bldr, 0.95);
res_ptr = register_dynamic_resource(fname, bldr.get_trimesh());
}
return res_ptr;
}
void reshape(int W, int H)
{
view_ctrl->reshape(W,H);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
view_ctrl->reset_projection();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(!light_follows_cam)
view_ctrl->set_gl_modelview();
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glMultMatrixf( lights_rot);
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos.get());
glPopMatrix();
if(light_follows_cam)
view_ctrl->set_gl_modelview();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
draw_imesh(my_mesh);
glutSwapBuffers();
}
void animate()
{
if ( glutGetWindow() != main_window )
glutSetWindow(main_window);
}
void timer(int)
{
if ( glutGetWindow() != main_window )
glutSetWindow(main_window);
view_ctrl->try_spin();
glutPostRedisplay();
glutTimerFunc(20, timer, 0);
}
void mouse(int button, int state, int x, int y)
{
Vec2i pos(x,y);
if (state==GLUT_DOWN)
{
if (button==GLUT_LEFT_BUTTON)
view_ctrl->grab_ball(ROTATE_ACTION,pos);
else if (button==GLUT_MIDDLE_BUTTON)
view_ctrl->grab_ball(ZOOM_ACTION,pos);
else if (button==GLUT_RIGHT_BUTTON)
view_ctrl->grab_ball(PAN_ACTION,pos);
}
else if (state==GLUT_UP)
view_ctrl->release_ball();
}
void motion(int x, int y) {
Vec2i pos(x,y);
view_ctrl->roll_ball(Vec2i(x,y));
}
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case '\033':
my_mesh.relinquish_resource();
ofstream ofs(".meshviewer.trackball",ofstream::binary);
view_ctrl->save(ofs);
ofs.close();
exit(0); break;
}
}
int main(int argc, char** argv)
{
if(argv[1])
my_mesh = load_mesh(argv[1]);
else
{
my_mesh = create_box();
cout << "Should print 4 below" << endl;
AttrHandle<MyClass> h;
my_mesh->get_vattr_handle("MyClass", h);
my_mesh->vattr(h,4).print();
}
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(WINX, WINY);
glutInit(&argc, argv);
main_window = glutCreateWindow("X3D Viewer");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
Vec3f c(0.152875, -4.92971, 0.04389);
float r = 2.14036;
my_mesh->get_bsphere(c,r);
view_ctrl = new GLViewController(WINX,WINY, c,r);
// --------------------------------------------------
// GL Init
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(1.0f, 1.0f, 1.0f, 0.f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// --------------------------------------------------
// creat glui interface.
GLUI *glui = GLUI_Master.create_glui( "GLUI" );
glui->add_checkbox( "Light follows cam ", &light_follows_cam );
glui->add_rotation( "Light direction", lights_rot );
glui->set_main_gfx_window( main_window );
GLUI_Master.set_glutIdleFunc( animate );
glutTimerFunc(20, timer, 0);
glutMainLoop();
return 0;
}