vcglib/apps/sample/trimesh_SDL/mysdl.h

300 lines
8.6 KiB
C
Raw Normal View History

2005-09-21 12:29:33 +02:00
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2005/03/15 07:00:54 ganovell
*** empty log message ***
****************************************************************************/
#include <iostream>
#include <fstream>
#include <SDL/SDL.h>
#include <gl/glew.h>
#include <GL/glu.h>
#include <GL/glut.h>
#ifdef _SHOW_A_MESH
// the trimesh drawer
#include "mesh_type.h"
#include <wrap/gl/trimesh.h>
#endif //_SHOW_A_MESH
#include <wrap/gui/trackball.h>
bool fullscreen = false, quit = false,keepdrawing = true;
int width =1024;
int height = 768;
int x,y;
vcg::GlTrimesh<MyMesh> glWrap;
int drawMode;
int keypress;
int pic_x,pic_y,doPick;
float sc;
MyMesh::FaceType * Pick(int x, int y, int width=4, int height=4);
SDL_Surface *screen = NULL;
vcg::Trackball track;
void gl_print(float x, float y, char *str);
bool init(const std::string &str) {
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
return false;
}
const SDL_VideoInfo *info = SDL_GetVideoInfo();
int bpp = info->vfmt->BitsPerPixel;
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int flags = SDL_OPENGL;
if(fullscreen)
flags |= SDL_FULLSCREEN;
screen = SDL_SetVideoMode(width, height, bpp, flags);
if(!screen) {
return false;
}
SDL_WM_SetIcon(SDL_LoadBMP("inspector.bmp"), NULL);
SDL_WM_SetCaption(str.c_str(), str.c_str());
glDisable(GL_DITHER);
glShadeModel(GL_SMOOTH);
glHint( GL_FOG_HINT, GL_NICEST );
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_LEQUAL );
glDisable(GL_LIGHTING);
glEnableClientState(GL_VERTEX_ARRAY);
#ifdef _SHOW_A_MESH
glWrap.Update();
#endif
return true;
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, width/(float)height, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
glViewport(0,0,width,height);
track.GetView();
track.Apply();
track.Draw();
#ifdef _SHOW_A_MESH
glScalef(1-sc,1-sc,1-sc);
glScalef(1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag());
glTranslate(-glWrap.m->bbox.Center());
// to do some picking
MyMesh::FaceType* fp=NULL;
if(doPick)
{
fp = Pick(pic_x,pic_y,1,1);
doPick=false;
}
// the trimesh drawing calls
switch(drawMode)
{
case 0: glWrap.Draw<vcg::GLW::DMSmooth,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 1: glWrap.Draw<vcg::GLW::DMPoints,vcg::GLW::CMNone,vcg::GLW::TMNone> (); break;
case 2: glWrap.Draw<vcg::GLW::DMWire,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 3: glWrap.Draw<vcg::GLW::DMFlatWire,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 4: glWrap.Draw<vcg::GLW::DMHidden,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 5: glWrap.Draw<vcg::GLW::DMFlat,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 6: break;
}
#endif
// glScalef(scale, scale, scale);
// Point3f center = sphere.Center();
// glTranslatef(-center[0], -center[1], -center[2]);
SDL_GL_SwapBuffers();
}
int sdl_idle() {
SDL_Event event;
while( !quit ) {
unsigned int anything = SDL_PollEvent(&event);
if(!anything && !keepdrawing) {
SDL_WaitEvent(&event);
anything = true;
}
if(anything) {
switch( event.type ) {
case SDL_QUIT: quit = 1; break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_RCTRL:
case SDLK_LCTRL: track.ButtonDown(vcg::Trackball::KEY_CTRL); break;
case SDLK_q: exit(0); break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym) {
case SDLK_RCTRL:
case SDLK_LCTRL:
track.ButtonUp(vcg::Trackball::KEY_CTRL); break;
}
break;
case SDL_MOUSEBUTTONDOWN:
x = event.button.x;
y = height - event.button.y;
#ifdef SDL_BUTTON_WHEELUP
if(event.button.button == SDL_BUTTON_WHEELUP)
track.MouseWheel(1);
else if(event.button.button == SDL_BUTTON_WHEELDOWN)
track.MouseWheel(-1);
else
#endif
if(event.button.button == SDL_BUTTON_LEFT)
track.MouseDown(x, y, vcg::Trackball::BUTTON_LEFT);
else if(event.button.button == SDL_BUTTON_RIGHT)
track.MouseDown(x, y, vcg::Trackball::BUTTON_RIGHT);
break;
case SDL_MOUSEBUTTONUP:
x = event.button.x;
y = height - event.button.y;
if(event.button.button == SDL_BUTTON_LEFT)
track.MouseUp(x, y, vcg::Trackball::BUTTON_LEFT);
else if(event.button.button == SDL_BUTTON_RIGHT)
track.MouseUp(x, y, vcg::Trackball::BUTTON_RIGHT);
break;
case SDL_MOUSEMOTION:
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
x = event.motion.x;
y = height - event.motion.y;
track.MouseMove(x, y);
break;
case SDL_VIDEOEXPOSE:
default: break;
}
}
display();
}
SDL_Quit();
return -1;
}
void gl_print(float x, float y, char *str) {
glRasterPos2f(x, y);
int len = (int)strlen(str);
for(int i = 0; i < len; i++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
}
#ifdef _SHOW_A_MESH
// you can use this funcion replacing the face with your own pickable primitive
MyMesh::FaceType * Pick(int x, int y,int w,int h)
{
long hits;
int sz=glWrap.m->face.size()*5;
unsigned int *selectBuf =new unsigned int[sz];
// static unsigned int selectBuf[16384];
glSelectBuffer(sz, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
/* Because LoadName() won't work with no names on the stack */
glPushName(-1);
double mp[16];
int viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
glMatrixMode(GL_PROJECTION);
glGetDoublev(GL_PROJECTION_MATRIX ,mp);
glPushMatrix();
glLoadIdentity();
//gluPickMatrix(x, viewport[3]-y, 4, 4, viewport);
gluPickMatrix(x, viewport[3]-y, width, height, viewport);
glMultMatrixd(mp);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
int tricnt=0;
MyMesh::FaceIterator ti;
for(ti=glWrap.m->face.begin();ti!=glWrap.m->face.end();++ti)
{
if(!(*ti).IsD())
{
glLoadName(tricnt);
glBegin(GL_TRIANGLES);
glVertex((*ti).P(0));
glVertex((*ti).P(1));
glVertex((*ti).P(2));
glEnd();
}
tricnt++;
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
hits = glRenderMode(GL_RENDER);
//xstring buf;
//if (hits <= 0) return 0;
std::vector< std::pair<double,int> > H;
for(int ii=0;ii<hits;ii++){
//TRACE("%ui %ui %ui %ui\n",selectBuf[ii*4],selectBuf[ii*4+1],selectBuf[ii*4+2],selectBuf[ii*4+3]);
H.push_back( std::pair<double,int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
}
if(H.empty()) return NULL;
std::sort(H.begin(),H.end());
return (MyMesh::FaceType *)&glWrap.m->face[H[0].second];
}
#endif //_SHOW_A_MESH