X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2F3dengfx%2Fsrc%2F3dengfx%2Ftextures.cpp;fp=src%2F3dengfx%2Fsrc%2F3dengfx%2Ftextures.cpp;h=e651375c32367b720f574b9ee2717b22387779a7;hb=6e23259dbabaeb1711a2a5ca25b9cb421f693759;hp=0000000000000000000000000000000000000000;hpb=fe068fa879814784c45e0cb2e65dac489e8f5594;p=summerhack diff --git a/src/3dengfx/src/3dengfx/textures.cpp b/src/3dengfx/src/3dengfx/textures.cpp new file mode 100644 index 0000000..e651375 --- /dev/null +++ b/src/3dengfx/src/3dengfx/textures.cpp @@ -0,0 +1,211 @@ +/* +This file is part of the 3dengfx, realtime visualization system. + +Copyright (c) 2004, 2005 John Tsiombikas + +3dengfx is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +3dengfx is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with 3dengfx; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "3dengfx_config.h" + +#include +#include +#include "opengl.h" +#include "textures.hpp" + +static void invert_image(Pixel *img, int x, int y) { + Pixel *s2 = img + (y - 1) * x; + Pixel *tmp = new Pixel[x]; + + int swaps = y / 2; + int sl_bytes = x * sizeof(Pixel); + for(int i=0; i= 8 ? y/8 : 1))%2 ? 0x00ff0000 : 0, x * sizeof(Pixel)); + } + } +} + + +Texture::Texture(int x, int y, TextureDim type) { + width = x; + height = type == TEX_1D ? 1 : y; + this->type = type; + + if(x != -1 && y != -1) { + gen_undef_image(width, height); + add_frame(undef_pbuf); + } +} + +Texture::Texture(int x, TextureDim type) { + width = x; + height = type == TEX_1D ? 1 : x; + this->type = type; + + gen_undef_image(width, height); + add_frame(undef_pbuf); +} + +Texture::~Texture() { + // TODO: check if it's destroyed between a lock/unlock and free image data +} + +void Texture::add_frame() { + glGenTextures(1, &tex_id); + glBindTexture(type, tex_id); + + glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if(type == TEX_CUBE) { + glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } else { + glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + frame_tex_id.push_back(tex_id); +} + +void Texture::add_frame(const PixelBuffer &pbuf) { + add_frame(); + + if(type == TEX_CUBE) { + set_pixel_data(pbuf, CUBE_MAP_PX); + set_pixel_data(pbuf, CUBE_MAP_NX); + set_pixel_data(pbuf, CUBE_MAP_PY); + set_pixel_data(pbuf, CUBE_MAP_NY); + set_pixel_data(pbuf, CUBE_MAP_PZ); + set_pixel_data(pbuf, CUBE_MAP_NZ); + } else { + set_pixel_data(pbuf); + } +} + +void Texture::set_active_frame(unsigned int frame) { + assert(frame < frame_tex_id.size()); + + active_frame = frame; + tex_id = frame_tex_id[active_frame]; +} + +unsigned int Texture::get_active_frame() const { + return active_frame; +} + +void Texture::lock(CubeMapFace cube_map_face) { + buffer = new Pixel[width * height]; + + glBindTexture(type, tex_id); + + if(type == TEX_CUBE) { + glGetTexImage(cube_map_face, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + } else { + glGetTexImage(type, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + } + + invert_image(buffer, width, height); +} + +void Texture::unlock(CubeMapFace cube_map_face) { + glBindTexture(type, tex_id); + + invert_image(buffer, width, height); + + switch(type) { + case TEX_1D: + glTexImage1D(type, 0, 4, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + break; + + case TEX_2D: + glTexImage2D(type, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + break; + + case TEX_CUBE: + glTexImage2D(cube_map_face, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + break; + + default: + break; + } + + delete [] buffer; + buffer = 0; +} + +void Texture::set_pixel_data(const PixelBuffer &pbuf, CubeMapFace cube_map_face) { + + if(!frame_tex_id.size()) { + add_frame(); + } + + width = pbuf.width; + height = pbuf.height; + + glBindTexture(type, tex_id); + + buffer = new Pixel[width * height]; + memcpy(buffer, pbuf.buffer, width * height * sizeof(Pixel)); + invert_image(buffer, width, height); + + switch(type) { + case TEX_1D: + glTexImage1D(type, 0, 4, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + break; + + case TEX_2D: + glTexImage2D(type, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); + break; + + case TEX_CUBE: + invert_image(buffer, width, height); + glTexImage2D(cube_map_face, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + break; + + default: + break; + } + + delete [] buffer; + buffer = 0; +} + +TextureDim Texture::get_type() const { + return type; +}