Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: splitted Texture and TextureData into two files.
Also fixed the Creator-Function for Textures with empty textures with size

File size: 9.0 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#endif
65
66
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->setClassID(CL_TEXTURE, "Texture");
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 *  Constructor for a Texture
116 */
117Texture::Texture(const std::string& imageName, GLenum target)
118{
119  this->init();
120
121  if (!imageName.empty())
122  {
123    this->setName(imageName);
124    this->loadImage(imageName, target);
125  }
126}
127
128
129
130Texture::Texture(SDL_Surface* surface, GLenum target)
131{
132  this->init();
133
134  if(surface != NULL)
135  {
136    this->data->loadSurface(surface, target);
137  }
138}
139
140void Texture::init()
141{
142  this->setClassID(CL_TEXTURE, "Texture");
143
144  this->data = CountPointer<TextureData>(new TextureData());
145
146  this->priority = 0.5;
147}
148
149/**
150 * @brief Destructor of a Texture
151 *
152 * Frees Data, and deletes the textures from GL
153 */
154Texture::~Texture()
155{}
156
157
158/**
159 * @brief loads an Image from a file to a Texture
160 * @param imageName The image to load
161*/
162bool Texture::loadImage(const std::string& imageName, GLenum target)
163{
164  if (Texture::texturesEnabled)
165  {
166    if (!imageName.empty())
167    {
168      SDL_Surface* tmpSurf;
169
170      // load the new Image to memory
171      tmpSurf = IMG_Load(imageName.c_str());
172      if(tmpSurf != NULL)
173      {
174        this->data->loadSurface(tmpSurf, target);
175        SDL_FreeSurface(tmpSurf);
176        return true;
177      }
178      else
179      {
180        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
181        this->setTexture(0);
182        return false;
183      }
184    }
185    else
186    {
187      PRINTF(2)("Image-Name not specified\n");
188      return false;
189    }
190  }
191  return false;
192}
193
194/**
195 * @brief rebuilds the texture.
196 *
197 * reloads the Texture from Memory to OpenGL.
198 */
199bool Texture::rebuild()
200{
201  this->data->setTexture(0);
202
203  if (this->data->getStoredImage() != NULL)
204  {
205    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
206    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
207  }
208  return true;
209}
210
211bool Texture::texturesEnabled = true;
212
213/**
214 * @brief enables, disables textures
215 * @param texturesEnabled true if the textures should be enabled
216 */
217void Texture::setTextureEnableState(bool texturesEnabled)
218{
219  Texture::texturesEnabled = texturesEnabled;
220}
221
222
223//////////////////////////////////////
224// UTILITY FUNCTIONALITY OF TEXTURE //
225//////////////////////////////////////
226/**
227 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
228 * @param surface the Surface to convert
229 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
230 * @returns a !!new!! Surface, that is loadable by openGL.
231 */
232SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
233{
234  assert(surface != NULL);
235  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
236
237  SDL_Surface* retSurface;
238  SDL_Rect area;
239  Uint32 saved_flags;
240  Uint8  saved_alpha;
241  hasAlpha = false;
242  int pixelDepth = 24;
243
244  Uint32* mask = opaqueMask;
245
246  /* Save the alpha blending attributes */
247  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
248  saved_alpha = surface->format->alpha;
249  if ( saved_flags & SDL_SRCALPHA )
250  {
251    SDL_SetAlpha(surface, 0, 0);
252    hasAlpha = true;
253    pixelDepth = 32;
254    mask = alphaMask;
255  }
256
257  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
258                                    surface->w, surface->h,
259                                    pixelDepth,
260                                    mask[0], mask[1], mask[2], mask[3] );
261  if ( retSurface == NULL )
262    return NULL;
263
264  /* Copy the surface into the GL texture this->data->getStoredImage() */
265  area.x = 0;
266  area.y = 0;
267  area.w = surface->w;
268  area.h = surface->h;
269  SDL_BlitSurface(surface, &area, retSurface, &area);
270
271  /* Restore the alpha blending attributes */
272  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
273  {
274    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
275    hasAlpha = true;
276  }
277
278  return (retSurface);
279}
280
281
282/**
283 * @brief Loads a Texture to the openGL-environment.
284 * @param surface the Image to load to openGL
285 * @returns The ID of the texture.
286 */
287GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
288{
289  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
290  //     glDeleteTextures(1, &this->data->getTexture());
291  //   this->data->getTexture() = 0;
292  assert(surface != NULL);
293
294  int      errorCode = 0;           //!< the error code for the texture loading functions
295  GLuint   texture = 0;             //!< the OpenGL texture handle
296  //int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
297  //int      mipmapWidth = 0;         //!< the width of the mipmap
298  //int      mipmapHight = 0;         //!< the height of the mipmap
299  GLenum   format = GL_RGB;
300  if (surface->format->BitsPerPixel == 32)
301  {
302    format = GL_RGBA;
303    assert(surface->format->BitsPerPixel == 32);
304  }
305  else
306  {
307    assert(surface->format->BitsPerPixel == 24);
308  }
309
310  /* Create an OpenGL texture for the this->data->getStoredImage() */
311  Texture::generateTexture(texture, target);
312
313  //   glTexImage2D(target,  0,  format,
314  //                surface->w,  surface->h,
315  //                0, format,  GL_UNSIGNED_BYTE,
316  //                surface->pixels);
317
318  ///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
319  ///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
320
321  /// TODO CHECK THIS BACK in
322  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
323
324  /* build the Texture  OpenGL V >= 1.1 */
325
326  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
327
328  /* control the mipmap levels */
329  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
330  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
331
332  // build the MipMaps automaticaly
333  errorCode = gluBuild2DMipmaps(target, format,
334                                surface->w,  surface->h,
335                                format,  GL_UNSIGNED_BYTE,
336                                surface->pixels
337                               );
338  if(unlikely(errorCode != 0))
339    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
340
341  return texture;
342}
343
344void Texture::generateTexture(GLuint& texture, GLenum target)
345{
346  if (texture == 0 && !glIsTexture(texture))
347  {
348    glGenTextures(1, &texture);
349  }
350  glBindTexture(target, texture);
351
352  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
353  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
354
355  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
356  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
357
358}
Note: See TracBrowser for help on using the repository browser.