a48  2.0.2
example_gl.cc

This is an example of how to use the ContainerBasedAP derived classes together with how to draw a simple mesh using OpenGL 2.x and GLUT.

See also:
adaptivepolicies.hh
#include <cstdio>
#include <cmath>

#include <iostream>

#include <GL/gl.h>
#include <GL/glut.h>

#include <mesh.hh>
#include <adaptivepolicies.hh>

#define MAX_LEVEL 12

typedef struct {
    char* title; 
    int w, h, id; 
    unsigned int mode; 
} glut_window;

template< class Traits >
class PosVertex : public a48::AdaptiveVertexT< Traits > {
public:
    float pos[3]; unsigned int id;
    float f(float u, float v) { float d = sqrt(u*u + v*v); return .1*sin(10*d); }
};

class GeoTraits {
public:
    typedef PosVertex< GeoTraits > vertex_type;
    typedef a48::AdaptiveFaceT< GeoTraits > face_type;
    typedef a48::AdaptiveHalfedgeT< GeoTraits > halfedge_type;
};

template< class Traits >
class ItemsPolicy : public virtual a48::BaseItemsPolicy< Traits > {

    typedef typename Traits::vertex_type vertex_type;
    typedef typename Traits::halfedge_type halfedge_type;
    typedef typename Traits::face_type face_type;

public:
    float *coords;
    unsigned int *faces;
    unsigned int nv, nf;

    ItemsPolicy() {
        const float c[] = { -1.0,-1.0, 1.0,-1.0, 1.0,1.0, -1.0,1.0 };
        const size_t cs = sizeof(c)/sizeof(float);
        coords = new float[ cs ];
        std::copy(c, c+cs, coords);
        const unsigned int f[] = { 1,3,0, 3,1,2 };
        const size_t fs = sizeof(f)/sizeof(unsigned int);
        faces = new unsigned int[ fs ];
        std::copy(f, f+fs, faces);
        nv = cs/2;
        nf = fs/3;
    }

    ~ItemsPolicy() {
        delete [] coords;
        delete [] faces;
    }

    void set_vertex_attributes(const unsigned int& i, vertex_type *v) {
        float *c = coords + 2*i;
        v->pos[0] = c[0];
        v->pos[1] = c[1];
        v->pos[2] = v->f( c[0], c[1] );
        v->id = i;
    }

    void set_vertex_attributes(vertex_type *v1, const vertex_type *v0) { }
    void set_halfedge_attributes(halfedge_type *h1, const halfedge_type *h0) { }
    void set_halfedge_attributes(halfedge_type *h, halfedge_type *o) { }
    void set_halfedge_attributes(const unsigned int& i, const unsigned int& j, const unsigned int& hi, halfedge_type *h) { }
    void set_face_attributes(face_type *f1, const face_type *f0) { }
    void set_face_attributes(const unsigned int& i, face_type *f) { }

};

template< class Traits >
class StellarPolicy : public virtual a48::BaseStellarPolicy< Traits > {

    typedef typename Traits::vertex_type vertex_type;
    typedef typename Traits::halfedge_type halfedge_type;
    typedef typename Traits::face_type face_type;
    
public:
    ItemsPolicy< Traits > ip;

    void sample_vertex(const halfedge_type *h, vertex_type *v) {
        const vertex_type* org = h->vertex();
        const vertex_type* dst = h->from_vertex();
        float x0, y0, x1, y1;
        x0 = org->pos[0]; y0 = org->pos[1];
        x1 = dst->pos[0]; y1 = dst->pos[1];
        v->pos[0] = 0.5*(x0 + x1);
        v->pos[1] = 0.5*(y0 + y1);
        v->pos[2] = v->f( v->pos[0], v->pos[1] );
        v->id = ip.nv;
        ++ip.nv;
    }

    void sample_vertex(const face_type *f, vertex_type *v) { }
    void remove_vertex(const halfedge_type *h, const vertex_type *v) { }
    void remove_vertex(const face_type *f, const vertex_type *v) { }
    void flip_halfedge(const halfedge_type *h) { }

};

typedef a48::AdaptiveMeshT< GeoTraits > Mesh;


static glut_window win = { (char*)"a48 GL Example", 1024, 1024, 0,
                           GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH };

Mesh* mesh;
a48::UniformLevelAP< GeoTraits > *uap;
a48::RangeLevelAP< GeoTraits > *rap;
unsigned char srange = 0;

std::vector<float> verts;
std::vector<unsigned int> faces;


void init() {

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_ALPHA_TEST);

    glDepthFunc(GL_LESS);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    
    glEnable(GL_MULTISAMPLE);
    glClearColor(1.0, 1.0, 1.0, 1.0);

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(2.0,2.0,3.0, 0.0,0.0,0.0, 0.0,0.0,1.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective( 40.0, 1.0, 0.125, 128.0 );

}

void get_data() {

    verts.clear();
    verts.reserve( mesh->size_of_vertices()*3 );

    unsigned int i = 0;
    for(Mesh::vertex_iterator vit = mesh->vertices_begin(); vit != mesh->vertices_end(); ++vit, ++i){
        Mesh::vertex_type *v = *vit;
        verts.push_back(v->pos[0]);
        verts.push_back(v->pos[1]);
        verts.push_back(v->pos[2]);
        v->id = i;
    }

    faces.clear();
    faces.reserve( mesh->size_of_faces()*3 );

    for(Mesh::face_iterator fit = mesh->faces_begin(); fit != mesh->faces_end(); ++fit){
        Mesh::halfedge_type *h = (*fit)->halfedge();
        faces.push_back(h->vertex()->id);
        h = h->next();
        faces.push_back(h->vertex()->id);
        h = h->next();
        faces.push_back(h->vertex()->id);
    }
}


void glWrite(GLdouble _x, GLdouble _y, const char *_str) {

    glRasterPos2d( _x, _y );

    for (char *s = (char*)_str; *s; s++)
        glutBitmapCharacter( GLUT_BITMAP_HELVETICA_12, *s );

}

void reshape(int _w, int _h) {

    glViewport( 0, 0, win.w = _w, win.h = _h );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 40.0, win.w/(GLdouble)win.h, 0.125, 128.0 );

}


void display(void) {

    char str[256];

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    glColor3d(0.2, 0.1, 0.8);

    sprintf( str, "Choose adaptive policy (u|r): %s", (mesh->get_adaptive_policy() == uap?"UniformLevel":"RangeLevel") );

    glWrite( -0.9, 0.9, str );

    glWrite( -0.9, 0.85, "Choose adaptation level (UP|DOWN)" );
    glWrite( -0.9, 0.8, "Choose min/max range level (LEFT|RIGHT)" );

    if( mesh->get_adaptive_policy() == uap )
        sprintf( str, "Current level: %d", uap->get_target_level() );
    else
        sprintf( str, "Current range: [%s%d, %d%s]", ((srange==0)?"*":" "), rap->get_min_level(), rap->get_max_level(), ((srange==1)?"*":" ") );

    glWrite( -0.9, -0.9, str );

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glColor3d(0.0, 0.0, 0.0);

    glEnableClientState(GL_VERTEX_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, &verts[0]);

    glDrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, &faces[0]);

    glDisableClientState(GL_VERTEX_ARRAY);

    glutSwapBuffers();

}

void update_mesh(void) {
    
    mesh->adapt_refine();
    mesh->adapt_simplify();
    get_data();

}

void special(int key, int x, int y) {

    switch(key) {
    case GLUT_KEY_UP:
        if( mesh->get_adaptive_policy() == uap )
            uap->inc_target_level( MAX_LEVEL );
        else {
            if( srange == 0 ) rap->inc_min_level( MAX_LEVEL );
            else rap->inc_max_level( MAX_LEVEL );
        }
        update_mesh();
        break;
    case GLUT_KEY_DOWN:
        if( mesh->get_adaptive_policy() == uap )
            uap->dec_target_level();
        else {
            if( srange == 0 ) rap->dec_min_level();
            else rap->dec_max_level();
        }
        update_mesh();
        break;
    case GLUT_KEY_LEFT:
        srange = 0;
        break;
    case GLUT_KEY_RIGHT:
        srange = 1;
        break;
    }

    glutPostRedisplay();

}

void keyboard(unsigned char key, int x, int y) {

    switch(key) {
    case 'u': case 'U':
        mesh->set_adaptive_policy( uap );
        update_mesh();
        break;
    case 'r': case 'R':
        mesh->set_adaptive_policy( rap );
        update_mesh();
        break;
    case 'q': case 'Q': case 27:
        glutDestroyWindow( win.id );
        return;
    }

    glutPostRedisplay();

}

float select_range_level(PosVertex< GeoTraits > *v) {

    return (v->pos[2] + .1f) / .2f;

}

int main(int argc, char** argv) {

    StellarPolicy< GeoTraits > sp;
    
    mesh = new Mesh(&sp.ip, &sp);

    uap = new a48::UniformLevelAP< GeoTraits >( mesh, 4 );
    rap = new a48::RangeLevelAP< GeoTraits >( mesh, select_range_level, 5, 12 );

    mesh->set_base( sp.ip.nv, sp.ip.nf, sp.ip.faces );

    mesh->set_adaptive_policy( uap );

    update_mesh();

    glutInit( &argc, argv );
    glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( win.w, win.h );
    glutInitDisplayMode( win.mode );
    win.id = glutCreateWindow( win.title );

    init();

    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutSpecialFunc(special);
    glutKeyboardFunc(keyboard);

    glutMainLoop ();

    delete [] mesh;
    delete [] uap;
    delete [] rap;

    return 0;

}
 All Classes Namespaces Files Functions Typedefs