Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/graphics_engine.cc @ 4819

Last change on this file since 4819 was 4817, checked in by patrick, 19 years ago

orxonox/trunk: orxonox is now baseobject, graphicsengine handles events itself and is therefore eventlistener now

File size: 10.9 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
17
18#include "graphics_engine.h"
19#include "resource_manager.h"
20#include "event_handler.h"
21
22#include "debug.h"
23#include "text_engine.h"
24
25#include "ini_parser.h"
26#include "substring.h"
27
28using namespace std;
29
30
31/**
32   \brief standard constructor
33   \todo this constructor is not jet implemented - do it
34*/
35GraphicsEngine::GraphicsEngine ()
36{
37  this->setClassID(CL_GRAPHICS_ENGINE, "GraphicsEngine");
38  this->setName("GraphicsEngine");
39
40  this->isInit = false;
41
42  this->bDisplayFPS = false;
43  this->minFPS = 9999;
44  this->maxFPS = 0;
45
46  this->fullscreenFlag = 0;
47
48//  this->listModes();
49
50  // subscribe the resolutionChanged-event
51  EventHandler::getInstance()->subscribe(this, ES_GAME, EV_VIDEO_RESIZE);
52
53}
54
55/**
56   \brief The Pointer to this GraphicsEngine
57*/
58GraphicsEngine* GraphicsEngine::singletonRef = NULL;
59
60/**
61   \brief destructs the graphicsEngine.
62*/
63GraphicsEngine::~GraphicsEngine ()
64{
65  // delete what has to be deleted here
66  EventHandler::getInstance()->unsubscribe(this);
67}
68
69int GraphicsEngine::init()
70{
71  this->initVideo(640,480,16);
72}
73
74/**
75   \brief initializes the Video for openGL.
76
77   This has to be done only once when starting orxonox.
78*/
79int GraphicsEngine::initVideo(unsigned int resX, unsigned int resY, unsigned int bbp)
80{
81  if (this->isInit)
82    return -1;
83  // initialize SDL_VIDEO
84  if (SDL_Init(SDL_INIT_VIDEO) == -1)
85    {
86      PRINTF(1)("could not initialize SDL Video\n");
87      //      return -1;
88    }
89  // initialize SDL_GL-settings
90  this->setGLattribs();
91
92  // setting the Video Flags.
93  this->videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE | SDL_DOUBLEBUF;
94
95  /* query SDL for information about our video hardware */
96  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
97  if( videoInfo == NULL)
98    {
99      PRINTF(1)("Failed getting Video Info :%s\n", SDL_GetError());
100      SDL_Quit ();
101    }
102  if( videoInfo->hw_available)
103    this->videoFlags |= SDL_HWSURFACE;
104  else
105    this->videoFlags |= SDL_SWSURFACE;
106  /*
107  if(VideoInfo -> blit_hw)
108    VideoFlags |= SDL_HWACCEL;
109  */
110    // setting up the Resolution
111  this->setResolution(resX, resY, bbp);
112
113  // TO DO: Create a cool icon and use it here
114  char* loadPic = new char[strlen(ResourceManager::getInstance()->getDataDir())+ 100];
115  sprintf(loadPic, "%s%s", ResourceManager::getInstance()->getDataDir(),  "pictures/orxonox-icon32x32.bmp");
116  SDL_WM_SetIcon(SDL_LoadBMP(loadPic), NULL);
117  delete loadPic;
118  // Enable default GL stuff
119  glEnable(GL_DEPTH_TEST);
120
121  this->isInit = true;
122}
123
124/**
125 * loads the GraphicsEngine's settings from a given ini-file and section
126 * @param iniParser the iniParser to load from
127 * @param section the Section in the ini-file to load from
128 * @returns nothing usefull
129 */
130int GraphicsEngine::initFromIniFile(IniParser* iniParser)
131{
132  // searching for a usefull resolution
133  SubString resolution(iniParser->getVar(CONFIG_NAME_RESOLUTION, CONFIG_SECTION_VIDEO, "640x480"), 'x');
134  this->initVideo(atoi(resolution.getString(0)), atoi(resolution.getString(1)), 16);
135
136  // looking if we are in fullscreen-mode
137  const char* fullscreen = iniParser->getVar(CONFIG_NAME_FULLSCREEN, CONFIG_SECTION_VIDEO, "0");
138  if (strchr(fullscreen, '1'))
139    this->setFullscreen(true);
140
141  // looking if we are in fullscreen-mode
142  const char* textures = iniParser->getVar(CONFIG_NAME_TEXTURES, CONFIG_SECTION_VIDEO_ADVANCED, "0");
143  if (strchr(textures, '1'))
144    this->texturesEnabled = true;
145  else
146    this->texturesEnabled = false;
147
148}
149
150
151
152/**
153 * sets the Window Captions and the Name of the icon.
154 * @param windowName The name of the Window
155 * @param icon The name of the Icon on the Disc
156 */
157void GraphicsEngine::setWindowName(const char* windowName, const char* icon)
158{
159  // Set window labeling
160  SDL_WM_SetCaption (windowName, icon);
161}
162
163
164/**
165   \brief Sets the GL-attributes
166*/
167int GraphicsEngine::setGLattribs()
168{
169  // Set video mode
170  // TO DO: parse arguments for settings
171  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
172  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
173  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
174  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
175
176
177  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
178  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
179  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
180  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
181  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
182  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
183  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
184}
185
186/**
187   \brief sets the Resolution of the Screen to display the Graphics to.
188   \param width The width of the window
189   \param height The height of the window
190   \param bpp bits per pixel
191*/
192int GraphicsEngine::setResolution(int width, int height, int bpp)
193{
194  this->resolutionX = width;
195  this->resolutionY = height;
196  this->bitsPerPixel = bpp;
197
198  if((this->screen = SDL_SetVideoMode(this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags | this->fullscreenFlag)) == NULL)
199    {
200      PRINTF(1)("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags, SDL_GetError());
201      SDL_Quit();
202      //    return -1;
203    }
204}
205
206/**
207   \brief sets Fullscreen mode
208   \param fullscreen true if fullscreen, false if windowed
209*/
210void GraphicsEngine::setFullscreen(bool fullscreen)
211{
212  if (fullscreen)
213    fullscreenFlag = SDL_FULLSCREEN;
214  else
215    fullscreenFlag = 0;
216  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
217}
218
219/**
220   \brief sets the background color
221   \param red the red part of the background
222   \param blue the blue part of the background
223   \param green the green part of the background
224   \param alpha the alpha part of the background
225*/
226void GraphicsEngine::setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
227{
228  glClearColor(red, green, blue, alpha);
229}
230
231
232/**
233   \brief Signalhandler, for when the resolution has changed
234   \param resizeInfo SDL information about the size of the new screen size
235*/
236int GraphicsEngine::resolutionChanged(const SDL_ResizeEvent& resizeInfo)
237{
238  this->setResolution(resizeInfo.w, resizeInfo.h, this->bitsPerPixel);
239}
240
241/**
242   \brief if Textures should be enabled
243*/
244bool GraphicsEngine::texturesEnabled = true;
245
246
247
248/**
249   \brief entering 2D Mode
250
251   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
252*/
253void GraphicsEngine::enter2DMode()
254{
255  GraphicsEngine::storeMatrices();
256  SDL_Surface *screen = SDL_GetVideoSurface();
257
258  /* Note, there may be other things you need to change,
259     depending on how you have your OpenGL state set up.
260  */
261  glPushAttrib(GL_ENABLE_BIT);
262  glDisable(GL_DEPTH_TEST);
263  glDisable(GL_CULL_FACE);
264  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
265  glEnable(GL_TEXTURE_2D);
266
267  /* This allows alpha blending of 2D textures with the scene */
268  glEnable(GL_BLEND);
269  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
270
271  glViewport(0, 0, screen->w, screen->h);
272
273  glMatrixMode(GL_PROJECTION);
274  glPushMatrix();
275  glLoadIdentity();
276
277  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
278
279  glMatrixMode(GL_MODELVIEW);
280  glPushMatrix();
281  glLoadIdentity();
282
283  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
284}
285
286/**
287   \brief leaves the 2DMode again also \see Font::enter2DMode()
288*/
289void GraphicsEngine::leave2DMode()
290{
291  glMatrixMode(GL_MODELVIEW);
292  glPopMatrix();
293
294  glMatrixMode(GL_PROJECTION);
295  glPopMatrix();
296
297  glPopAttrib();
298}
299
300/**
301   \brief stores the GL_matrices
302*/
303void GraphicsEngine::storeMatrices()
304{
305  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
306  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
307  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
308}
309
310//! the stored ModelView Matrix.
311GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
312//! the stored Projection Matrix
313GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
314//! The ViewPort
315GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
316
317
318
319/**
320   \brief outputs all the Fullscreen modes.
321*/
322void GraphicsEngine::listModes()
323{
324  /* Get available fullscreen/hardware modes */
325  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
326
327  /* Check is there are any modes available */
328  if(this->videoModes == (SDL_Rect **)0){
329    PRINTF(1)("No modes available!\n");
330    exit(-1);
331  }
332
333  /* Check if our resolution is restricted */
334  if(this->videoModes == (SDL_Rect **)-1){
335    PRINTF(2)("All resolutions available.\n");
336  }
337  else{
338    /* Print valid modes */
339    PRINT(0)("Available Resoulution Modes are\n");
340    for(int i = 0; this->videoModes[i]; ++i)
341      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
342  }
343}
344
345/**
346   \brief ticks the Text
347   \param dt the time passed
348*/
349void GraphicsEngine::tick(float dt)
350{
351  if( unlikely(this->bDisplayFPS))
352    {
353      this->currentFPS = 1.0/dt;
354      if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
355      if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
356
357#ifndef NO_TEXT
358      char tmpChar1[20];
359      sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
360      this->geTextCFPS->setText(tmpChar1);
361      char tmpChar2[20];
362      sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
363      this->geTextMaxFPS->setText(tmpChar2);
364      char tmpChar3[20];
365      sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
366      this->geTextMinFPS->setText(tmpChar3);
367#endif /* NO_TEXT */
368    }
369}
370
371/**
372   \brief displays the Frames per second
373   \param display if the text should be displayed
374
375   \todo this is dangerous
376*/
377void GraphicsEngine::displayFPS(bool display)
378{
379  if( display)
380    {
381#ifndef NO_TEXT
382      this->geTextCFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
383      this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
384      this->geTextCFPS->setPosition(5, 500);
385      this->geTextMaxFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 15, TEXT_DYNAMIC, 0, 255, 0);
386      this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
387      this->geTextMaxFPS->setPosition(5, 530);
388      this->geTextMinFPS = TextEngine::getInstance()->createText("fonts/arial_black.ttf", 35, TEXT_DYNAMIC, 0, 255, 0);
389      this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
390      this->geTextMinFPS->setPosition(5, 560);
391#endif /* NO_TEXT */
392    }
393  this->bDisplayFPS = display;
394}
395
396
397/**
398  \brief processes the events for orxonox main class
399  \param the event to handle
400 */
401void GraphicsEngine::process(const Event &event)
402{
403  switch (event.type)
404  {
405    case EV_VIDEO_RESIZE:
406      this->resolutionChanged(event.resize);
407      break;
408  }
409
410}
411
Note: See TracBrowser for help on using the repository browser.