2 This file is part of the 3dengfx, realtime visualization system.
4 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
6 3dengfx 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 of the License, or
9 (at your option) any later version.
11 3dengfx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with 3dengfx; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "3dengfx_config.h"
26 #include "textures.hpp"
28 static void invert_image(Pixel *img, int x, int y) {
29 Pixel *s2 = img + (y - 1) * x;
30 Pixel *tmp = new Pixel[x];
33 int sl_bytes = x * sizeof(Pixel);
34 for(int i=0; i<swaps; i++) {
35 memcpy(tmp, img, sl_bytes);
36 memcpy(img, s2, sl_bytes);
37 memcpy(s2, tmp, sl_bytes);
45 static PixelBuffer undef_pbuf;
47 static void gen_undef_image(int x, int y) {
48 if((int)undef_pbuf.width != x || (int)undef_pbuf.height != y) {
49 if(undef_pbuf.buffer) {
50 delete [] undef_pbuf.buffer;
53 undef_pbuf.height = y;
54 undef_pbuf.pitch = x * sizeof(Pixel);
55 undef_pbuf.buffer = new Pixel[x * y];
57 for(int i=0; i<y; i++) {
58 memset(&undef_pbuf.buffer[i * x], (i/(y >= 8 ? y/8 : 1))%2 ? 0x00ff0000 : 0, x * sizeof(Pixel));
64 Texture::Texture(int x, int y, TextureDim type) {
66 height = type == TEX_1D ? 1 : y;
69 if(x != -1 && y != -1) {
70 gen_undef_image(width, height);
71 add_frame(undef_pbuf);
75 Texture::Texture(int x, TextureDim type) {
77 height = type == TEX_1D ? 1 : x;
80 gen_undef_image(width, height);
81 add_frame(undef_pbuf);
85 // TODO: check if it's destroyed between a lock/unlock and free image data
88 void Texture::add_frame() {
89 glGenTextures(1, &tex_id);
90 glBindTexture(type, tex_id);
92 glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
93 glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
95 if(type == TEX_CUBE) {
96 glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
97 glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
99 glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_REPEAT);
100 glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_REPEAT);
103 frame_tex_id.push_back(tex_id);
106 void Texture::add_frame(const PixelBuffer &pbuf) {
109 if(type == TEX_CUBE) {
110 set_pixel_data(pbuf, CUBE_MAP_PX);
111 set_pixel_data(pbuf, CUBE_MAP_NX);
112 set_pixel_data(pbuf, CUBE_MAP_PY);
113 set_pixel_data(pbuf, CUBE_MAP_NY);
114 set_pixel_data(pbuf, CUBE_MAP_PZ);
115 set_pixel_data(pbuf, CUBE_MAP_NZ);
117 set_pixel_data(pbuf);
121 void Texture::set_active_frame(unsigned int frame) {
122 assert(frame < frame_tex_id.size());
124 active_frame = frame;
125 tex_id = frame_tex_id[active_frame];
128 unsigned int Texture::get_active_frame() const {
132 void Texture::lock(CubeMapFace cube_map_face) {
133 buffer = new Pixel[width * height];
135 glBindTexture(type, tex_id);
137 if(type == TEX_CUBE) {
138 glGetTexImage(cube_map_face, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
140 glGetTexImage(type, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
143 invert_image(buffer, width, height);
146 void Texture::unlock(CubeMapFace cube_map_face) {
147 glBindTexture(type, tex_id);
149 invert_image(buffer, width, height);
153 glTexImage1D(type, 0, 4, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
157 glTexImage2D(type, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
161 glTexImage2D(cube_map_face, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
172 void Texture::set_pixel_data(const PixelBuffer &pbuf, CubeMapFace cube_map_face) {
174 if(!frame_tex_id.size()) {
179 height = pbuf.height;
181 glBindTexture(type, tex_id);
183 buffer = new Pixel[width * height];
184 memcpy(buffer, pbuf.buffer, width * height * sizeof(Pixel));
185 invert_image(buffer, width, height);
189 glTexImage1D(type, 0, 4, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
193 glTexImage2D(type, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
197 invert_image(buffer, width, height);
198 glTexImage2D(cube_map_face, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
209 TextureDim Texture::get_type() const {