Subversion Repositories gelsvn

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <fstream>
#include "Graphics/GLViewController.h"
#include <GL/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 CMP;
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;
}