Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/osx/src/lib/graphics/importer/texture.cc @ 8162

Last change on this file since 8162 was 8162, checked in by ponder, 18 years ago

The md2Model loader now works as expected

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