src/video/gl/gl_lightmap.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "video/gl/gl_lightmap.hpp"
00018 
00019 #include <SDL_image.h>
00020 #include <algorithm>
00021 #include <assert.h>
00022 #include <functional>
00023 #include <iomanip>
00024 #include <iostream>
00025 #include <math.h>
00026 #include <physfs.h>
00027 #include <sstream>
00028 
00029 #include "supertux/gameconfig.hpp"
00030 #include "supertux/globals.hpp"
00031 #include "util/obstackpp.hpp"
00032 #include "video/drawing_context.hpp"
00033 #include "video/drawing_request.hpp"
00034 #include "video/font.hpp"
00035 #include "video/gl/gl_surface_data.hpp"
00036 #include "video/gl/gl_renderer.hpp"
00037 #include "video/gl/gl_texture.hpp"
00038 #include "video/glutil.hpp"
00039 #include "video/lightmap.hpp"
00040 #include "video/renderer.hpp"
00041 #include "video/surface.hpp"
00042 #include "video/texture_manager.hpp"
00043 
00044 GLLightmap::GLLightmap() :
00045   screen(),
00046   lightmap(),
00047   lightmap_width(),
00048   lightmap_height(),
00049   lightmap_uv_right(),
00050   lightmap_uv_bottom()
00051 {
00052   screen = SDL_GetVideoSurface();
00053 
00054   lightmap_width = SCREEN_WIDTH / LIGHTMAP_DIV;
00055   lightmap_height = SCREEN_HEIGHT / LIGHTMAP_DIV;
00056   unsigned int width = next_po2(lightmap_width);
00057   unsigned int height = next_po2(lightmap_height);
00058 
00059   lightmap.reset(new GLTexture(width, height));
00060 
00061   lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
00062   lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
00063   texture_manager->register_texture(lightmap.get());
00064 }
00065 
00066 GLLightmap::~GLLightmap()
00067 {
00068 }
00069 
00070 void
00071 GLLightmap::start_draw(const Color &ambient_color)
00072 {
00073   
00074   glGetFloatv(GL_VIEWPORT, old_viewport); //save viewport
00075   glViewport(old_viewport[0], SCREEN_HEIGHT - lightmap_height + old_viewport[1], lightmap_width, lightmap_height);
00076   glMatrixMode(GL_PROJECTION);
00077   glLoadIdentity();
00078 #ifdef GL_VERSION_ES_CM_1_0
00079   glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
00080 #else
00081   glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
00082 #endif
00083   glMatrixMode(GL_MODELVIEW);
00084   glLoadIdentity();
00085 
00086   glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
00087   glClear(GL_COLOR_BUFFER_BIT);
00088 }
00089 
00090 void
00091 GLLightmap::end_draw()
00092 {
00093   glDisable(GL_BLEND);
00094   glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
00095   glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, old_viewport[0], SCREEN_HEIGHT  - lightmap_height + old_viewport[1], lightmap_width, lightmap_height);
00096   
00097   glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]);
00098   glMatrixMode(GL_PROJECTION);
00099   glLoadIdentity();
00100 #ifdef GL_VERSION_ES_CM_1_0
00101   glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
00102 #else
00103   glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
00104 #endif
00105   glMatrixMode(GL_MODELVIEW);
00106   glLoadIdentity();
00107   glEnable(GL_BLEND);
00108   //glClear(GL_COLOR_BUFFER_BIT);
00109 }
00110 
00111 void
00112 GLLightmap::do_draw()
00113 {
00114   // multiple the lightmap with the framebuffer
00115   glBlendFunc(GL_DST_COLOR, GL_ZERO);
00116 
00117   glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
00118 
00119   float vertices[] = {
00120     0, 0,
00121     SCREEN_WIDTH, 0,
00122     SCREEN_WIDTH, SCREEN_HEIGHT,
00123     0, SCREEN_HEIGHT
00124   };
00125   glVertexPointer(2, GL_FLOAT, 0, vertices);
00126 
00127   float uvs[] = {
00128     0,                 lightmap_uv_bottom,
00129     lightmap_uv_right, lightmap_uv_bottom,
00130     lightmap_uv_right, 0,
00131     0, 0
00132   };
00133   glTexCoordPointer(2, GL_FLOAT, 0, uvs);
00134 
00135   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
00136 
00137   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00138 }
00139 
00140 void
00141 GLLightmap::draw_surface(const DrawingRequest& request)
00142 {
00143   const Surface* surface = (const Surface*) request.request_data;
00144   boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
00145   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
00146 
00147   glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
00148   intern_draw(request.pos.x, request.pos.y,
00149               request.pos.x + surface->get_width(),
00150               request.pos.y + surface->get_height(),
00151               surface_data->get_uv_left(),
00152               surface_data->get_uv_top(),
00153               surface_data->get_uv_right(),
00154               surface_data->get_uv_bottom(),
00155               request.angle,
00156               request.alpha,
00157               request.color,
00158               request.blend,
00159               request.drawing_effect);
00160 }
00161 
00162 void
00163 GLLightmap::draw_surface_part(const DrawingRequest& request)
00164 {
00165   const SurfacePartRequest* surfacepartrequest
00166     = (SurfacePartRequest*) request.request_data;
00167   const Surface* surface = surfacepartrequest->surface;
00168   boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture());
00169   GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
00170 
00171   float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
00172   float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
00173 
00174   float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
00175   float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
00176   float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
00177   float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
00178 
00179   glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
00180   intern_draw(request.pos.x, request.pos.y,
00181               request.pos.x + surfacepartrequest->size.x,
00182               request.pos.y + surfacepartrequest->size.y,
00183               uv_left,
00184               uv_top,
00185               uv_right,
00186               uv_bottom,
00187               0.0,
00188               request.alpha,
00189               Color(1.0, 1.0, 1.0),
00190               Blend(),
00191               request.drawing_effect);
00192 }
00193 
00194 void
00195 GLLightmap::draw_gradient(const DrawingRequest& request)
00196 {
00197   const GradientRequest* gradientrequest 
00198     = (GradientRequest*) request.request_data;
00199   const Color& top = gradientrequest->top;
00200   const Color& bottom = gradientrequest->bottom;
00201 
00202   glDisable(GL_TEXTURE_2D);
00203   glDisable(GL_TEXTURE_COORD_ARRAY);
00204   glEnable(GL_COLOR_ARRAY);
00205 
00206   float vertices[] = {
00207     0, 0,
00208     SCREEN_WIDTH, 0,
00209     SCREEN_WIDTH, SCREEN_HEIGHT,
00210     0, SCREEN_HEIGHT
00211   };
00212   glVertexPointer(2, GL_FLOAT, 0, vertices);
00213 
00214   float colors[] = {
00215     top.red, top.green, top.blue, top.alpha,
00216     top.red, top.green, top.blue, top.alpha,
00217     bottom.red, bottom.green, bottom.blue, bottom.alpha,
00218     bottom.red, bottom.green, bottom.blue, bottom.alpha,
00219   };
00220   glColorPointer(4, GL_FLOAT, 0, colors);
00221 
00222   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
00223 
00224   glDisable(GL_COLOR_ARRAY);
00225   glEnable(GL_TEXTURE_COORD_ARRAY);
00226 
00227   glEnable(GL_TEXTURE_2D);
00228   glColor4f(1, 1, 1, 1);
00229 }
00230 
00231 void
00232 GLLightmap::draw_filled_rect(const DrawingRequest& request)
00233 {
00234   const FillRectRequest* fillrectrequest
00235     = (FillRectRequest*) request.request_data;
00236 
00237   float x = request.pos.x;
00238   float y = request.pos.y;
00239   float w = fillrectrequest->size.x;
00240   float h = fillrectrequest->size.y;
00241 
00242   glDisable(GL_TEXTURE_2D);
00243   glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
00244             fillrectrequest->color.blue, fillrectrequest->color.alpha);
00245   glDisable(GL_TEXTURE_COORD_ARRAY);
00246 
00247   float vertices[] = {
00248     x,   y,
00249     x+w, y,
00250     x+w, y+h,
00251     x,   y+h
00252   };
00253   glVertexPointer(2, GL_FLOAT, 0, vertices);
00254 
00255   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
00256 
00257   glEnable(GL_TEXTURE_COORD_ARRAY);
00258   glEnable(GL_TEXTURE_2D);
00259   glColor4f(1, 1, 1, 1);
00260 }
00261 
00262 void
00263 GLLightmap::get_light(const DrawingRequest& request) const
00264 {
00265   const GetLightRequest* getlightrequest 
00266     = (GetLightRequest*) request.request_data;
00267 
00268   float pixels[3];
00269   for( int i = 0; i<3; i++)
00270     pixels[i] = 0.0f; //set to black
00271 
00272   float posX = request.pos.x * lightmap_width / SCREEN_WIDTH + old_viewport[0];
00273   float posY = SCREEN_HEIGHT + old_viewport[1] - request.pos.y * lightmap_height / SCREEN_HEIGHT;
00274   glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
00275   *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]);
00276 }
00277 
00278 /* EOF */

Generated on Mon Jun 9 03:38:24 2014 for SuperTux by  doxygen 1.5.1