Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-12-06 21:33:34 +0000
committerStijn Buys <ingar@osirion.org>2010-12-06 21:33:34 +0000
commitc50095cab023e91ba2a4fec8dcb290e6d817124b (patch)
treee9511df876d45faffb428ee7ae342a8aabab4194 /src/render/textures.cc
parent8c7fa7dd3258e8d3e112fb9780249dd0d0ef008a (diff)
Re-enabled environment mapping with the skybox as cubemap.
Diffstat (limited to 'src/render/textures.cc')
-rw-r--r--src/render/textures.cc201
1 files changed, 170 insertions, 31 deletions
diff --git a/src/render/textures.cc b/src/render/textures.cc
index e252f2d..ad1d8d1 100644
--- a/src/render/textures.cc
+++ b/src/render/textures.cc
@@ -10,9 +10,6 @@
#include "render/gl.h"
#include "render/image.h"
#include "render/textures.h"
-#include "render/tgafile.h"
-#include "render/pngfile.h"
-#include "render/jpgfile.h"
#include "render/state.h"
#include "sys/sys.h"
@@ -24,6 +21,7 @@ namespace render
std::map<std::string, size_t> Textures::registry;
GLuint Textures::textures[MAXTEXTURES];
math::Vector2f Textures::texture_size[MAXTEXTURES];
+std::string textures_cubemapname;
void material_loader_func(model::Material *material)
{
@@ -84,6 +82,8 @@ void Textures::clear()
registry.clear();
memset(textures, 0, sizeof(textures));
+
+ textures_cubemapname.clear();
}
void Textures::unload(const std::string &name)
@@ -118,6 +118,169 @@ void Textures::unload(const size_t id)
}
}
+void Textures::load_cubemap(const std::string & name)
+{
+ if (textures_cubemapname.compare(name) == 0) {
+ // cubemap is already loaded
+ return;
+ }
+
+ textures_cubemapname.assign(name);
+
+const GLenum cube_map[6] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+
+ };
+
+ Image *cube_texture[6] = {
+ Image::load(name + "_front"),
+ Image::load(name + "_back"),
+ Image::load(name + "_left"),
+ Image::load(name + "_right"),
+ Image::load(name + "_up"),
+ Image::load(name + "_down")
+
+ };
+
+ if (cube_texture[0]) {
+ Image *image = cube_texture[0];
+
+ if (image->width() != image->height()) {
+ con_warn << " " << name << "_front: non-square sky texture!" << std::endl;
+ } else {
+ unsigned char pixel_data[image->channels()];
+
+ for (size_t y = 0; y < image->height(); y++) {
+ for (size_t x = y +1; x < image->width(); x++) {
+ void *src = image->pixel(x, y);
+ void *dst = image->pixel(y, x);
+ memcpy(pixel_data, dst, image->channels());
+ memcpy(dst, src, image->channels());
+ memcpy(src, pixel_data, image->channels());
+ }
+
+ }
+ }
+ }
+
+ if (cube_texture[1]) {
+ Image *image = cube_texture[1];
+
+ if (image->width() != image->height()) {
+ con_warn << " " << name << "_back: non-square sky texture!" << std::endl;
+ } else {
+ unsigned char pixel_data[image->channels()];
+
+ for (size_t y = 0; y < image->height(); y++) {
+ for (size_t x = y +1; x < image->width(); x++) {
+ void *src = image->pixel(image->width() - x - 1, y);
+ void *dst = image->pixel(image->height() - y - 1, x);
+ memcpy(pixel_data, dst, image->channels());
+ memcpy(dst, src, image->channels());
+ memcpy(src, pixel_data, image->channels());
+ }
+
+ }
+ }
+ }
+
+ if (cube_texture[2]) {
+ cube_texture[2]->flip_vertical();
+ }
+
+ if (cube_texture[3]) {
+ cube_texture[3]->flip_horizontal();
+ }
+
+ if (cube_texture[4]) {
+ Image *image = cube_texture[4];
+
+ if (image->width() != image->height()) {
+ con_warn << " " << name << "_back: non-square sky texture!" << std::endl;
+ } else {
+ unsigned char pixel_data[image->channels()];
+
+ for (size_t y = 0; y < image->height(); y++) {
+ for (size_t x = y +1; x < image->width(); x++) {
+ void *src = image->pixel(x, y);
+ void *dst = image->pixel(y, x);
+ memcpy(pixel_data, dst, image->channels());
+ memcpy(dst, src, image->channels());
+ memcpy(src, pixel_data, image->channels());
+ }
+
+ }
+ }
+ }
+
+ if (cube_texture[5]) {
+ Image *image = cube_texture[5];
+
+ if (image->width() != image->height()) {
+ con_warn << " " << name << "_down: non-square sky texture!" << std::endl;
+ } else {
+ unsigned char pixel_data[image->channels()];
+
+ for (size_t y = 0; y < image->height(); y++) {
+ for (size_t x = y +1; x < image->width(); x++) {
+ void *src = image->pixel(x, y);
+ void *dst = image->pixel(y, x);
+ memcpy(pixel_data, dst, image->channels());
+ memcpy(dst, src, image->channels());
+ memcpy(src, pixel_data, image->channels());
+ }
+
+ }
+ }
+ }
+
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ // 4 levels of mipmaps
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 4);
+
+ if (r_mipmap->value()) {
+ // hardware generated mipmaps (requires OpenGL 1.4)
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
+ }
+
+ for (size_t i = 0; i < 6; i++) {
+ if (cube_texture[i]) {
+ int texture_format;
+ int texture_internalformat;
+
+ if (cube_texture[i]->channels() == 4) {
+ texture_format = GL_RGBA;
+ texture_internalformat = GL_RGBA8;
+ } else {
+ texture_format = GL_RGB;
+ texture_internalformat = GL_RGB8;
+ }
+
+ if (r_mipmap->value() <= 0) {
+ gluBuild2DMipmaps(cube_map[i],
+ texture_internalformat, cube_texture[i]->width(), cube_texture[i]->height(),
+ texture_format, GL_UNSIGNED_BYTE, cube_texture[i]->ptr());
+ } else {
+ glTexImage2D(cube_map[i], 0,
+ texture_internalformat, cube_texture[i]->width(), cube_texture[i]->height(), 0,
+ texture_format, GL_UNSIGNED_BYTE, cube_texture[i]->ptr());
+ }
+
+ delete cube_texture[i];
+ }
+ }
+}
+
size_t Textures::load(const char *name, const bool filter)
{
if (name)
@@ -144,33 +307,9 @@ size_t Textures::load(const std::string &name, const bool filter)
return 0;
}
- std::string filename;
- Image *image = 0;
-
- if (!image) {
- // try the png version
- filename.assign(name);
- filename.append(".png");
- image = PNG::load(filename.c_str());
- }
-
- if (!image) {
- // try the tga version
- filename.assign(name);
- filename.append(".tga");
- image = TGA::load(filename.c_str());
- }
-
- if (!image) {
- // try the jpg version
- filename.assign(name);
- filename.append(".jpg");
- image = JPG::load(filename.c_str());
- }
-
+ Image *image = Image::load(name);
if (!image) {
// add to the registry with id 0 (texture not found)
- con_warn << "Could not open texture " << name << std::endl;
registry[name] = 0;
return 0;
}
@@ -183,7 +322,7 @@ size_t Textures::load(const std::string &name, const bool filter)
if (filter) {
// scaling functions
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 4 levels of mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
@@ -219,11 +358,11 @@ size_t Textures::load(const std::string &name, const bool filter)
if (filter && (r_mipmap->value() <= 0)) {
gluBuild2DMipmaps(GL_TEXTURE_2D,
texture_internalformat, image->width(), image->height(),
- texture_format, GL_UNSIGNED_BYTE, image->data());
+ texture_format, GL_UNSIGNED_BYTE, image->ptr());
} else {
glTexImage2D(GL_TEXTURE_2D, 0,
texture_internalformat, image->width(), image->height(), 0,
- texture_format, GL_UNSIGNED_BYTE, image->data());
+ texture_format, GL_UNSIGNED_BYTE, image->ptr());
}
// add to the registry