Mercurial > fife-parpg
view engine/core/video/opengl/renderbackendopengl.cpp @ 146:54b3984e1afc
The getIndex function was a hack that shadowed another bug
that caused the pools to misbehave.
AddResourceFromFile works now exactly as getIndex,
it's just faster.
Fixed GUIImage to not hold a reference, it uses the
index directly anyway.
Plus heaps of minor adjustments for
more informative debug output and statistics.
author | phoku@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Thu, 09 Oct 2008 12:36:21 +0000 |
parents | 18c2a21ac0ad |
children | 66db8ce5dfa2 |
line wrap: on
line source
/*************************************************************************** * Copyright (C) 2005-2008 by the FIFE team * * http://www.fifengine.de * * This file is part of FIFE. * * * * FIFE is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ // Standard C++ library includes // Platform specific includes // 3rd party library includes #include <SDL.h> // FIFE includes #include "util/base/exception.h" #include "fife_opengl.h" #include "glimage.h" #include "renderbackendopengl.h" #include "SDL_image.h" namespace FIFE { RenderBackendOpenGL::RenderBackendOpenGL() : RenderBackend() { // Get the pixelformat we want. SDL_Surface* testsurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 1, 1, 32, RMASK, GMASK, BMASK ,AMASK); m_rgba_format = *(testsurface->format); SDL_FreeSurface(testsurface); } const std::string& RenderBackendOpenGL::getName() const { static std::string backend_name = "OpenGL"; return backend_name; } RenderBackendOpenGL::~RenderBackendOpenGL() { } void RenderBackendOpenGL::init() { Uint32 flags = SDL_INIT_VIDEO; if (SDL_InitSubSystem(flags) < 0) throw SDLException(SDL_GetError()); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // temporary hack } Image* RenderBackendOpenGL::createMainScreen(unsigned int width, unsigned int height, unsigned char bitsPerPixel, bool fs, const std::string& title, const std::string& icon) { delete m_screen; m_screen = 0; Uint32 flags = SDL_OPENGL | SDL_HWPALETTE | SDL_HWACCEL; if ( fs ) { flags |= SDL_FULLSCREEN; } if(icon != "") { SDL_Surface *img = IMG_Load(icon.c_str()); if(img != NULL) { SDL_WM_SetIcon(img, 0); } } SDL_Surface* screen = NULL; if( 0 == bitsPerPixel ) { /// autodetect best mode unsigned char possibleBitsPerPixel[] = {32, 24, 16, 0}; int i = 0; while( true ) { bitsPerPixel = possibleBitsPerPixel[i]; if( !bitsPerPixel ) { throw SDLException("Videomode not available"); } if ( SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) { screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags); if( screen ) { break; } } ++i; } } else { if ( !SDL_VideoModeOK(width, height, bitsPerPixel, flags) ) { throw SDLException("Videomode not available"); } screen = SDL_SetVideoMode(width, height, bitsPerPixel, flags); } SDL_WM_SetCaption(title.c_str(), 0); if (!screen) { throw SDLException(SDL_GetError()); } glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); gluOrtho2D(0, width, height, 0); glMatrixMode(GL_MODELVIEW); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_SCISSOR_TEST); glPointSize(1.0); glLineWidth(1.0); m_screen = new GLImage(screen); return m_screen; } void RenderBackendOpenGL::startFrame() { glClear(GL_COLOR_BUFFER_BIT); } void RenderBackendOpenGL::endFrame() { SDL_GL_SwapBuffers(); } Image* RenderBackendOpenGL::createImage(SDL_Surface* surface) { // Given an abritary surface, we must convert it to the format GLImage will understand. // It's easiest to let SDL do this for us. // Uh. Gotta love this :-) // Check for colorkey too? // Leave out the loss/shift checks? if( m_rgba_format.BitsPerPixel == surface->format->BitsPerPixel && m_rgba_format.Rmask == surface->format->Rmask && m_rgba_format.Gmask == surface->format->Gmask && m_rgba_format.Bmask == surface->format->Bmask && m_rgba_format.Amask == surface->format->Amask && m_rgba_format.Rshift == surface->format->Rshift && m_rgba_format.Gshift == surface->format->Gshift && m_rgba_format.Bshift == surface->format->Bshift && m_rgba_format.Ashift == surface->format->Ashift && m_rgba_format.Rloss == surface->format->Rloss && m_rgba_format.Gloss == surface->format->Gloss && m_rgba_format.Bloss == surface->format->Bloss && m_rgba_format.Aloss == surface->format->Aloss && surface->flags & SDL_SRCALPHA ) { return new GLImage(surface); } SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE|SDL_SRCALPHA); GLImage* image = new GLImage(conv); SDL_FreeSurface( surface ); return image; } Image* RenderBackendOpenGL::createImage(const uint8_t* data, unsigned int width, unsigned int height) { return new GLImage(data, width, height); } bool RenderBackendOpenGL::putPixel(int x, int y, int r, int g, int b) { if ((x < 0) || (x >= (int)getWidth()) || (y < 0) || (y >= (int)getHeight())) { return false; } glColor4ub(r, g, b, 255); glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); std::cout << x << ", "<< y << "\n"; return true; } void RenderBackendOpenGL::drawLine(const Point& p1, const Point& p2, int r, int g, int b) { glColor4ub(r, g, b, 255); glBegin(GL_LINES); glVertex3f(p1.x+0.5f, p1.y+0.5f, 0); glVertex3f(p2.x+0.5f, p2.y+0.5f, 0); glEnd(); glBegin(GL_POINTS); glVertex3f(p2.x+0.5f, p2.y+0.5f, 0); glEnd(); } void RenderBackendOpenGL::drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4, int r, int g, int b) { glColor4ub(r, g, b, 165); glBegin(GL_QUADS); glVertex3f(p1.x, p1.y, 0); glVertex3f(p2.x, p2.y, 0); glVertex3f(p3.x, p3.y, 0); glVertex3f(p4.x, p4.y, 0); glEnd(); } }