Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain/src/lib/graphics/importer/texture.cc @ 8295

Last change on this file since 8295 was 8293, checked in by bensch, 18 years ago

orxonox/trunk: merged the osX-branche back here
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/osx . -r7763:HEAD

conflicts resolved, and everything is working as expected (or at least i hope so :) )

File size: 9.3 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_IMPORTER
17
18#include "texture.h"
19
20#include "debug.h"
21#include "compiler.h"
22
23#ifdef HAVE_SDL_SDL_H
24#include <SDL/SDL_image.h>
25#include <SDL/SDL_endian.h>
26#include <SDL/SDL_byteorder.h>
27#else
28#include <SDL_endian.h>
29#include <SDL_image.h>
30#include <SDL_byteorder.h>
31#endif
32#if SDL_BYTEORDER == SDL_BIG_ENDIAN
33/*
34 * On the BIG_ENDIAN architecture, the 24 and 32bit bitmaps have
35 * different masks. If you don't do this distinction properly,
36 * you will get weird-looking textures.
37 */
38Uint32 alphaMask[] = {
39        0xFF000000,
40        0x00FF0000,
41        0x0000FF00,
42        0x000000FF,
43};
44
45Uint32 opaqueMask[] = {
46        0x00FF0000,
47        0x0000FF00,
48        0x000000FF,
49        0xFF000000
50};
51#else
52/*
53 * On the LIL_ENDIAN architecture everything is fine and easy. The 24
54 * and 32bit bitmaps have the same masks.
55 */
56Uint32 alphaMask[] = {
57        0x000000FF,
58        0x0000FF00,
59        0x00FF0000,
60        0xFF000000,
61};
62
63Uint32 *opaqueMask = alphaMask;
64
65#endif
66
67TextureData::TextureData()
68{
69  this->bAlpha = false;
70  this->texture = 0;
71  this->image = NULL;
72}
73
74
75/**
76 * @brief Destructor of a Texture
77 *
78 *  Frees Data, and deletes the textures from GL
79 */
80TextureData::~TextureData()
81{
82  if (this->texture != 0)
83    glDeleteTextures(1, &this->texture);
84  if (this->image != NULL)
85    SDL_FreeSurface(this->image);
86}
87
88
89/**
90 * @brief Loads an SDL_Surface.
91 */
92bool TextureData::loadSurface(SDL_Surface* surface, GLenum target)
93{
94  if (Texture::getTextureEnableState())
95  {
96    SDL_Surface* newSurf = Texture::prepareSurface(surface, this->bAlpha);
97    if (newSurf != NULL)
98    {
99      this->setSurface(newSurf);
100      this->setTexture(Texture::loadTexToGL(newSurf, target));
101      return true;
102    }
103  }
104  return false;
105}
106
107
108
109/**
110 * @brief set the surface this Texture handles
111 * @param newSurface the new Surface to set as the image for this Texture.
112 *
113 * This deletes the old version of the stored Texture,
114 * and sets the newly given Surface as current.
115 */
116bool TextureData::setSurface(SDL_Surface* newSurface)
117{
118  if (this->image != NULL)
119    SDL_FreeSurface(this->image);
120
121  this->image = newSurface;
122
123  return (this->image != NULL);
124}
125
126
127
128bool TextureData::setTexture(GLuint texture)
129{
130     // unload the old Texture.
131  if (this->texture != 0 && glIsTexture(this->getTexture()))
132  {
133    glDeleteTextures(1, &this->texture);
134  }
135  this->texture = texture;
136  return (texture != 0);
137}
138
139Texture::Texture()
140{
141  this->init();
142}
143
144
145Texture::Texture(const Texture& texture)
146  : data(texture.data)
147{
148  this->setClassID(CL_TEXTURE, "Texture");
149  this->priority = 0.5;
150}
151
152
153Texture::Texture(GLenum target)
154{
155  this->init();
156  GLuint texture;
157  Texture::generateTexture(texture, target);
158  this->data->setTexture(texture);
159}
160
161/**
162 *  Constructor for a Texture
163 */
164Texture::Texture(const std::string& imageName, GLenum target)
165{
166  this->init();
167
168  if (!imageName.empty())
169  {
170    this->setName(imageName);
171    this->loadImage(imageName, target);
172  }
173}
174
175
176
177Texture::Texture(SDL_Surface* surface, GLenum target)
178{
179  this->init();
180
181  if(surface != NULL)
182  {
183    this->data->loadSurface(surface, target);
184  }
185}
186
187void Texture::init()
188{
189  this->setClassID(CL_TEXTURE, "Texture");
190
191  this->data = CountPointer<TextureData>(new TextureData());
192
193  this->priority = 0.5;
194}
195
196/**
197 * @brief Destructor of a Texture
198 *
199 * Frees Data, and deletes the textures from GL
200 */
201Texture::~Texture()
202{
203}
204
205
206/**
207 * @brief loads an Image from a file to a Texture
208 * @param imageName The image to load
209*/
210bool Texture::loadImage(const std::string& imageName, GLenum target)
211{
212  if (Texture::texturesEnabled)
213  {
214    if (!imageName.empty())
215    {
216      SDL_Surface* tmpSurf;
217
218      // load the new Image to memory
219      tmpSurf = IMG_Load(imageName.c_str());
220      if(tmpSurf != NULL)
221      {
222        this->data->loadSurface(tmpSurf, target);
223        SDL_FreeSurface(tmpSurf);
224        return true;
225      }
226      else
227      {
228        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
229        this->setTexture(0);
230        return false;
231      }
232    }
233    else
234    {
235      PRINTF(2)("Image-Name not specified\n");
236      return false;
237    }
238  }
239  return false;
240}
241
242/**
243 * @brief rebuilds the texture.
244 *
245 * reloads the Texture from Memory to OpenGL.
246 */
247bool Texture::rebuild()
248{
249  this->data->setTexture(0);
250
251  if (this->data->getStoredImage() != NULL)
252  {
253    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
254    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
255  }
256  return true;
257}
258
259bool Texture::texturesEnabled = true;
260
261/**
262 * @brief enables, disables textures
263 * @param texturesEnabled true if the textures should be enabled
264 */
265void Texture::setTextureEnableState(bool texturesEnabled)
266{
267  Texture::texturesEnabled = texturesEnabled;
268}
269
270
271//////////////////////////////////////
272// UTILITY FUNCTIONALITY OF TEXTURE //
273//////////////////////////////////////
274/**
275 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
276 * @param surface the Surface to convert
277 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
278 * @returns a !!new!! Surface, that is loadable by openGL.
279 */
280SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
281{
282  assert(surface != NULL);
283  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
284
285  SDL_Surface* retSurface;
286  SDL_Rect area;
287  Uint32 saved_flags;
288  Uint8  saved_alpha;
289  hasAlpha = false;
290  int pixelDepth = 24;
291
292        Uint32* mask = opaqueMask;
293       
294  /* Save the alpha blending attributes */
295  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
296  saved_alpha = surface->format->alpha;
297  if ( saved_flags & SDL_SRCALPHA )
298  {
299    SDL_SetAlpha(surface, 0, 0);
300    hasAlpha = true;
301    pixelDepth = 32;
302                mask = alphaMask;
303  }
304               
305  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
306                                    surface->w, surface->h,
307                                    pixelDepth,
308                                                                                                                                                mask[0], mask[1], mask[2], mask[3] );
309  if ( retSurface == NULL )
310    return NULL;
311
312  /* Copy the surface into the GL texture this->data->getStoredImage() */
313  area.x = 0;
314  area.y = 0;
315  area.w = surface->w;
316  area.h = surface->h;
317  SDL_BlitSurface(surface, &area, retSurface, &area);
318
319  /* Restore the alpha blending attributes */
320  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
321  {
322    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
323    hasAlpha = true;
324  }
325
326  return (retSurface);
327}
328
329
330/**
331 * @brief Loads a Texture to the openGL-environment.
332 * @param surface the Image to load to openGL
333 * @returns The ID of the texture.
334 */
335GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
336{
337  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
338  //     glDeleteTextures(1, &this->data->getTexture());
339  //   this->data->getTexture() = 0;
340  assert(surface != NULL);
341
342  int      errorCode = 0;           //!< the error code for the texture loading functions
343  GLuint   texture = 0;             //!< the OpenGL texture handle
344  int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
345  int      mipmapWidth = 0;         //!< the width of the mipmap
346  int      mipmapHight = 0;         //!< the height of the mipmap
347  GLenum   format = GL_RGB;
348  if (surface->format->BitsPerPixel == 32)
349  {
350    format = GL_RGBA;
351    assert(surface->format->BitsPerPixel == 32);
352  }
353  else
354  {
355    assert(surface->format->BitsPerPixel == 24);
356  }
357
358  /* Create an OpenGL texture for the this->data->getStoredImage() */
359  Texture::generateTexture(texture, target);
360
361//   glTexImage2D(target,  0,  format,
362//                surface->w,  surface->h,
363//                0, format,  GL_UNSIGNED_BYTE,
364//                surface->pixels);
365
366///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
367///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
368
369  /// TODO CHECK THIS BACK in
370  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
371
372  /* build the Texture  OpenGL V >= 1.1 */
373
374  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
375
376  // build the MipMaps automaticaly
377  errorCode = gluBuild2DMipmaps(target, format,
378                                surface->w,  surface->h,
379                                format,  GL_UNSIGNED_BYTE,
380                                surface->pixels
381                               );
382  if(unlikely(errorCode != 0))
383    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
384
385  return texture;
386}
387
388void Texture::generateTexture(GLuint& texture, GLenum target)
389{
390  if (texture == 0 && !glIsTexture(texture))
391  {
392    glGenTextures(1, &texture);
393  }
394  glBindTexture(target, texture);
395
396  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
397  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
398
399  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
400  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
401
402  /* control the mipmap levels */
403  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
404  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
405}
Note: See TracBrowser for help on using the repository browser.