Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/texture.cc

Last change on this file was 10475, checked in by bensch, 17 years ago

fixed a compilation bug on tardis machines, now SDL is only searched for with sdl-config if SDL is not found natively by automake algorithms.
the only problem is, that if SDL is really not found, nothing is reported
but at least it works for the moment

please inform me if any problems on other platforms do arise

File size: 10.1 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_image.h>
29 #include <SDL_endian.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#endif
65
66ObjectListDefinition(Texture);
67
68/**
69 * @brief creates an Empty Texture,
70 *
71 * onto this Texture you can load non-empty textures with the =
72 * operator.
73 */
74Texture::Texture()
75{
76  this->init();
77}
78
79/**
80 * @brief Creates a Texture from another Texture (copy Constructor)
81 * @param texture the Texture to copy.
82 *
83 * @note only the Data-Pointer will be shared.
84 */
85Texture::Texture(const Texture& texture)
86    : data(texture.data)
87{
88  this->registerObject(this, Texture::_objectList);
89  this->priority = 0.5;
90}
91
92/**
93 * @brief Creates a new empty Texture with the below properties.
94 * @param target: the GL-Target.
95 * @param width: the Width of the Texture.
96 * @param height: The Hight of the Texture.
97 * @param channels: also known as BitsPerPixel.
98 * @param type the Type of Texture.
99 */
100Texture::Texture(GLenum target, unsigned int width, unsigned int height, unsigned int channels, GLenum type)
101{
102  this->init();
103
104  SDL_Surface * surface = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, channels,
105                          alphaMask[0], alphaMask[1], alphaMask[2], alphaMask[3]);
106
107  if(surface != NULL)
108  {
109    this->data->loadSurface(surface, target);
110    SDL_FreeSurface(surface);
111  }
112}
113
114/**
115 * @brief Constructor for a Texture
116 * @param imageName: the Name of the Texutre (FileName)
117 * @param target: the GL-Target to load the Texture to.
118 */
119Texture::Texture(const std::string& imageName, GLenum target)
120{
121  this->init();
122
123  if (!imageName.empty())
124  {
125    this->setName(imageName);
126    this->loadImage(imageName, target);
127  }
128}
129
130
131/**
132 * @brief creates a Texture out of a SDL_Surface.
133 * @param surface: the Surface to load.
134 * @param target: the GL-Target to load this to.
135 */
136Texture::Texture(SDL_Surface* surface, GLenum target)
137{
138  this->init();
139
140  if(surface != NULL)
141  {
142    this->data->loadSurface(surface, target);
143  }
144}
145
146/**
147 * @brief Initializes the Texture.
148 */
149void Texture::init()
150{
151  this->registerObject(this, Texture::_objectList);
152
153  this->data = TextureData::Pointer(new TextureData());
154
155  this->priority = 0.5;
156}
157
158/**
159 * @brief Destructor of a Texture
160 *
161 * Frees Data, and deletes the textures from GL
162 */
163Texture::~Texture()
164{}
165
166/**
167 * @brief copies the Data from texture to this texture.
168 * @param texture the Texture to copy into this one.
169 * @returns the Texture.
170 */
171Texture& Texture::operator=(const Texture& texture)
172{
173  this->data = texture.data;
174
175  return *this;
176}
177
178Texture& Texture::operator=(const TextureData::Pointer& textureDataPointer)
179{
180  this->data = textureDataPointer;
181  return *this;
182}
183
184
185/**
186 * @brief loads an Image from a file to a Texture
187 * @param imageName The image to load
188*/
189bool Texture::loadImage(const std::string& imageName, GLenum target)
190{
191  if (Texture::texturesEnabled)
192  {
193    if (!imageName.empty())
194    {
195      SDL_Surface* tmpSurf;
196
197      // load the new Image to memory
198      tmpSurf = IMG_Load(imageName.c_str());
199      if(tmpSurf != NULL)
200      {
201        this->data->loadSurface(tmpSurf, target);
202        SDL_FreeSurface(tmpSurf);
203        return true;
204      }
205      else
206      {
207        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
208        this->setTexture(0);
209        return false;
210      }
211    }
212    else
213    {
214      PRINTF(2)("Image-Name not specified\n");
215      return false;
216    }
217  }
218  return false;
219}
220
221/**
222 * @brief rebuilds the texture.
223 *
224 * reloads the Texture from Memory to OpenGL.
225 */
226bool Texture::rebuild()
227{
228  this->data->setTexture(0);
229
230  if (this->data->getStoredImage() != NULL)
231  {
232    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassCName(), this->getCName());
233    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
234  }
235  return true;
236}
237
238bool Texture::texturesEnabled = true;
239
240/**
241 * @brief enables, disables textures
242 * @param texturesEnabled true if the textures should be enabled
243 */
244void Texture::setTextureEnableState(bool texturesEnabled)
245{
246  Texture::texturesEnabled = texturesEnabled;
247}
248
249
250//////////////////////////////////////
251// UTILITY FUNCTIONALITY OF TEXTURE //
252//////////////////////////////////////
253/**
254 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
255 * @param surface the Surface to convert
256 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
257 * @returns a !!new!! Surface, that is loadable by openGL.
258 */
259SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
260{
261  assert(surface != NULL);
262  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
263
264  SDL_Surface* retSurface;
265  SDL_Rect area;
266  Uint32 saved_flags;
267  Uint8  saved_alpha;
268  hasAlpha = false;
269  int pixelDepth = 24;
270
271  Uint32* mask = opaqueMask;
272
273  /* Save the alpha blending attributes */
274  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
275  saved_alpha = surface->format->alpha;
276  if ( saved_flags & SDL_SRCALPHA )
277  {
278    SDL_SetAlpha(surface, 0, 0);
279    hasAlpha = true;
280    pixelDepth = 32;
281    mask = alphaMask;
282  }
283
284  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
285                                    surface->w, surface->h,
286                                    pixelDepth,
287                                    mask[0], mask[1], mask[2], mask[3] );
288  if ( retSurface == NULL )
289    return NULL;
290
291  /* Copy the surface into the GL texture this->data->getStoredImage() */
292  area.x = 0;
293  area.y = 0;
294  area.w = surface->w;
295  area.h = surface->h;
296  SDL_BlitSurface(surface, &area, retSurface, &area);
297
298  /* Restore the alpha blending attributes */
299  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
300  {
301    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
302    hasAlpha = true;
303  }
304
305  return (retSurface);
306}
307
308
309/**
310 * @brief Loads a Texture to the openGL-environment.
311 * @param surface the Image to load to openGL
312 * @returns The ID of the texture.
313 */
314GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
315{
316  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
317  //     glDeleteTextures(1, &this->data->getTexture());
318  //   this->data->getTexture() = 0;
319  assert(surface != NULL);
320
321  int      errorCode = 0;           //!< the error code for the texture loading functions
322  GLuint   texture = 0;             //!< the OpenGL texture handle
323  //int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
324  //int      mipmapWidth = 0;         //!< the width of the mipmap
325  //int      mipmapHight = 0;         //!< the height of the mipmap
326  GLenum   format = GL_RGB;
327  if (surface->format->BitsPerPixel == 32)
328  {
329    format = GL_RGBA;
330    assert(surface->format->BitsPerPixel == 32);
331  }
332  else
333  {
334    assert(surface->format->BitsPerPixel == 24);
335  }
336
337  /* Create an OpenGL texture for the this->data->getStoredImage() */
338  Texture::generateTexture(texture, target);
339
340  //   glTexImage2D(target,  0,  format,
341  //                surface->w,  surface->h,
342  //                0, format,  GL_UNSIGNED_BYTE,
343  //                surface->pixels);
344
345  ///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
346  ///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
347
348  /// TODO CHECK THIS BACK in
349  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
350
351  /* build the Texture  OpenGL V >= 1.1 */
352
353  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
354
355  /* control the mipmap levels */
356  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
357  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
358
359  // build the MipMaps automaticaly
360  errorCode = gluBuild2DMipmaps(target, format,
361                                surface->w,  surface->h,
362                                format,  GL_UNSIGNED_BYTE,
363                                surface->pixels
364                               );
365  if(unlikely(errorCode != 0))
366    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
367
368  return texture;
369}
370
371/**
372 * @brief creates a new Texture.
373 * @param texture: the Texture is loaded here (should be 0 and will be set to the Value of the New Texture.)
374 * @param target: The GL-Target to generate the texture on.
375 *
376 * @note this is the real GL-texture-creat-wrapper, where the Texture is Created
377 */
378void Texture::generateTexture(GLuint& texture, GLenum target)
379{
380  if (texture == 0 && !glIsTexture(texture))
381  {
382    glGenTextures(1, &texture);
383  }
384  glBindTexture(target, texture);
385
386  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
387  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
388
389  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
390  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
391
392}
Note: See TracBrowser for help on using the repository browser.