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
RevLine 
[4662]1/*
[3341]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
[3590]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
17
[3341]18#include "texture.h"
19
[4357]20#include "debug.h"
[6139]21#include "compiler.h"
22#include <math.h>
[3622]23
[8162]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>
[4357]30#include <SDL_image.h>
[8162]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};
[4662]52#else
[8162]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
[4662]66#endif
[3341]67/**
[7727]68 * @brief Constructor for a Texture
[3344]69*/
[7221]70Texture::Texture(const std::string& imageName, GLenum target)
[3655]71{
[5304]72  this->setClassID(CL_TEXTURE, "Texture");
73
[5212]74  this->bAlpha = false;
[3655]75  this->texture = 0;
[5753]76  this->image = NULL;
[6139]77  this->priority = 0.5;
[5754]78
[7221]79  if (!imageName.empty())
[5769]80  {
81    this->setName(imageName);
[6465]82    this->loadImage(imageName, target);
[5769]83  }
[4662]84}
[3655]85
[5863]86
[3655]87/**
[7727]88 * @brief Destructor of a Texture
89 *
90 * Frees Data, and deletes the textures from GL
91 */
[4746]92Texture::~Texture()
[3344]93{
[5211]94  if (this->texture != 0)
[3344]95    glDeleteTextures(1, &this->texture);
[5753]96  if (this->image != NULL)
97    SDL_FreeSurface(this->image);
[3344]98}
99
[5863]100
[3863]101/**
[7727]102 * @brief loads an Image from a file to a Texture
[4836]103 * @param imageName The image to load
[3863]104*/
[7221]105bool Texture::loadImage(const std::string& imageName, GLenum target)
[3341]106{
[5858]107  if (Texture::texturesEnabled)
[6859]108  {
109    if (this->image != NULL)
[3341]110    {
[6859]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    }
[7221]119    if (!imageName.empty())
[6859]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
[7221]125      tmpSurf = IMG_Load(imageName.c_str());
[6859]126      if(tmpSurf != NULL)
127      {
[7676]128        PRINTF(4)("loading Image %s\n", imageName.c_str());
[6859]129        bool hasAlpha;
130        SDL_Surface* newSurf = this->prepareSurface(tmpSurf, hasAlpha);
131        if (newSurf != NULL)
[5768]132        {
[6859]133          this->setSurface(newSurf);
134          this->setAlpha(hasAlpha);
135          this->setTexture(Texture::loadTexToGL(newSurf, target));
[5768]136        }
[5856]137
[6859]138        SDL_FreeSurface(tmpSurf);
139        return true;
140      }
[3622]141      else
[6859]142      {
143        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
144        this->texture = 0;
145        return false;
146      }
[3341]147    }
[6859]148    else
149    {
150      PRINTF(2)("Image-Name not specified\n");
151      return false;
152    }
153  }
[5754]154  return false;
[3341]155}
[5753]156
[5863]157
158/**
[7727]159 * @brief rebuilds the texture.
160 *
[5863]161 * reloads the Texture from Memory to OpenGL.
162 */
[5755]163bool Texture::rebuild()
[5754]164{
[5860]165  if (this->texture != 0)
[6859]166  {
167    if (glIsTexture(this->texture))
168      glDeleteTextures(1,&this->texture);
169    this->setTexture(0);
170  }
[5754]171
172  if (this->image != NULL)
[6859]173  {
174    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
175    this->setTexture(loadTexToGL(this->image));
176  }
[5863]177}
[5768]178
[5863]179
180/**
[7727]181 * @brief set the surface this Texture handles
[5863]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);
[5754]195}
196
[5863]197
198bool Texture::texturesEnabled = true;
199
[5754]200/**
[7727]201 * @brief enables, disables textures
[5863]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/**
[7727]214 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
[5754]215 * @param surface the Surface to convert
[5859]216 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
[5754]217 * @returns a !!new!! Surface, that is loadable by openGL.
218 */
[6139]219SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha) const
[5753]220{
[7727]221  assert(surface != NULL);
[5753]222  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
[5768]223
[5859]224  SDL_Surface* retSurface;
[5753]225  SDL_Rect area;
226  Uint32 saved_flags;
227  Uint8  saved_alpha;
[5859]228  hasAlpha = false;
[7727]229  int pixelDepth = 24;
230
[8162]231        Uint32* mask = opaqueMask;
232       
[7727]233  /* Save the alpha blending attributes */
234  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
235  saved_alpha = surface->format->alpha;
[8162]236  if ( saved_flags & SDL_SRCALPHA )
[7727]237  {
238    SDL_SetAlpha(surface, 0, 0);
239    hasAlpha = true;
240    pixelDepth = 32;
[8162]241                mask = alphaMask;
[7727]242  }
[8162]243               
[7727]244  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
[5863]245                                    surface->w, surface->h,
[7727]246                                    pixelDepth,
[8162]247                                                                                                                                                mask[0], mask[1], mask[2], mask[3] );
[5859]248  if ( retSurface == NULL )
249    return NULL;
[5768]250
[5753]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;
[5859]256  SDL_BlitSurface(surface, &area, retSurface, &area);
[5768]257
[5753]258  /* Restore the alpha blending attributes */
[5768]259  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
260  {
261    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
[5859]262    hasAlpha = true;
[5768]263  }
264
[5859]265  return (retSurface);
[5753]266}
267
268
269/**
[7727]270 * @brief Loads a Texture to the openGL-environment.
[5753]271 * @param surface the Image to load to openGL
272 * @returns The ID of the texture.
273 */
[6465]274GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target) const
[5753]275{
[6859]276  //   if (this->texture != 0 && glIsTexture(this->texture))
277  //     glDeleteTextures(1, &this->texture);
278  //   this->texture = 0;
[7727]279  assert(surface != NULL);
[5768]280
[6139]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
[7727]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  }
[5856]296
[5753]297  /* Create an OpenGL texture for the image */
[5856]298  glGenTextures(1, &texture);
[6465]299  glBindTexture(target, texture);
[6139]300
[7751]301//   glTexImage2D(target,  0,  format,
302//                surface->w,  surface->h,
303//                0, format,  GL_UNSIGNED_BYTE,
304//                surface->pixels);
[7727]305
[6634]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*/);
[6465]310  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
[6165]311
[6634]312  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
[6165]313
[6145]314
[6139]315  /* control the mipmap levels */
[6634]316  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
317  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
[6139]318
319  /* build the Texture  OpenGL V >= 1.1 */
[7727]320
[6871]321  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
[6139]322
323  // build the MipMaps automaticaly
[7727]324  errorCode = gluBuild2DMipmaps(target, format,
325                                surface->w,  surface->h,
326                                format,  GL_UNSIGNED_BYTE,
[6139]327                                surface->pixels
328                               );
329  if(unlikely(errorCode != 0))
[6165]330    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
[6139]331
[5856]332  return texture;
[5753]333}
[6139]334
Note: See TracBrowser for help on using the repository browser.