Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

graphic.cpp

Go to the documentation of this file.
00001 // PTF - Psychological Test Framework 00002 // http://ptf.sourceforge.net 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Library General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 #include <ptf/environment/graphic.hpp> 00019 #include <ptf/core/ptfcore.hpp> 00020 #include <SDL_image.h> 00021 #include <math.h> 00022 #include <stdexcept> 00023 00027 Graphic::Graphic() { 00028 windowOpen = false; 00029 } 00030 00034 Graphic::~Graphic() { 00035 // clean up textures 00036 for (int i = 0; i < (int)textures.size(); i++) { 00037 glDeleteTextures(1, &textures[i]); 00038 } 00039 } 00040 00048 bool Graphic::createWindow(int w, int h, bool fullscreen) { 00049 PtfCore::getSingleton().getMessageLog() 00050 << MESSAGE("Initializing graphic system and opening window.\n"); 00051 // initialize SDL graphics 00052 if (SDL_Init(SDL_INIT_VIDEO) < 0) { 00053 PtfCore::getSingleton().getMessageLog() 00054 << ERROR("Graphic initialization failed: ") << SDL_GetError() << "\n"; 00055 throw std::runtime_error("Graphic initialization failed."); 00056 } 00057 // query current video settings 00058 if (SDL_GetVideoInfo() == 0) { 00059 PtfCore::getSingleton().getMessageLog() 00060 << ERROR("Video query failed: ") << SDL_GetError() << "\n"; 00061 throw std::runtime_error("Video query failed."); 00062 } 00063 // set bits per pixel 00064 width = w; 00065 height = h; 00066 if (fullscreen) { 00067 bpp = 32; 00068 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 00069 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 00070 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 00071 } 00072 else { 00073 bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel; 00074 } 00075 // set values for red, green, blue, depth buffer and double buffering 00076 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); 00077 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00078 // set flags 00079 int flags; 00080 if(fullscreen) flags = SDL_OPENGL | SDL_FULLSCREEN; 00081 else flags = SDL_OPENGL | SDL_RESIZABLE; 00082 // set video mode 00083 if ((display = SDL_SetVideoMode(width, height, bpp, flags)) == 0) { 00084 PtfCore::getSingleton().getMessageLog() 00085 << ERROR(" Video mode setup failed: ") << SDL_GetError() << "\n"; 00086 throw std::runtime_error("Video mode setup failed."); 00087 } 00088 // call OpenGL init 00089 initOpenGL(); 00090 // set windowOpen and return 00091 windowOpen = true; 00092 // don't show mouse cursor 00093 SDL_ShowCursor(SDL_DISABLE); 00094 // set window title 00095 SDL_WM_SetCaption("PTF - Psychological Test Framework", "PTF"); 00096 return true; 00097 } 00098 00102 void Graphic::initOpenGL() { 00103 // disable unneeded things 00104 glDisable(GL_CULL_FACE); 00105 glDisable(GL_DEPTH_TEST); 00106 glDisable(GL_LIGHTING); 00107 // select shade model 00108 glShadeModel(GL_SMOOTH); 00109 // setup viewport 00110 glViewport(0, 0, width, height); 00111 // set clear color to black 00112 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 00113 // set orthographic perspective 00114 glMatrixMode(GL_PROJECTION); 00115 glLoadIdentity(); 00116 double wneg = -width / 2.0; 00117 double wpos = -wneg - 1.0; 00118 double hneg = -height / 2.0; 00119 double hpos = -hneg - 1.0; 00120 gluOrtho2D(wneg, wpos, hneg, hpos); 00121 // set modelview matrix 00122 glMatrixMode(GL_MODELVIEW); 00123 glLoadIdentity(); 00124 } 00125 00133 void Graphic::setBGColor(float r, float g, float b) { 00134 glClearColor(r, g, b, 1.0f); 00135 } 00136 00140 void Graphic::drawFixationCross(){ 00141 Point pc1; pc1.x = 0; pc1.y = 10; 00142 Point pc2; pc2.x = 0; pc2.y = -10; 00143 Point pc3; pc3.x = -10; pc3.y = 0; 00144 Point pc4; pc4.x = 10; pc4.y = 0; 00145 clear(); 00146 setFGColor(0.8f, 0.8f, 0.8f); 00147 drawLine(pc1, pc2); 00148 drawLine(pc3, pc4); 00149 } 00150 00156 void Graphic::drawFixationCross(int w, int h){ 00157 int a = w/2; 00158 int b = h/2; 00159 Point pc1; pc1.x = 0; pc1.y = a; 00160 Point pc2; pc2.x = 0; pc2.y = -a; 00161 Point pc3; pc3.x = -b; pc3.y = 0; 00162 Point pc4; pc4.x = b; pc4.y = 0; 00163 clear(); 00164 setFGColor(0.8f, 0.8f, 0.8f); 00165 drawLine(pc1, pc2); 00166 drawLine(pc3, pc4); 00167 } 00168 00175 void Graphic::setFGColor(float r, float g, float b) { 00176 glColor3f(r, g, b); 00177 } 00178 00184 void Graphic::drawLine(Point p1, Point p2) { 00185 glBegin(GL_LINES); 00186 glVertex2f(p1.x, p1.y); 00187 glVertex2f(p2.x, p2.y); 00188 glEnd(); 00189 } 00190 00197 void Graphic::drawTriangle(Point p1, Point p2, Point p3) { 00198 glBegin(GL_TRIANGLES); 00199 glVertex2f(p1.x, p1.y); 00200 glVertex2f(p2.x, p2.y); 00201 glVertex2f(p3.x, p3.y); 00202 glEnd(); 00203 } 00204 00212 void Graphic::drawRectangle(Point p1, Point p2, Point p3, Point p4) { 00213 glBegin(GL_QUADS); 00214 glVertex2f(p1.x, p1.y); 00215 glVertex2f(p2.x, p2.y); 00216 glVertex2f(p3.x, p3.y); 00217 glVertex2f(p4.x, p4.y); 00218 glEnd(); 00219 } 00220 00226 void Graphic::drawUnfilledCircle(Point p, float radius){ 00227 float x, y, r; 00228 glBegin(GL_LINE_STRIP); 00229 for(int i = 0; i <= 360; i++) { 00230 r = M_PI * i / 180.0f; 00231 x = radius * cos(r); 00232 y = radius * sin(r); 00233 glVertex2f(p.x + x, p.y + y); 00234 } 00235 glEnd(); 00236 } 00237 00243 void Graphic::drawCircle(Point p, float radius){ 00244 float x, y, r; 00245 glBegin(GL_TRIANGLE_FAN); 00246 glVertex2f(p.x, p.y); 00247 for(int i = 0; i <= 360; i++) { 00248 r = M_PI * i / 180.0f; 00249 x = radius * cos(r); 00250 y = radius * sin(r); 00251 glVertex2f(p.x + x, p.y + y); 00252 } 00253 glEnd(); 00254 } 00255 00259 void Graphic::clear() { 00260 glClear(GL_COLOR_BUFFER_BIT); 00261 } 00262 00266 void Graphic::swap() { 00267 SDL_GL_SwapBuffers(); 00268 } 00269 00275 int Graphic::addTexture(char* fname) { 00276 // some variables for a 32bit RGBA surface 00277 int bits = 32; 00278 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 00279 int rmask = 0xff000000; 00280 int gmask = 0x00ff0000; 00281 int bmask = 0x0000ff00; 00282 int amask = 0x000000ff; 00283 #else 00284 int rmask = 0x000000ff; 00285 int gmask = 0x0000ff00; 00286 int bmask = 0x00ff0000; 00287 int amask = 0xff000000; 00288 #endif 00289 // load image from file 00290 SDL_Surface* texFile = IMG_Load(fname); 00291 if (texFile == 0) { 00292 PtfCore::getSingleton().getMessageLog() 00293 << ERROR(" Failed to load a texture (") << fname << ").\n"; 00294 throw std::runtime_error("Failed to load a texture."); 00295 } 00296 // create new surface 00297 SDL_Surface* texRes = SDL_CreateRGBSurface(SDL_SWSURFACE, 00298 texFile->w, texFile->h, bits, rmask, gmask, bmask, amask); 00299 // blit surface 00300 SDL_BlitSurface(texFile, &texFile->clip_rect, texRes, &texRes->clip_rect); 00301 // create OpenGL texture 00302 GLuint tex; 00303 glGenTextures(1, &tex); 00304 glBindTexture(GL_TEXTURE_2D, tex); 00305 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 00306 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 00307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 00308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 00309 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texRes->w, texRes->h, 00310 GL_RGBA, GL_UNSIGNED_BYTE, texRes->pixels); 00311 glMatrixMode(GL_TEXTURE); 00312 // rotate texture matrix 00313 glLoadIdentity(); 00314 glRotatef(90.0f, 0.0f, 0.0f, 1.0f); 00315 glMatrixMode(GL_MODELVIEW); 00316 glFlush(); 00317 // clean up 00318 SDL_FreeSurface(texFile); 00319 SDL_FreeSurface(texRes); 00320 // add texture handle 00321 textures.push_back(tex); 00322 // work around - without it OpenGL will display no texture the first 00323 // time used 00324 PointTex pq1; pq1.x = -1; pq1.y = -1; pq1.u = 1.0f; pq1.v = 0.0f; 00325 PointTex pq2; pq2.x = 1; pq2.y = -1; pq2.u = 0.0f; pq2.v = 0.0f; 00326 PointTex pq3; pq3.x = 1; pq3.y = 1; pq3.u = 0.0f; pq3.v = 1.0f; 00327 PointTex pq4; pq4.x = -1; pq4.y = 1; pq4.u = 1.0f; pq4.v = 1.0f; 00328 drawTexturedRectangle(pq1, pq2, pq3, pq4, (int)textures.size() - 1); 00329 clear(); 00330 // return index 00331 return (int)textures.size() - 1; 00332 } 00333 00342 void Graphic::drawTexturedRectangle(PointTex p1, PointTex p2, PointTex p3, PointTex p4, int tex) { 00343 if (tex >= (int)textures.size() || tex < 0) { 00344 PtfCore::getSingleton().getMessageLog() 00345 << ERROR(" Texture doesn't exist (number ") << tex << ").\n"; 00346 throw std::runtime_error("Texture doesn't exist."); 00347 } 00348 glBindTexture(GL_TEXTURE_2D, textures[tex]); 00349 glEnable(GL_TEXTURE_2D); 00350 glBegin(GL_QUADS); 00351 glVertex2f(p1.x, p1.y); glTexCoord2f(p1.u, p1.v); 00352 glVertex2f(p2.x, p2.y); glTexCoord2f(p2.u, p2.v); 00353 glVertex2f(p3.x, p3.y); glTexCoord2f(p3.u, p3.v); 00354 glVertex2f(p4.x, p4.y); glTexCoord2f(p4.u, p4.v); 00355 glEnd(); 00356 glDisable(GL_TEXTURE_2D); 00357 }

Generated on Fri Dec 17 14:54:23 2004 for Psychological Test Framework by doxygen 1.3.8