3 # Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 # -----------------------------------------------------------------------------
21 # This patch allows running the game on systems without OpenGL support.
23 # It modifies the video portion of the SuperTux engine to render all graphics
24 # with SDL functions only. Many features are removed from the video engine,
25 # so don't expect much.
27 # Installing the patch should be pretty straightforward. Simply run the
28 # following command prior to running autogen.sh and configure:
30 # patch -p0 < contrib/supertux-nogl.diff
32 # This patch works for revision 5070. It may break for later revisions.
34 # -----------------------------------------------------------------------------
35 Index: src/gameconfig.hpp
36 ===================================================================
37 --- src/gameconfig.hpp (revision 5069)
38 +++ src/gameconfig.hpp (working copy)
40 #ifndef SUPERTUX_CONFIG_H
41 #define SUPERTUX_CONFIG_H
58 Index: src/video/drawing_context.cpp
59 ===================================================================
60 --- src/video/drawing_context.cpp (revision 5069)
61 +++ src/video/drawing_context.cpp (working copy)
65 #include <SDL_image.h>
71 +#include "glutil.hpp"
72 #include "drawing_context.hpp"
73 #include "surface.hpp"
76 #include "gameconfig.hpp"
77 -#include "glutil.hpp"
78 #include "texture.hpp"
79 #include "texture_manager.hpp"
80 #include "obstack/obstackpp.hpp"
83 screen = SDL_GetVideoSurface();
86 lightmap_width = screen->w / LIGHTMAP_DIV;
87 lightmap_height = screen->h / LIGHTMAP_DIV;
88 unsigned int width = next_po2(lightmap_width);
90 lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
91 lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
92 texture_manager->register_texture(lightmap);
95 requests = &drawing_requests;
99 obstack_free(&obst, NULL);
102 texture_manager->remove_texture(lightmap);
108 @@ -338,15 +341,31 @@
109 const GetLightRequest* getlightrequest
110 = (GetLightRequest*) request.request_data;
113 - for( int i = 0; i<3; i++)
114 - pixels[i] = 0.0f; //set to black
116 + if(config->use_opengl)
119 + for( int i = 0; i<3; i++)
120 + pixels[i] = 0.0f; //set to black
122 - float posX = request.pos.x * lightmap_width / SCREEN_WIDTH;
123 - float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT;
124 - glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
125 + float posX = request.pos.x * lightmap_width / SCREEN_WIDTH;
126 + float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT;
127 + glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
128 *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]);
129 - //printf("get_light %f/%f =>%f/%f r%f g%f b%f\n", request.pos.x, request.pos.y, posX, posY, pixels[0], pixels[1], pixels[2]);
130 + //printf("get_light %f/%f =>%f/%f r%f g%f b%f\n", request.pos.x, request.pos.y, posX, posY, pixels[0], pixels[1], pixels[2]);
135 + // FIXME: implement properly for SDL
137 + i += 1; i &= 0xFFFF;
139 + *(getlightrequest->color_ptr) = Color(0.0f, 0.0f, 0.0f);
141 + *(getlightrequest->color_ptr) = Color(1.0f, 1.0f, 1.0f);
147 @@ -370,17 +389,50 @@
148 const Color& top = gradientrequest->top;
149 const Color& bottom = gradientrequest->bottom;
151 - glDisable(GL_TEXTURE_2D);
153 - glColor4f(top.red, top.green, top.blue, top.alpha);
155 - glVertex2f(SCREEN_WIDTH, 0);
156 - glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha);
157 - glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
158 - glVertex2f(0, SCREEN_HEIGHT);
160 - glEnable(GL_TEXTURE_2D);
161 - glColor4f(1, 1, 1, 1);
163 + if(config->use_opengl)
165 + glDisable(GL_TEXTURE_2D);
167 + glColor4f(top.red, top.green, top.blue, top.alpha);
169 + glVertex2f(SCREEN_WIDTH, 0);
170 + glColor4f(bottom.red, bottom.green, bottom.blue, bottom.alpha);
171 + glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
172 + glVertex2f(0, SCREEN_HEIGHT);
174 + glEnable(GL_TEXTURE_2D);
175 + glColor4f(1, 1, 1, 1);
180 + for(int y = 0;y < screen->h;++y)
182 + Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255);
183 + Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255);
184 + Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255);
185 + Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255);
186 + Uint32 color = SDL_MapRGB(screen->format, r, g, b);
191 + rect.w = screen->w;
194 + if(a == SDL_ALPHA_OPAQUE) {
195 + SDL_FillRect(screen, &rect, color);
196 + } else if(a != SDL_ALPHA_TRANSPARENT) {
197 + SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
199 + SDL_FillRect(temp, 0, color);
200 + SDL_SetAlpha(temp, SDL_SRCALPHA, a);
201 + SDL_BlitSurface(temp, 0, screen, &rect);
202 + SDL_FreeSurface(temp);
209 @@ -398,29 +450,61 @@
210 const FillRectRequest* fillrectrequest
211 = (FillRectRequest*) request.request_data;
213 - float x = request.pos.x;
214 - float y = request.pos.y;
215 - float w = fillrectrequest->size.x;
216 - float h = fillrectrequest->size.y;
218 + if(config->use_opengl)
220 + float x = request.pos.x;
221 + float y = request.pos.y;
222 + float w = fillrectrequest->size.x;
223 + float h = fillrectrequest->size.y;
225 - glDisable(GL_TEXTURE_2D);
226 - glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
227 - fillrectrequest->color.blue, fillrectrequest->color.alpha);
228 + glDisable(GL_TEXTURE_2D);
229 + glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
230 + fillrectrequest->color.blue, fillrectrequest->color.alpha);
234 - glVertex2f(x+w, y);
235 - glVertex2f(x+w, y+h);
236 - glVertex2f(x, y+h);
238 - glEnable(GL_TEXTURE_2D);
240 - glColor4f(1, 1, 1, 1);
243 + glVertex2f(x+w, y);
244 + glVertex2f(x+w, y+h);
245 + glVertex2f(x, y+h);
247 + glEnable(GL_TEXTURE_2D);
248 + glColor4f(1, 1, 1, 1);
254 + rect.x = (Sint16)request.pos.x;
255 + rect.y = (Sint16)request.pos.y;
256 + rect.w = (Uint16)fillrectrequest->size.x;
257 + rect.h = (Uint16)fillrectrequest->size.y;
258 + Uint8 r = static_cast<Uint8>(fillrectrequest->color.red * 255);
259 + Uint8 g = static_cast<Uint8>(fillrectrequest->color.green * 255);
260 + Uint8 b = static_cast<Uint8>(fillrectrequest->color.blue * 255);
261 + Uint8 a = static_cast<Uint8>(fillrectrequest->color.alpha * 255);
262 + Uint32 color = SDL_MapRGB(screen->format, r, g, b);
263 + if(a == SDL_ALPHA_OPAQUE) {
264 + SDL_FillRect(screen, &rect, color);
265 + } else if(a != SDL_ALPHA_TRANSPARENT) {
266 + SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
268 + SDL_FillRect(temp, 0, color);
269 + SDL_SetAlpha(temp, SDL_SRCALPHA, a);
270 + SDL_BlitSurface(temp, 0, screen, &rect);
271 + SDL_FreeSurface(temp);
278 DrawingContext::draw_lightmap(const DrawingRequest& request) const
280 +DrawingContext::draw_lightmap(const DrawingRequest&) const
284 const Texture* texture = reinterpret_cast<Texture*> (request.request_data);
286 // multiple the lightmap with the framebuffer
290 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
295 @@ -462,29 +547,38 @@
297 // PART1: create lightmap
299 - glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
300 - glMatrixMode(GL_PROJECTION);
302 - glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
303 - glMatrixMode(GL_MODELVIEW);
306 + if(config->use_opengl)
308 + glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
309 + glMatrixMode(GL_PROJECTION);
311 + glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
312 + glMatrixMode(GL_MODELVIEW);
315 - glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
316 - glClear(GL_COLOR_BUFFER_BIT);
317 - handle_drawing_requests(lightmap_requests);
318 - lightmap_requests.clear();
319 + glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
320 + glClear(GL_COLOR_BUFFER_BIT);
321 + handle_drawing_requests(lightmap_requests);
322 + lightmap_requests.clear();
324 - glDisable(GL_BLEND);
325 - glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
326 - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
327 + glDisable(GL_BLEND);
328 + glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
329 + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
331 - glViewport(0, 0, screen->w, screen->h);
332 - glMatrixMode(GL_PROJECTION);
334 - glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
335 - glMatrixMode(GL_MODELVIEW);
337 - glEnable(GL_BLEND);
338 + glViewport(0, 0, screen->w, screen->h);
339 + glMatrixMode(GL_PROJECTION);
341 + glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
342 + glMatrixMode(GL_MODELVIEW);
344 + glEnable(GL_BLEND);
349 + // FIXME: SDL alternative
352 // add a lightmap drawing request into the queue
353 DrawingRequest* request = new(obst) DrawingRequest();
355 drawing_requests.clear();
356 obstack_free(&obst, NULL);
358 - assert_gl("drawing");
360 + if(config->use_opengl)
362 + assert_gl("drawing");
366 // if a screenshot was requested, take one
367 if (screenshot_requested) {
369 screenshot_requested = false;
372 - SDL_GL_SwapBuffers();
374 + if(config->use_opengl)
376 + SDL_GL_SwapBuffers();
385 class RequestPtrCompare
386 @@ -644,36 +752,47 @@
388 // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
390 - // create surface to hold screenshot
391 - #if SDL_BYTEORDER == SDL_BIG_ENDIAN
392 - SDL_Surface* shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
394 - SDL_Surface* shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
397 - log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
400 + SDL_Surface *shot_surf;
402 + if(config->use_opengl)
404 + // create surface to hold screenshot
405 + #if SDL_BYTEORDER == SDL_BIG_ENDIAN
406 + shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
408 + shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
411 + log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
415 - // read pixels into array
416 - char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT];
418 - log_warning << "Could not allocate memory to store screenshot" << std::endl;
419 - SDL_FreeSurface(shot_surf);
422 - glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
423 + // read pixels into array
424 + char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT];
426 + log_warning << "Could not allocate memory to store screenshot" << std::endl;
427 + SDL_FreeSurface(shot_surf);
430 + glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
432 - // copy array line-by-line
433 - for (int i = 0; i < SCREEN_HEIGHT; i++) {
434 - char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
435 - char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
436 - memcpy(dst, src, 3 * SCREEN_WIDTH);
437 + // copy array line-by-line
438 + for (int i = 0; i < SCREEN_HEIGHT; i++) {
439 + char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
440 + char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
441 + memcpy(dst, src, 3 * SCREEN_WIDTH);
450 + shot_surf = SDL_GetVideoSurface();
451 + shot_surf->refcount++;
458 static const std::string writeDir = PHYSFS_getWriteDir();
459 static const std::string dirSep = PHYSFS_getDirSeparator();
460 Index: src/video/texture_manager.hpp
461 ===================================================================
462 --- src/video/texture_manager.hpp (revision 5069)
463 +++ src/video/texture_manager.hpp (working copy)
465 #ifndef __IMAGE_TEXTURE_MANAGER_HPP__
466 #define __IMAGE_TEXTURE_MANAGER_HPP__
469 +#include "glutil.hpp"
473 Index: src/video/texture.cpp
474 ===================================================================
475 --- src/video/texture.cpp (revision 5069)
476 +++ src/video/texture.cpp (working copy)
480 #include "texture.hpp"
481 +#include "gameconfig.hpp"
482 +#include "glutil.hpp"
486 -#include "glutil.hpp"
487 +#include <stdexcept>
489 static inline bool is_power_of_2(int v)
491 return (v & (v-1)) == 0;
495 Texture::Texture(unsigned int w, unsigned int h, GLenum glformat)
497 +Texture::Texture(unsigned int w, unsigned int h, GLenum)
500 assert(is_power_of_2(w));
501 assert(is_power_of_2(h));
503 + use_opengl = config->use_opengl;
509 + surface.opengl.width = w;
510 + surface.opengl.height = h;
512 - assert_gl("before creating texture");
513 - glGenTextures(1, &handle);
514 + assert_gl("before creating texture");
515 + glGenTextures(1, &surface.opengl.handle);
518 - glBindTexture(GL_TEXTURE_2D, handle);
520 + glBindTexture(GL_TEXTURE_2D, surface.opengl.handle);
522 - glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA,
523 - GL_UNSIGNED_BYTE, 0);
524 + glTexImage2D(GL_TEXTURE_2D, 0, glformat, surface.opengl.width,
525 + surface.opengl.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
527 - set_texture_params();
529 - glDeleteTextures(1, &handle);
531 + set_texture_params();
533 + glDeleteTextures(1, &surface.opengl.handle);
545 Texture::Texture(SDL_Surface* image, GLenum glformat)
547 +Texture::Texture(SDL_Surface* image, GLenum)
550 const SDL_PixelFormat* format = image->format;
551 if(!is_power_of_2(image->w) || !is_power_of_2(image->h))
552 - throw std::runtime_error("image has no power of 2 size");
553 + throw std::runtime_error("image does not have power of 2 size");
554 if(format->BitsPerPixel != 24 && format->BitsPerPixel != 32)
555 - throw std::runtime_error("image has no 24 or 32 bit color depth");
556 + throw std::runtime_error("image does not have 24 or 32 bit color depth");
558 + use_opengl = config->use_opengl;
560 - this->width = image->w;
561 - this->height = image->h;
564 + surface.opengl.width = image->w;
565 + surface.opengl.height = image->h;
567 - assert_gl("before creating texture");
568 - glGenTextures(1, &handle);
569 + assert_gl("before creating texture");
570 + glGenTextures(1, &surface.opengl.handle);
574 - if(format->BytesPerPixel == 3)
575 - sdl_format = GL_RGB;
576 - else if(format->BytesPerPixel == 4)
577 - sdl_format = GL_RGBA;
582 + if(format->BytesPerPixel == 3)
583 + sdl_format = GL_RGB;
584 + else if(format->BytesPerPixel == 4)
585 + sdl_format = GL_RGBA;
589 - glBindTexture(GL_TEXTURE_2D, handle);
590 - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
591 - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel);
592 - glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, sdl_format,
593 - GL_UNSIGNED_BYTE, image->pixels);
594 + glBindTexture(GL_TEXTURE_2D, surface.opengl.handle);
595 + glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
596 + glPixelStorei(GL_UNPACK_ROW_LENGTH, image->pitch/format->BytesPerPixel);
597 + glTexImage2D(GL_TEXTURE_2D, 0, glformat, surface.opengl.width,
598 + surface.opengl.height, 0, sdl_format,
599 + GL_UNSIGNED_BYTE, image->pixels);
601 - assert_gl("creating texture");
602 + assert_gl("creating texture");
604 - set_texture_params();
606 - glDeleteTextures(1, &handle);
608 + set_texture_params();
610 + glDeleteTextures(1, &surface.opengl.handle);
617 + surface.sdl = SDL_DisplayFormatAlpha(image);
623 - glDeleteTextures(1, &handle);
627 + glDeleteTextures(1, &surface.opengl.handle);
632 + SDL_FreeSurface(surface.sdl);
637 Texture::set_texture_params()
639 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
640 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
641 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
642 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
646 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
647 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
648 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
649 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
651 - assert_gl("set texture params");
652 + assert_gl("set texture params");
656 Index: src/video/drawing_context.hpp
657 ===================================================================
658 --- src/video/drawing_context.hpp (revision 5069)
659 +++ src/video/drawing_context.hpp (working copy)
665 #include <SDL_video.h>
667 +#include "glutil.hpp"
668 #include "obstack/obstack.h"
669 #include "math/vector.hpp"
670 #include "math/rect.hpp"
671 Index: src/video/glutil.hpp
672 ===================================================================
673 --- src/video/glutil.hpp (revision 5069)
674 +++ src/video/glutil.hpp (working copy)
676 #ifndef __GLUTIL_HPP__
677 #define __GLUTIL_HPP__
686 +#include <GL/glext.h>
688 static inline void check_gl_error(const char* message)
698 +#define GL_SRC_ALPHA 0
699 +#define GL_ONE_MINUS_SRC_ALPHA 1
706 Index: src/video/texture.hpp
707 ===================================================================
708 --- src/video/texture.hpp (revision 5069)
709 +++ src/video/texture.hpp (working copy)
711 #ifndef __TEXTURE_HPP__
712 #define __TEXTURE_HPP__
721 +#include "gameconfig.hpp"
722 +#include "glutil.hpp"
725 * This class is a wrapper around a texture handle. It stores the texture width
726 * and height and provides convenience functions for uploading SDL_Surfaces
731 - friend class TextureManager;
733 - unsigned int width;
734 - unsigned int height;
742 + unsigned int width;
743 + unsigned int height;
753 Texture(unsigned int width, unsigned int height, GLenum glformat);
754 - Texture(SDL_Surface* surface, GLenum glformat);
755 + Texture(SDL_Surface* sdlsurface, GLenum glformat);
758 - GLuint get_handle() const
760 + const GLuint &get_handle() const {
761 + assert(use_opengl);
762 + return surface.opengl.handle;
765 + void set_handle(GLuint handle) {
766 + assert(use_opengl);
767 + surface.opengl.handle = handle;
771 + SDL_Surface *get_surface() const
775 + assert(!use_opengl);
777 + return surface.sdl;
780 + void set_surface(SDL_Surface *sdlsurface)
783 + assert(!use_opengl);
785 + surface.sdl = sdlsurface;
788 unsigned int get_width() const
794 + return surface.opengl.width;
799 + return surface.sdl->w;
803 unsigned int get_height() const
809 + return surface.opengl.height;
814 + return surface.sdl->h;
819 Index: src/video/surface.cpp
820 ===================================================================
821 --- src/video/surface.cpp (revision 5069)
822 +++ src/video/surface.cpp (working copy)
825 texture = texture_manager->get(file);
829 - uv_right = texture->get_uv_right();
830 - uv_bottom = texture->get_uv_bottom();
832 - width = texture->get_image_width();
833 - height = texture->get_image_height();
835 + use_opengl = config->use_opengl;
839 + surface.opengl.uv_left = 0;
840 + surface.opengl.uv_top = 0;
841 + surface.opengl.uv_right = texture->get_uv_right();
842 + surface.opengl.uv_bottom = texture->get_uv_bottom();
844 + surface.opengl.width = texture->get_image_width();
845 + surface.opengl.height = texture->get_image_height();
850 + memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *));
852 + surface.sdl.offsetx = 0;
853 + surface.sdl.offsety = 0;
854 + surface.sdl.width = static_cast<int>(texture->get_image_width());
855 + surface.sdl.height = static_cast<int>(texture->get_image_height());
857 + surface.sdl.flipx = false;
861 Surface::Surface(const std::string& file, int x, int y, int w, int h)
863 texture = texture_manager->get(file);
866 - float tex_w = static_cast<float> (texture->get_width());
867 - float tex_h = static_cast<float> (texture->get_height());
868 - uv_left = static_cast<float>(x) / tex_w;
869 - uv_top = static_cast<float>(y) / tex_h;
870 - uv_right = static_cast<float>(x+w) / tex_w;
871 - uv_bottom = static_cast<float>(y+h) / tex_h;
873 + use_opengl = config->use_opengl;
879 + float tex_w = static_cast<float> (texture->get_width());
880 + float tex_h = static_cast<float> (texture->get_height());
881 + surface.opengl.uv_left = static_cast<float>(x) / tex_w;
882 + surface.opengl.uv_top = static_cast<float>(y) / tex_h;
883 + surface.opengl.uv_right = static_cast<float>(x+w) / tex_w;
884 + surface.opengl.uv_bottom = static_cast<float>(y+h) / tex_h;
886 + surface.opengl.width = w;
887 + surface.opengl.height = h;
892 + memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *));
894 + surface.sdl.offsetx = x;
895 + surface.sdl.offsety = y;
896 + surface.sdl.width = w;
897 + surface.sdl.height = h;
899 + surface.sdl.flipx = false;
903 Surface::Surface(const Surface& other)
905 texture = other.texture;
908 - uv_left = other.uv_left;
909 - uv_top = other.uv_top;
910 - uv_right = other.uv_right;
911 - uv_bottom = other.uv_bottom;
912 - width = other.width;
913 - height = other.height;
915 + use_opengl = config->use_opengl;
919 + surface.opengl.uv_left = other.surface.opengl.uv_left;
920 + surface.opengl.uv_top = other.surface.opengl.uv_top;
921 + surface.opengl.uv_right = other.surface.opengl.uv_right;
922 + surface.opengl.uv_bottom = other.surface.opengl.uv_bottom;
923 + surface.opengl.width = other.surface.opengl.width;
924 + surface.opengl.height = other.surface.opengl.height;
929 + memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *));
931 + surface.sdl.offsetx = other.surface.sdl.offsetx;
932 + surface.sdl.offsety = other.surface.sdl.offsety;
933 + surface.sdl.width = other.surface.sdl.width;
934 + surface.sdl.height = other.surface.sdl.height;
936 + surface.sdl.flipx = other.surface.sdl.flipx;
941 @@ -86,148 +141,329 @@
943 texture = other.texture;
945 - uv_left = other.uv_left;
946 - uv_top = other.uv_top;
947 - uv_right = other.uv_right;
948 - uv_bottom = other.uv_bottom;
949 - width = other.width;
950 - height = other.height;
952 + use_opengl = config->use_opengl;
956 + surface.opengl.uv_left = other.surface.opengl.uv_left;
957 + surface.opengl.uv_top = other.surface.opengl.uv_top;
958 + surface.opengl.uv_right = other.surface.opengl.uv_right;
959 + surface.opengl.uv_bottom = other.surface.opengl.uv_bottom;
960 + surface.opengl.width = other.surface.opengl.width;
961 + surface.opengl.height = other.surface.opengl.height;
966 + memset(transforms, 0, NUM_EFFECTS * sizeof(SDL_Surface *));
968 + surface.sdl.offsetx = other.surface.sdl.offsetx;
969 + surface.sdl.offsety = other.surface.sdl.offsety;
970 + surface.sdl.width = other.surface.sdl.width;
971 + surface.sdl.height = other.surface.sdl.height;
973 + surface.sdl.flipx = other.surface.sdl.flipx;
987 + std::for_each(transforms, transforms + NUM_EFFECTS, SDL_FreeSurface);
994 - std::swap(uv_left, uv_right);
998 + std::swap(surface.opengl.uv_left, surface.opengl.uv_right);
1003 + surface.sdl.flipx = !surface.sdl.flipx;
1007 -static inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top,
1008 - float uv_right, float uv_bottom,
1009 - DrawingEffect effect)
1013 - if(effect & HORIZONTAL_FLIP)
1014 - std::swap(uv_left, uv_right);
1015 - if(effect & VERTICAL_FLIP) {
1016 - std::swap(uv_top, uv_bottom);
1018 + inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top,
1019 + float uv_right, float uv_bottom,
1020 + DrawingEffect effect)
1022 + if(effect & HORIZONTAL_FLIP)
1023 + std::swap(uv_left, uv_right);
1024 + if(effect & VERTICAL_FLIP) {
1025 + std::swap(uv_top, uv_bottom);
1028 - glBegin(GL_QUADS);
1029 - glTexCoord2f(uv_left, uv_top);
1030 - glVertex2f(left, top);
1031 + glBegin(GL_QUADS);
1032 + glTexCoord2f(uv_left, uv_top);
1033 + glVertex2f(left, top);
1035 - glTexCoord2f(uv_right, uv_top);
1036 - glVertex2f(right, top);
1037 + glTexCoord2f(uv_right, uv_top);
1038 + glVertex2f(right, top);
1040 - glTexCoord2f(uv_right, uv_bottom);
1041 - glVertex2f(right, bottom);
1042 + glTexCoord2f(uv_right, uv_bottom);
1043 + glVertex2f(right, bottom);
1045 - glTexCoord2f(uv_left, uv_bottom);
1046 - glVertex2f(left, bottom);
1050 -static inline void intern_draw2(float left, float top, float right, float bottom,
1051 - float uv_left, float uv_top,
1052 - float uv_right, float uv_bottom,
1053 - float angle, float alpha,
1054 - const Color& color,
1055 - const Blend& blend,
1056 - DrawingEffect effect)
1058 - if(effect & HORIZONTAL_FLIP)
1059 - std::swap(uv_left, uv_right);
1060 - if(effect & VERTICAL_FLIP) {
1061 - std::swap(uv_top, uv_bottom);
1062 + glTexCoord2f(uv_left, uv_bottom);
1063 + glVertex2f(left, bottom);
1067 - float center_x = (left + right) / 2;
1068 - float center_y = (top + bottom) / 2;
1069 + inline void intern_draw2(float left, float top, float right, float bottom,
1070 + float uv_left, float uv_top,
1071 + float uv_right, float uv_bottom,
1072 + float angle, float alpha,
1073 + const Color& color,
1074 + const Blend& blend,
1075 + DrawingEffect effect)
1077 + if(effect & HORIZONTAL_FLIP)
1078 + std::swap(uv_left, uv_right);
1079 + if(effect & VERTICAL_FLIP) {
1080 + std::swap(uv_top, uv_bottom);
1083 - float sa = sinf(angle/180.0f*M_PI);
1084 - float ca = cosf(angle/180.0f*M_PI);
1085 + float center_x = (left + right) / 2;
1086 + float center_y = (top + bottom) / 2;
1089 - right -= center_x;
1090 + float sa = sinf(angle/180.0f*M_PI);
1091 + float ca = cosf(angle/180.0f*M_PI);
1094 - bottom -= center_y;
1096 + right -= center_x;
1098 - glBlendFunc(blend.sfactor, blend.dfactor);
1099 - glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
1100 - glBegin(GL_QUADS);
1101 - glTexCoord2f(uv_left, uv_top);
1102 - glVertex2f(left*ca - top*sa + center_x,
1103 - left*sa + top*ca + center_y);
1105 + bottom -= center_y;
1107 - glTexCoord2f(uv_right, uv_top);
1108 - glVertex2f(right*ca - top*sa + center_x,
1109 - right*sa + top*ca + center_y);
1110 + glBlendFunc(blend.sfactor, blend.dfactor);
1111 + glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
1112 + glBegin(GL_QUADS);
1113 + glTexCoord2f(uv_left, uv_top);
1114 + glVertex2f(left*ca - top*sa + center_x,
1115 + left*sa + top*ca + center_y);
1117 - glTexCoord2f(uv_right, uv_bottom);
1118 - glVertex2f(right*ca - bottom*sa + center_x,
1119 - right*sa + bottom*ca + center_y);
1120 + glTexCoord2f(uv_right, uv_top);
1121 + glVertex2f(right*ca - top*sa + center_x,
1122 + right*sa + top*ca + center_y);
1124 - glTexCoord2f(uv_left, uv_bottom);
1125 - glVertex2f(left*ca - bottom*sa + center_x,
1126 - left*sa + bottom*ca + center_y);
1128 + glTexCoord2f(uv_right, uv_bottom);
1129 + glVertex2f(right*ca - bottom*sa + center_x,
1130 + right*sa + bottom*ca + center_y);
1132 - // FIXME: find a better way to restore the blend mode
1133 - glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1134 - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1135 + glTexCoord2f(uv_left, uv_bottom);
1136 + glVertex2f(left*ca - bottom*sa + center_x,
1137 + left*sa + bottom*ca + center_y);
1140 + // FIXME: find a better way to restore the blend mode
1141 + glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1142 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1148 -Surface::draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const
1149 +Surface::draw(float x, float y, float alpha,
1151 + float angle, const Color& color, const Blend& blend,
1153 + float, const Color&, const Blend&,
1155 + DrawingEffect effect) const
1157 - glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1159 - intern_draw2(x, y,
1160 - x + width, y + height,
1161 - uv_left, uv_top, uv_right, uv_bottom,
1170 + glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1171 + intern_draw2(x, y,
1172 + x + surface.opengl.width, y + surface.opengl.height,
1173 + surface.opengl.uv_left, surface.opengl.uv_top,
1174 + surface.opengl.uv_right, surface.opengl.uv_bottom,
1184 + draw_part(0, 0, x, y, surface.sdl.width, surface.sdl.height, alpha, effect);
1189 Surface::draw(float x, float y, float alpha, DrawingEffect effect) const
1191 - glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1195 + glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1196 + glColor4f(1, 1, 1, alpha);
1198 + x + surface.opengl.width, y + surface.opengl.height,
1199 + surface.opengl.uv_left, surface.opengl.uv_top,
1200 + surface.opengl.uv_right, surface.opengl.uv_bottom, effect);
1201 + glColor4f(1, 1, 1, 1);
1206 + draw_part(0, 0, x, y, surface.sdl.width, surface.sdl.height, alpha, effect);
1210 - glColor4f(1, 1, 1, alpha);
1212 - x + width, y + height,
1213 - uv_left, uv_top, uv_right, uv_bottom, effect);
1214 - glColor4f(1, 1, 1, 1);
1217 + SDL_Surface *horz_flip(SDL_Surface *src)
1219 + SDL_Surface *dst = SDL_ConvertSurface(src, src->format, src->flags);
1220 + int bpp = dst->format->BytesPerPixel;
1221 + for(int y = 0;y < dst->h;y++) {
1222 + Uint8 *line = (Uint8 *) dst->pixels + y * dst->pitch;
1223 + for(int x = 0;x < (dst->w / 2);x++) {
1226 + line[3 + x * bpp] ^= line[3 + (dst->w - x - 1) * bpp];
1227 + line[3 + (dst->w - x - 1) * bpp] ^= line[3 + x * bpp];
1228 + line[3 + x * bpp] ^= line[3 + (dst->w - x - 1) * bpp];
1230 + line[2 + x * bpp] ^= line[2 + (dst->w - x - 1) * bpp];
1231 + line[2 + (dst->w - x - 1) * bpp] ^= line[2 + x * bpp];
1232 + line[2 + x * bpp] ^= line[2 + (dst->w - x - 1) * bpp];
1234 + line[1 + x * bpp] ^= line[1 + (dst->w - x - 1) * bpp];
1235 + line[1 + (dst->w - x - 1) * bpp] ^= line[1 + x * bpp];
1236 + line[1 + x * bpp] ^= line[1 + (dst->w - x - 1) * bpp];
1238 + line[0 + x * bpp] ^= line[0 + (dst->w - x - 1) * bpp];
1239 + line[0 + (dst->w - x - 1) * bpp] ^= line[0 + x * bpp];
1240 + line[0 + x * bpp] ^= line[0 + (dst->w - x - 1) * bpp];
1247 + SDL_Surface *vert_flip(SDL_Surface *src)
1249 + SDL_Surface *dst = SDL_ConvertSurface(src, src->format, src->flags);
1250 + int bpp = dst->format->BytesPerPixel;
1251 + for(int x = 0;x < dst->w;x++) {
1252 + Uint8 *rank = (Uint8 *) dst->pixels + x * bpp;
1253 + for(int y = 0;y < (dst->h / 2);y++) {
1256 + rank[3 + y * dst->pitch] ^= rank[3 + (dst->h - y - 1) * dst->pitch];
1257 + rank[3 + (dst->h - y - 1) * dst->pitch] ^= rank[3 + y * dst->pitch];
1258 + rank[3 + y * dst->pitch] ^= rank[3 + (dst->h - y - 1) * dst->pitch];
1260 + rank[2 + y * dst->pitch] ^= rank[2 + (dst->h - y - 1) * dst->pitch];
1261 + rank[2 + (dst->h - y - 1) * dst->pitch] ^= rank[2 + y * dst->pitch];
1262 + rank[2 + y * dst->pitch] ^= rank[2 + (dst->h - y - 1) * dst->pitch];
1264 + rank[1 + y * dst->pitch] ^= rank[1 + (dst->h - y - 1) * dst->pitch];
1265 + rank[1 + (dst->h - y - 1) * dst->pitch] ^= rank[1 + y * dst->pitch];
1266 + rank[1 + y * dst->pitch] ^= rank[1 + (dst->h - y - 1) * dst->pitch];
1268 + rank[0 + y * dst->pitch] ^= rank[0 + (dst->h - y - 1) * dst->pitch];
1269 + rank[0 + (dst->h - y - 1) * dst->pitch] ^= rank[0 + y * dst->pitch];
1270 + rank[0 + y * dst->pitch] ^= rank[0 + (dst->h - y - 1) * dst->pitch];
1279 Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y,
1281 float width, float height, float alpha,
1283 + float width, float height, float,
1285 DrawingEffect effect) const
1287 - float uv_width = uv_right - uv_left;
1288 - float uv_height = uv_bottom - uv_top;
1292 + float uv_width = surface.opengl.uv_right - surface.opengl.uv_left;
1293 + float uv_height = surface.opengl.uv_bottom - surface.opengl.uv_top;
1295 - float uv_left = this->uv_left + (uv_width * src_x) / this->width;
1296 - float uv_top = this->uv_top + (uv_height * src_y) / this->height;
1297 - float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width;
1298 - float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height;
1299 + float uv_left = surface.opengl.uv_left + (uv_width * src_x) / surface.opengl.width;
1300 + float uv_top = surface.opengl.uv_top + (uv_height * src_y) / surface.opengl.height;
1301 + float uv_right = surface.opengl.uv_left + (uv_width * (src_x + width)) / surface.opengl.width;
1302 + float uv_bottom = surface.opengl.uv_top + (uv_height * (src_y + height)) / surface.opengl.height;
1304 - glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1305 + glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1306 + glColor4f(1, 1, 1, alpha);
1307 + intern_draw(dst_x, dst_y,
1308 + dst_x + width, dst_y + height,
1309 + uv_left, uv_top, uv_right, uv_bottom, effect);
1310 + glColor4f(1, 1, 1, 1);
1315 + //FIXME: support parameter "alpha"
1317 + // get and check SDL_Surface
1318 + if (texture->get_surface() == 0) {
1319 + std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
1323 - glColor4f(1, 1, 1, alpha);
1324 - intern_draw(dst_x, dst_y,
1325 - dst_x + width, dst_y + height,
1326 - uv_left, uv_top, uv_right, uv_bottom, effect);
1327 - glColor4f(1, 1, 1, 1);
1328 + if (surface.sdl.flipx) effect = HORIZONTAL_FLIP;
1330 + if(transforms[effect] == 0) {
1333 + transforms[NO_EFFECT] = texture->get_surface();
1334 + transforms[NO_EFFECT]->refcount++;
1336 + case HORIZONTAL_FLIP:
1337 + transforms[HORIZONTAL_FLIP] = horz_flip(texture->get_surface());
1339 + case VERTICAL_FLIP:
1340 + transforms[VERTICAL_FLIP] = vert_flip(texture->get_surface());
1343 + std::cerr << "Warning: No known transformation applies to surface, skipped draw" << std::endl;
1348 + int ox = surface.sdl.offsetx; if (effect == HORIZONTAL_FLIP) ox = static_cast<int>(transforms[effect]->w) - (ox+static_cast<int>(width));
1349 + int oy = surface.sdl.offsety; if (effect == VERTICAL_FLIP) oy = static_cast<int>(transforms[effect]->h) - (oy+static_cast<int>(height));
1350 + // draw surface to screen
1351 + SDL_Surface* screen = SDL_GetVideoSurface();
1354 + srcRect.x = static_cast<int>(ox+src_x);
1355 + srcRect.y = static_cast<int>(oy+src_y);
1356 + srcRect.w = static_cast<int>(width);
1357 + srcRect.h = static_cast<int>(height);
1360 + dstRect.x = static_cast<int>(dst_x);
1361 + dstRect.y = static_cast<int>(dst_y);
1363 + SDL_BlitSurface(transforms[effect], &srcRect, screen, &dstRect);
1366 Index: src/video/texture_manager.cpp
1367 ===================================================================
1368 --- src/video/texture_manager.cpp (revision 5069)
1369 +++ src/video/texture_manager.cpp (working copy)
1373 #include <SDL_image.h>
1375 -#include <GL/glext.h>
1378 #include <stdexcept>
1379 #include "physfs/physfs_sdl.hpp"
1380 #include "image_texture.hpp"
1381 #include "glutil.hpp"
1382 +#include "gameconfig.hpp"
1383 #include "file_system.hpp"
1386 @@ -149,12 +148,16 @@
1388 TextureManager::save_textures()
1390 - glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1391 - glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
1392 - glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1393 - glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1394 - glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
1395 - glPixelStorei(GL_PACK_ALIGNMENT, 1);
1397 + if(config->use_opengl) {
1398 + glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1399 + glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
1400 + glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1401 + glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1402 + glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
1403 + glPixelStorei(GL_PACK_ALIGNMENT, 1);
1406 for(Textures::iterator i = textures.begin(); i != textures.end(); ++i) {
1409 @@ -169,74 +172,90 @@
1411 SavedTexture saved_texture;
1412 saved_texture.texture = texture;
1413 - glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1414 - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
1415 - &saved_texture.width);
1416 - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
1417 - &saved_texture.height);
1418 - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER,
1419 - &saved_texture.border);
1420 - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1421 - &saved_texture.min_filter);
1422 - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1423 - &saved_texture.mag_filter);
1424 - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
1425 - &saved_texture.wrap_s);
1426 - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
1427 - &saved_texture.wrap_t);
1429 + if(config->use_opengl) {
1430 + glBindTexture(GL_TEXTURE_2D, texture->get_handle());
1431 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
1432 + &saved_texture.width);
1433 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT,
1434 + &saved_texture.height);
1435 + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER,
1436 + &saved_texture.border);
1437 + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1438 + &saved_texture.min_filter);
1439 + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1440 + &saved_texture.mag_filter);
1441 + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
1442 + &saved_texture.wrap_s);
1443 + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
1444 + &saved_texture.wrap_t);
1448 size_t pixelssize = saved_texture.width * saved_texture.height * 4;
1449 saved_texture.pixels = new char[pixelssize];
1451 - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1452 - saved_texture.pixels);
1454 + if(config->use_opengl) {
1455 + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1456 + saved_texture.pixels);
1460 saved_textures.push_back(saved_texture);
1462 - glDeleteTextures(1, &(texture->handle));
1463 - texture->handle = 0;
1465 + if(config->use_opengl) {
1466 + glDeleteTextures(1, &(texture->get_handle()));
1467 + texture->set_handle(0);
1469 - assert_gl("retrieving texture for save");
1470 + assert_gl("retrieving texture for save");
1476 TextureManager::reload_textures()
1478 - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1479 - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1480 - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1481 - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1482 - glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
1483 - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1485 + if(config->use_opengl) {
1486 + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1487 + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1488 + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1489 + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1490 + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
1491 + glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1493 - for(std::vector<SavedTexture>::iterator i = saved_textures.begin();
1494 - i != saved_textures.end(); ++i) {
1495 - SavedTexture& saved_texture = *i;
1496 + for(std::vector<SavedTexture>::iterator i = saved_textures.begin();
1497 + i != saved_textures.end(); ++i) {
1498 + SavedTexture& saved_texture = *i;
1501 - glGenTextures(1, &handle);
1502 - assert_gl("creating texture handle");
1504 + glGenTextures(1, &handle);
1505 + assert_gl("creating texture handle");
1507 - glBindTexture(GL_TEXTURE_2D, handle);
1508 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1509 - saved_texture.width, saved_texture.height,
1510 - saved_texture.border, GL_RGBA,
1511 - GL_UNSIGNED_BYTE, saved_texture.pixels);
1512 - delete[] saved_texture.pixels;
1513 - assert_gl("uploading texture pixel data");
1514 + glBindTexture(GL_TEXTURE_2D, handle);
1515 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1516 + saved_texture.width, saved_texture.height,
1517 + saved_texture.border, GL_RGBA,
1518 + GL_UNSIGNED_BYTE, saved_texture.pixels);
1519 + delete[] saved_texture.pixels;
1520 + assert_gl("uploading texture pixel data");
1522 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1523 - saved_texture.min_filter);
1524 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1525 - saved_texture.mag_filter);
1526 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
1527 - saved_texture.wrap_s);
1528 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
1529 - saved_texture.wrap_t);
1530 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1531 + saved_texture.min_filter);
1532 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1533 + saved_texture.mag_filter);
1534 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
1535 + saved_texture.wrap_s);
1536 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
1537 + saved_texture.wrap_t);
1539 - assert_gl("setting texture_params");
1540 - saved_texture.texture->handle = handle;
1541 + assert_gl("setting texture_params");
1542 + saved_texture.texture->set_handle(handle);
1547 saved_textures.clear();
1549 Index: src/video/surface.hpp
1550 ===================================================================
1551 --- src/video/surface.hpp (revision 5069)
1552 +++ src/video/surface.hpp (working copy)
1554 #ifndef __SURFACE_HPP__
1555 #define __SURFACE_HPP__
1557 +#include <config.h>
1561 +#include "gameconfig.hpp"
1562 #include "math/vector.hpp"
1566 /// bitset for drawing effects
1567 enum DrawingEffect {
1568 /** Don't apply anything */
1569 - NO_EFFECT = 0x0000,
1571 /** Draw the Surface upside down */
1572 - VERTICAL_FLIP = 0x0001,
1574 /** Draw the Surface from left to down */
1575 - HORIZONTAL_FLIP = 0x0002,
1583 friend class DrawingContext;
1585 - ImageTexture* texture;
1592 void draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const;
1593 void draw(float x, float y, float alpha, DrawingEffect effect) const;
1594 void draw_part(float src_x, float src_y, float dst_x, float dst_y,
1595 float width, float height,
1596 float alpha, DrawingEffect effect) const;
1600 + ImageTexture* texture;
1622 + int offsetx; /**< Region in ::surface to be used for blitting */
1623 + int offsety; /**< Region in ::surface to be used for blitting */
1624 + int width; /**< Region in ::surface to be used for blitting */
1625 + int height; /**< Region in ::surface to be used for blitting */
1628 + mutable SDL_Surface *transforms[NUM_EFFECTS]; /**< Cache for pre-transformed surfaces */
1631 Surface(const std::string& file);
1632 Surface(const std::string& file, int x, int y, int w, int h);
1633 @@ -75,12 +102,30 @@
1635 float get_width() const
1641 + return surface.opengl.width;
1646 + return surface.sdl.width;
1650 float get_height() const
1656 + return surface.opengl.height;
1661 + return surface.sdl.height;
1666 Index: src/gameconfig.cpp
1667 ===================================================================
1668 --- src/gameconfig.cpp (revision 5069)
1669 +++ src/gameconfig.cpp (working copy)
1673 use_fullscreen = true;
1675 + use_opengl = true;
1679 sound_enabled = true;
1681 const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
1682 if(config_video_lisp) {
1683 config_video_lisp->get("fullscreen", use_fullscreen);
1684 - config_video_lisp->get("vsync", try_vsync);
1686 + config_video_lisp->get("opengl", use_opengl);
1688 + config_video_lisp->get("vsync", try_vsync);
1689 config_video_lisp->get("width", screenwidth);
1690 config_video_lisp->get("height", screenheight);
1691 config_video_lisp->get("aspect_ratio", aspect_ratio);
1694 writer.start_list("video");
1695 writer.write_bool("fullscreen", use_fullscreen);
1697 + writer.write_bool("opengl", use_opengl);
1699 writer.write_bool("vsync", try_vsync);
1700 writer.write_int("width", screenwidth);
1701 writer.write_int("height", screenheight);
1703 ===================================================================
1704 --- src/main.cpp (revision 5069)
1705 +++ src/main.cpp (working copy)
1709 #include <SDL_image.h>
1712 #include "gameconfig.hpp"
1713 #include "resources.hpp"
1714 @@ -383,7 +382,11 @@
1715 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
1716 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
1718 - int flags = SDL_OPENGL;
1720 + int flags = config->use_opengl ? SDL_OPENGL : SDL_SWSURFACE;
1722 + int flags = SDL_SWSURFACE;
1724 if(config->use_fullscreen)
1725 flags |= SDL_FULLSCREEN;
1726 int width = config->screenwidth;
1727 @@ -437,23 +440,28 @@
1729 log_info << (config->use_fullscreen?"fullscreen ":"window ") << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << " Ratio: " << aspect_ratio << "\n";
1731 - // setup opengl state and transform
1732 - glDisable(GL_DEPTH_TEST);
1733 - glDisable(GL_CULL_FACE);
1734 - glEnable(GL_TEXTURE_2D);
1735 - glEnable(GL_BLEND);
1736 - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1738 + if(config->use_opengl)
1740 + // setup opengl state and transform
1741 + glDisable(GL_DEPTH_TEST);
1742 + glDisable(GL_CULL_FACE);
1743 + glEnable(GL_TEXTURE_2D);
1744 + glEnable(GL_BLEND);
1745 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1747 - glViewport(0, 0, screen->w, screen->h);
1748 - glMatrixMode(GL_PROJECTION);
1750 - // logical resolution here not real monitor resolution
1751 - glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
1752 - glMatrixMode(GL_MODELVIEW);
1754 - glTranslatef(0, 0, 0);
1755 + glViewport(0, 0, screen->w, screen->h);
1756 + glMatrixMode(GL_PROJECTION);
1758 + // logical resolution here not real monitor resolution
1759 + glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
1760 + glMatrixMode(GL_MODELVIEW);
1762 + glTranslatef(0, 0, 0);
1764 - check_gl_error("Setting up view matrices");
1765 + check_gl_error("Setting up view matrices");
1769 if(texture_manager != NULL)
1770 texture_manager->reload_textures();
1772 ===================================================================
1773 --- configure.ac (revision 5069)
1774 +++ configure.ac (working copy)
1775 @@ -154,9 +154,15 @@
1776 [AC_MSG_ERROR([Please intall OpenAL])],
1780 -if test "$no_gl" = "yes"; then
1781 - AC_MSG_ERROR([Please install opengl libraries and headers])
1782 +AC_ARG_ENABLE(opengl,
1783 + AC_HELP_STRING([--enable-opengl], [enable opengl support]),
1784 + [enable_opengl=$enableval], [enable_opengl=yes])
1786 +if test "$enable_opengl" = "yes"; then
1788 + if test "$no_gl" != "yes"; then
1789 + AC_DEFINE_UNQUOTED(HAVE_OPENGL, 1, Define if OpenGL is present on the system)
1793 dnl Checks for library functions.