00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <SDL.h>
00028
00029
00030 #include "util/base/exception.h"
00031
00032 #include "fife_opengl.h"
00033 #include "glimage.h"
00034 #include "renderbackendopengl.h"
00035 #include "SDL_image.h"
00036
00037 namespace FIFE {
00038
00039 RenderBackendOpenGL::RenderBackendOpenGL(const SDL_Color& colorkey) : RenderBackend(colorkey) {
00040
00041 SDL_Surface* testsurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 1, 1, 32,
00042 RMASK, GMASK, BMASK ,AMASK);
00043
00044 m_rgba_format = *(testsurface->format);
00045 SDL_FreeSurface(testsurface);
00046 }
00047
00048 const std::string& RenderBackendOpenGL::getName() const {
00049 static std::string backend_name = "OpenGL";
00050 return backend_name;
00051 }
00052
00053 RenderBackendOpenGL::~RenderBackendOpenGL() {
00054 }
00055
00056
00057 void RenderBackendOpenGL::init() {
00058 Uint32 flags = SDL_INIT_VIDEO;
00059 if (SDL_InitSubSystem(flags) < 0)
00060 throw SDLException(SDL_GetError());
00061 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00062
00063 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00064 }
00065
00066 Image* RenderBackendOpenGL::createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fs, const std::string& title, const std::string& icon) {
00067 delete m_screen;
00068 m_screen = 0;
00069
00070 Uint32 flags = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL;
00071 if ( fs ) {
00072 flags |= SDL_FULLSCREEN;
00073 }
00074
00075 if(icon != "") {
00076 SDL_Surface *img = IMG_Load(icon.c_str());
00077 if(img != NULL) {
00078 SDL_WM_SetIcon(img, 0);
00079 }
00080 }
00081
00082 SDL_Surface* screen = NULL;
00083
00084 if( 0 == bitsPerPixel ) {
00086 unsigned char possibleBitsPerPixel[] = {32, 24, 16, 0};
00087 int i = 0;
00088 while( true ) {
00089 bitsPerPixel = possibleBitsPerPixel[i];
00090 if( !bitsPerPixel ) {
00091 throw SDLException("Videomode not available");
00092 }
00093
00094 if ( SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) {
00095 screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
00096 if( screen ) {
00097 break;
00098 }
00099 }
00100 ++i;
00101 }
00102 } else {
00103 if ( !SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) {
00104 throw SDLException("Videomode not available");
00105 }
00106 screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags);
00107 }
00108
00109 SDL_WM_SetCaption(title.c_str(), 0);
00110
00111 if (!screen) {
00112 throw SDLException(SDL_GetError());
00113 }
00114
00115 glViewport(0, 0, width, height);
00116 glMatrixMode(GL_PROJECTION);
00117 gluOrtho2D(0, width, height, 0);
00118 glMatrixMode(GL_MODELVIEW);
00119
00120 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00121 glEnable(GL_TEXTURE_2D);
00122 glEnable(GL_BLEND);
00123 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00124
00125 glEnable(GL_SCISSOR_TEST);
00126
00127 glPointSize(1.0);
00128 glLineWidth(1.0);
00129
00130 m_screen = new GLImage(screen);
00131 return m_screen;
00132 }
00133
00134 void RenderBackendOpenGL::startFrame() {
00135 glDisable(GL_SCISSOR_TEST);
00136 glClear(GL_COLOR_BUFFER_BIT);
00137 glEnable(GL_SCISSOR_TEST);
00138 }
00139
00140 void RenderBackendOpenGL::endFrame() {
00141 SDL_GL_SwapBuffers();
00142 }
00143
00144 Image* RenderBackendOpenGL::createImage(SDL_Surface* surface) {
00145
00146
00147
00148
00149
00150
00151 if( m_rgba_format.BitsPerPixel == surface->format->BitsPerPixel
00152 && m_rgba_format.Rmask == surface->format->Rmask
00153 && m_rgba_format.Gmask == surface->format->Gmask
00154 && m_rgba_format.Bmask == surface->format->Bmask
00155 && m_rgba_format.Amask == surface->format->Amask
00156 && m_rgba_format.Rshift == surface->format->Rshift
00157 && m_rgba_format.Gshift == surface->format->Gshift
00158 && m_rgba_format.Bshift == surface->format->Bshift
00159 && m_rgba_format.Ashift == surface->format->Ashift
00160 && m_rgba_format.Rloss == surface->format->Rloss
00161 && m_rgba_format.Gloss == surface->format->Gloss
00162 && m_rgba_format.Bloss == surface->format->Bloss
00163 && m_rgba_format.Aloss == surface->format->Aloss
00164 && surface->flags & SDL_SRCALPHA ) {
00165
00166 return new GLImage(surface);
00167 }
00168
00169 SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE|SDL_SRCALPHA);
00170 GLImage* image = new GLImage(conv);
00171 SDL_FreeSurface( surface );
00172 return image;
00173 }
00174
00175 Image* RenderBackendOpenGL::createImage(const uint8_t* data, unsigned int width, unsigned int height) {
00176 return new GLImage(data, width, height);
00177 }
00178
00179 bool RenderBackendOpenGL::putPixel(int x, int y, int r, int g, int b) {
00180 if ((x < 0) || (x >= (int)getWidth()) || (y < 0) || (y >= (int)getHeight())) {
00181 return false;
00182 }
00183 glColor4ub(r, g, b, 255);
00184 glBegin(GL_POINTS);
00185 glVertex2i(x, y);
00186 glEnd();
00187 return true;
00188 }
00189
00190 void RenderBackendOpenGL::drawLine(const Point& p1, const Point& p2, int r, int g, int b) {
00191 glColor4ub(r, g, b, 255);
00192 glBegin(GL_LINES);
00193 glVertex3f(p1.x+0.5f, p1.y+0.5f, 0);
00194 glVertex3f(p2.x+0.5f, p2.y+0.5f, 0);
00195 glEnd();
00196
00197 glBegin(GL_POINTS);
00198 glVertex3f(p2.x+0.5f, p2.y+0.5f, 0);
00199 glEnd();
00200 }
00201
00202 void RenderBackendOpenGL::drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4, int r, int g, int b) {
00203 glColor4ub(r, g, b, 165);
00204 glBegin(GL_QUADS);
00205 glVertex3f(p1.x, p1.y, 0);
00206 glVertex3f(p2.x, p2.y, 0);
00207 glVertex3f(p3.x, p3.y, 0);
00208 glVertex3f(p4.x, p4.y, 0);
00209 glEnd();
00210 }
00211
00212 void RenderBackendOpenGL::drawVertex(const Point& p, const uint8_t size, int r, int g, int b){
00213
00214 GLfloat width;
00215
00216 glGetFloatv(GL_LINE_WIDTH, &width);
00217 glLineWidth(1.0);
00218
00219 glBegin(GL_LINE_LOOP);
00220 glColor4ub(r, g, b, 255);
00221
00222 glVertex3f(p.x-size, p.y+size, 0);
00223 glVertex3f(p.x+size, p.y+size, 0);
00224 glVertex3f(p.x+size, p.y-size, 0);
00225 glVertex3f(p.x-size, p.y-size, 0);
00226
00227 glEnd();
00228
00229 glLineWidth(width);
00230 }
00231 }