Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/water/src/lib/graphics/importer/texture.cc @ 8261

Last change on this file since 8261 was 8089, checked in by stefalie, 19 years ago

water: gui hack

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