Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10772 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
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"
[3622]22
[8293]23#ifdef HAVE_SDL_SDL_H
[10475]24 #include <SDL/SDL_image.h>
25 #include <SDL/SDL_endian.h>
26 #include <SDL/SDL_byteorder.h>
[8293]27#else
[10475]28 #include <SDL_image.h>
29 #include <SDL_endian.h>
30 #include <SDL_byteorder.h>
[8293]31#endif
32#if SDL_BYTEORDER == SDL_BIG_ENDIAN
33/*
34 * On the BIG_ENDIAN architecture, the 24 and 32bit bitmaps have
[8316]35 * different masks. If you don't do this distinction properly,
[8293]36 * you will get weird-looking textures.
37 */
38Uint32 alphaMask[] = {
[8363]39                       0xFF000000,
40                       0x00FF0000,
41                       0x0000FF00,
42                       0x000000FF,
43                     };
[8293]44
45Uint32 opaqueMask[] = {
[8363]46                        0x00FF0000,
47                        0x0000FF00,
48                        0x000000FF,
49                        0xFF000000
50                      };
[4662]51#else
[8293]52/*
[8363]53* On the LIL_ENDIAN architecture everything is fine and easy. The 24
54* and 32bit bitmaps have the same masks.
55*/
[8293]56Uint32 alphaMask[] = {
[8363]57                       0x000000FF,
58                       0x0000FF00,
59                       0x00FF0000,
60                       0xFF000000,
61                     };
[8293]62
63Uint32 *opaqueMask = alphaMask;
[4662]64#endif
[4357]65
[9869]66ObjectListDefinition(Texture);
[5754]67
[7785]68/**
[8363]69 * @brief creates an Empty Texture,
[7785]70 *
[8363]71 * onto this Texture you can load non-empty textures with the =
72 * operator.
[7785]73 */
[8363]74Texture::Texture()
[7785]75{
[8363]76  this->init();
[7785]77}
78
79/**
[8363]80 * @brief Creates a Texture from another Texture (copy Constructor)
81 * @param texture the Texture to copy.
[7785]82 *
[8363]83 * @note only the Data-Pointer will be shared.
[7785]84 */
[7788]85Texture::Texture(const Texture& texture)
[8363]86    : data(texture.data)
[7788]87{
[9869]88  this->registerObject(this, Texture::_objectList);
[7788]89  this->priority = 0.5;
90}
[7785]91
[8363]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 */
[8312]100Texture::Texture(GLenum target, unsigned int width, unsigned int height, unsigned int channels, GLenum type)
[7785]101{
102  this->init();
[8312]103
[8363]104  SDL_Surface * surface = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, channels,
105                          alphaMask[0], alphaMask[1], alphaMask[2], alphaMask[3]);
[8312]106
[8363]107  if(surface != NULL)
108  {
109    this->data->loadSurface(surface, target);
110    SDL_FreeSurface(surface);
111  }
[7785]112}
113
114/**
[8366]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.
[7785]118 */
119Texture::Texture(const std::string& imageName, GLenum target)
120{
121  this->init();
122
[7221]123  if (!imageName.empty())
[5769]124  {
125    this->setName(imageName);
[6465]126    this->loadImage(imageName, target);
[5769]127  }
[4662]128}
[3655]129
[5863]130
[8366]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 */
[7785]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
[8366]146/**
147 * @brief Initializes the Texture.
148 */
[7785]149void Texture::init()
150{
[9869]151  this->registerObject(this, Texture::_objectList);
[7785]152
[9869]153  this->data = TextureData::Pointer(new TextureData());
[7785]154
155  this->priority = 0.5;
156}
157
[3655]158/**
[7727]159 * @brief Destructor of a Texture
160 *
161 * Frees Data, and deletes the textures from GL
162 */
[4746]163Texture::~Texture()
[8363]164{}
[3344]165
[8376]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;
[5863]174
[8376]175  return *this;
176}
177
[9869]178Texture& Texture::operator=(const TextureData::Pointer& textureDataPointer)
[8761]179{
180  this->data = textureDataPointer;
181  return *this;
182}
[8376]183
[8761]184
[3863]185/**
[7727]186 * @brief loads an Image from a file to a Texture
[4836]187 * @param imageName The image to load
[3863]188*/
[7221]189bool Texture::loadImage(const std::string& imageName, GLenum target)
[3341]190{
[5858]191  if (Texture::texturesEnabled)
[6859]192  {
[7221]193    if (!imageName.empty())
[6859]194    {
195      SDL_Surface* tmpSurf;
[7785]196
[6859]197      // load the new Image to memory
[7221]198      tmpSurf = IMG_Load(imageName.c_str());
[6859]199      if(tmpSurf != NULL)
200      {
[7785]201        this->data->loadSurface(tmpSurf, target);
[6859]202        SDL_FreeSurface(tmpSurf);
203        return true;
204      }
[3622]205      else
[6859]206      {
207        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
[7785]208        this->setTexture(0);
[6859]209        return false;
210      }
[3341]211    }
[6859]212    else
213    {
214      PRINTF(2)("Image-Name not specified\n");
215      return false;
216    }
217  }
[5754]218  return false;
[3341]219}
[5753]220
[5863]221/**
[7727]222 * @brief rebuilds the texture.
223 *
[5863]224 * reloads the Texture from Memory to OpenGL.
225 */
[5755]226bool Texture::rebuild()
[5754]227{
[7785]228  this->data->setTexture(0);
[5754]229
[7785]230  if (this->data->getStoredImage() != NULL)
[6859]231  {
[9406]232    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassCName(), this->getCName());
[7785]233    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
[6859]234  }
[8145]235  return true;
[5863]236}
[5768]237
[5863]238bool Texture::texturesEnabled = true;
239
[5754]240/**
[7727]241 * @brief enables, disables textures
[5863]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/**
[7727]254 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
[5754]255 * @param surface the Surface to convert
[5859]256 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
[5754]257 * @returns a !!new!! Surface, that is loadable by openGL.
258 */
[7785]259SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
[5753]260{
[7727]261  assert(surface != NULL);
[5753]262  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
[5768]263
[5859]264  SDL_Surface* retSurface;
[5753]265  SDL_Rect area;
266  Uint32 saved_flags;
267  Uint8  saved_alpha;
[5859]268  hasAlpha = false;
[7727]269  int pixelDepth = 24;
270
[8363]271  Uint32* mask = opaqueMask;
[8316]272
[7727]273  /* Save the alpha blending attributes */
274  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
275  saved_alpha = surface->format->alpha;
[8293]276  if ( saved_flags & SDL_SRCALPHA )
[7727]277  {
278    SDL_SetAlpha(surface, 0, 0);
279    hasAlpha = true;
280    pixelDepth = 32;
[8363]281    mask = alphaMask;
[7727]282  }
[8316]283
[7727]284  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
[5863]285                                    surface->w, surface->h,
[7727]286                                    pixelDepth,
[8363]287                                    mask[0], mask[1], mask[2], mask[3] );
[5859]288  if ( retSurface == NULL )
289    return NULL;
[5768]290
[7785]291  /* Copy the surface into the GL texture this->data->getStoredImage() */
[5753]292  area.x = 0;
293  area.y = 0;
294  area.w = surface->w;
295  area.h = surface->h;
[5859]296  SDL_BlitSurface(surface, &area, retSurface, &area);
[5768]297
[5753]298  /* Restore the alpha blending attributes */
[5768]299  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
300  {
301    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
[5859]302    hasAlpha = true;
[5768]303  }
304
[5859]305  return (retSurface);
[5753]306}
307
308
309/**
[7727]310 * @brief Loads a Texture to the openGL-environment.
[5753]311 * @param surface the Image to load to openGL
312 * @returns The ID of the texture.
313 */
[7785]314GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
[5753]315{
[7785]316  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
317  //     glDeleteTextures(1, &this->data->getTexture());
318  //   this->data->getTexture() = 0;
[7727]319  assert(surface != NULL);
[5768]320
[6139]321  int      errorCode = 0;           //!< the error code for the texture loading functions
[7785]322  GLuint   texture = 0;             //!< the OpenGL texture handle
[8316]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
[7727]326  GLenum   format = GL_RGB;
[7785]327  if (surface->format->BitsPerPixel == 32)
[7727]328  {
329    format = GL_RGBA;
330    assert(surface->format->BitsPerPixel == 32);
331  }
332  else
333  {
334    assert(surface->format->BitsPerPixel == 24);
335  }
[5856]336
[7785]337  /* Create an OpenGL texture for the this->data->getStoredImage() */
338  Texture::generateTexture(texture, target);
[6139]339
[8363]340  //   glTexImage2D(target,  0,  format,
341  //                surface->w,  surface->h,
342  //                0, format,  GL_UNSIGNED_BYTE,
343  //                surface->pixels);
[7727]344
[8363]345  ///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
346  ///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
[6634]347
[7785]348  /// TODO CHECK THIS BACK in
349  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
[6165]350
[6139]351  /* build the Texture  OpenGL V >= 1.1 */
[7727]352
[6871]353  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
[6139]354
[8312]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
[6139]359  // build the MipMaps automaticaly
[7727]360  errorCode = gluBuild2DMipmaps(target, format,
361                                surface->w,  surface->h,
362                                format,  GL_UNSIGNED_BYTE,
[6139]363                                surface->pixels
364                               );
365  if(unlikely(errorCode != 0))
[6165]366    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
[6139]367
[5856]368  return texture;
[5753]369}
[6139]370
[8366]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 */
[7785]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.