Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: merged the water-branche back here
removed the HACK in GameWorld in the Process (hope it is not needed anymore…

merged with command:
svn merge https://svn.orxonox.net/orxonoanches/water/src/lib/gui/gl_gui src/lib/gui/gl/ -r8063:HEAD

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