Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8296 was 8293, checked in by bensch, 19 years ago

orxonox/trunk: merged the osX-branche back here
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/osx . -r7763:HEAD

conflicts resolved, and everything is working as expected (or at least i hope so :) )

File size: 9.3 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
153Texture::Texture(GLenum target)
154{
155  this->init();
156  GLuint texture;
[7789]157  Texture::generateTexture(texture, target);
[7785]158  this->data->setTexture(texture);
159}
160
161/**
162 *  Constructor for a Texture
163 */
164Texture::Texture(const std::string& imageName, GLenum target)
165{
166  this->init();
167
[7221]168  if (!imageName.empty())
[5769]169  {
170    this->setName(imageName);
[6465]171    this->loadImage(imageName, target);
[5769]172  }
[4662]173}
[3655]174
[5863]175
[7785]176
177Texture::Texture(SDL_Surface* surface, GLenum target)
178{
179  this->init();
180
181  if(surface != NULL)
182  {
183    this->data->loadSurface(surface, target);
184  }
185}
186
187void Texture::init()
188{
189  this->setClassID(CL_TEXTURE, "Texture");
190
191  this->data = CountPointer<TextureData>(new TextureData());
192
193  this->priority = 0.5;
194}
195
[3655]196/**
[7727]197 * @brief Destructor of a Texture
198 *
199 * Frees Data, and deletes the textures from GL
200 */
[4746]201Texture::~Texture()
[3344]202{
203}
204
[5863]205
[3863]206/**
[7727]207 * @brief loads an Image from a file to a Texture
[4836]208 * @param imageName The image to load
[3863]209*/
[7221]210bool Texture::loadImage(const std::string& imageName, GLenum target)
[3341]211{
[5858]212  if (Texture::texturesEnabled)
[6859]213  {
[7221]214    if (!imageName.empty())
[6859]215    {
216      SDL_Surface* tmpSurf;
[7785]217
[6859]218      // load the new Image to memory
[7221]219      tmpSurf = IMG_Load(imageName.c_str());
[6859]220      if(tmpSurf != NULL)
221      {
[7785]222        this->data->loadSurface(tmpSurf, target);
[6859]223        SDL_FreeSurface(tmpSurf);
224        return true;
225      }
[3622]226      else
[6859]227      {
228        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
[7785]229        this->setTexture(0);
[6859]230        return false;
231      }
[3341]232    }
[6859]233    else
234    {
235      PRINTF(2)("Image-Name not specified\n");
236      return false;
237    }
238  }
[5754]239  return false;
[3341]240}
[5753]241
[5863]242/**
[7727]243 * @brief rebuilds the texture.
244 *
[5863]245 * reloads the Texture from Memory to OpenGL.
246 */
[5755]247bool Texture::rebuild()
[5754]248{
[7785]249  this->data->setTexture(0);
[5754]250
[7785]251  if (this->data->getStoredImage() != NULL)
[6859]252  {
253    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
[7785]254    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
[6859]255  }
[8145]256  return true;
[5863]257}
[5768]258
[5863]259bool Texture::texturesEnabled = true;
260
[5754]261/**
[7727]262 * @brief enables, disables textures
[5863]263 * @param texturesEnabled true if the textures should be enabled
264 */
265void Texture::setTextureEnableState(bool texturesEnabled)
266{
267  Texture::texturesEnabled = texturesEnabled;
268}
269
270
271//////////////////////////////////////
272// UTILITY FUNCTIONALITY OF TEXTURE //
273//////////////////////////////////////
274/**
[7727]275 * @brief converts surface to a new SDL_Surface, that is loadable by openGL
[5754]276 * @param surface the Surface to convert
[5859]277 * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
[5754]278 * @returns a !!new!! Surface, that is loadable by openGL.
279 */
[7785]280SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
[5753]281{
[7727]282  assert(surface != NULL);
[5753]283  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
[5768]284
[5859]285  SDL_Surface* retSurface;
[5753]286  SDL_Rect area;
287  Uint32 saved_flags;
288  Uint8  saved_alpha;
[5859]289  hasAlpha = false;
[7727]290  int pixelDepth = 24;
291
[8293]292        Uint32* mask = opaqueMask;
293       
[7727]294  /* Save the alpha blending attributes */
295  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
296  saved_alpha = surface->format->alpha;
[8293]297  if ( saved_flags & SDL_SRCALPHA )
[7727]298  {
299    SDL_SetAlpha(surface, 0, 0);
300    hasAlpha = true;
301    pixelDepth = 32;
[8293]302                mask = alphaMask;
[7727]303  }
[8293]304               
[7727]305  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
[5863]306                                    surface->w, surface->h,
[7727]307                                    pixelDepth,
[8293]308                                                                                                                                                mask[0], mask[1], mask[2], mask[3] );
[5859]309  if ( retSurface == NULL )
310    return NULL;
[5768]311
[7785]312  /* Copy the surface into the GL texture this->data->getStoredImage() */
[5753]313  area.x = 0;
314  area.y = 0;
315  area.w = surface->w;
316  area.h = surface->h;
[5859]317  SDL_BlitSurface(surface, &area, retSurface, &area);
[5768]318
[5753]319  /* Restore the alpha blending attributes */
[5768]320  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
321  {
322    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
[5859]323    hasAlpha = true;
[5768]324  }
325
[5859]326  return (retSurface);
[5753]327}
328
329
330/**
[7727]331 * @brief Loads a Texture to the openGL-environment.
[5753]332 * @param surface the Image to load to openGL
333 * @returns The ID of the texture.
334 */
[7785]335GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
[5753]336{
[7785]337  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
338  //     glDeleteTextures(1, &this->data->getTexture());
339  //   this->data->getTexture() = 0;
[7727]340  assert(surface != NULL);
[5768]341
[6139]342  int      errorCode = 0;           //!< the error code for the texture loading functions
[7785]343  GLuint   texture = 0;             //!< the OpenGL texture handle
[6139]344  int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
345  int      mipmapWidth = 0;         //!< the width of the mipmap
346  int      mipmapHight = 0;         //!< the height of the mipmap
[7727]347  GLenum   format = GL_RGB;
[7785]348  if (surface->format->BitsPerPixel == 32)
[7727]349  {
350    format = GL_RGBA;
351    assert(surface->format->BitsPerPixel == 32);
352  }
353  else
354  {
355    assert(surface->format->BitsPerPixel == 24);
356  }
[5856]357
[7785]358  /* Create an OpenGL texture for the this->data->getStoredImage() */
359  Texture::generateTexture(texture, target);
[6139]360
[7751]361//   glTexImage2D(target,  0,  format,
362//                surface->w,  surface->h,
363//                0, format,  GL_UNSIGNED_BYTE,
364//                surface->pixels);
[7727]365
[7785]366///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
367///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
[6634]368
[7785]369  /// TODO CHECK THIS BACK in
370  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
[6165]371
[6139]372  /* build the Texture  OpenGL V >= 1.1 */
[7727]373
[6871]374  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
[6139]375
376  // build the MipMaps automaticaly
[7727]377  errorCode = gluBuild2DMipmaps(target, format,
378                                surface->w,  surface->h,
379                                format,  GL_UNSIGNED_BYTE,
[6139]380                                surface->pixels
381                               );
382  if(unlikely(errorCode != 0))
[6165]383    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
[6139]384
[5856]385  return texture;
[5753]386}
[6139]387
[7785]388void Texture::generateTexture(GLuint& texture, GLenum target)
389{
390  if (texture == 0 && !glIsTexture(texture))
391  {
392    glGenTextures(1, &texture);
393  }
394  glBindTexture(target, texture);
395
396  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
397  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
398
399  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
400  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
401
402  /* control the mipmap levels */
403  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
404  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
405}
Note: See TracBrowser for help on using the repository browser.