00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
00076 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
00077 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00078
00079
int flags;
00080
if(fullscreen) flags = SDL_OPENGL | SDL_FULLSCREEN;
00081
else flags = SDL_OPENGL | SDL_RESIZABLE;
00082
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
00089 initOpenGL();
00090
00091 windowOpen =
true;
00092
00093 SDL_ShowCursor(SDL_DISABLE);
00094
00095 SDL_WM_SetCaption(
"PTF - Psychological Test Framework",
"PTF");
00096
return true;
00097 }
00098
00102
void Graphic::initOpenGL() {
00103
00104 glDisable(GL_CULL_FACE);
00105 glDisable(GL_DEPTH_TEST);
00106 glDisable(GL_LIGHTING);
00107
00108 glShadeModel(GL_SMOOTH);
00109
00110 glViewport(0, 0, width, height);
00111
00112 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00113
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
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
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
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
00297 SDL_Surface* texRes = SDL_CreateRGBSurface(SDL_SWSURFACE,
00298 texFile->w, texFile->h, bits, rmask, gmask, bmask, amask);
00299
00300 SDL_BlitSurface(texFile, &texFile->clip_rect, texRes, &texRes->clip_rect);
00301
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
00313 glLoadIdentity();
00314 glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
00315 glMatrixMode(GL_MODELVIEW);
00316 glFlush();
00317
00318 SDL_FreeSurface(texFile);
00319 SDL_FreeSurface(texRes);
00320
00321 textures.push_back(tex);
00322
00323
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
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 }