#include <math.h>
#include <assert.h>
#include "texture.h"
+#include "datamap.h"
#include "image.h"
#include "opengl.h"
#include "imago2.h"
+#include "logger.h"
static int glifmt_from_ifmt(unsigned int ifmt);
static int glfmt_from_ifmt(unsigned int ifmt);
}
}
+int next_pow2(int x)
+{
+ x--;
+ x = (x >> 1) | x;
+ x = (x >> 2) | x;
+ x = (x >> 4) | x;
+ x = (x >> 8) | x;
+ x = (x >> 16) | x;
+ return x + 1;
+}
+
Image *Texture::default_img;
return sz[dim];
}
+int Texture::get_width() const
+{
+ return sz[0];
+}
+
+int Texture::get_height() const
+{
+ return sz[1];
+}
+
unsigned int Texture::get_id() const
{
return id;
void Texture::create(int xsz, int ysz, TextureType textype, unsigned int ifmt)
{
if(textype == TEX_CUBE && xsz != ysz) {
- fprintf(stderr, "trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
+ error_log("trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
return;
}
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- switch(type) {
+ switch(textype) {
case TEX_2D:
glTexImage2D(GL_TEXTURE_2D, 0, glifmt_from_ifmt(ifmt), xsz, ysz, 0, fmt, type, 0);
break;
pixels += 4;
}
}
- default_img->save("/tmp/foo.png");
}
switch(type) {
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
#ifdef __GLEW_H__
if(GLEW_SGIS_generate_mipmap) {
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
bool Texture::set_image_cube(const Image &img, int idx)
{
+ unsigned int err;
if(idx < 0 || idx >= 6) {
return false;
}
target = GL_TEXTURE_CUBE_MAP;
glBindTexture(target, id);
- assert(glGetError() == GL_NO_ERROR);
+ if((err = glGetError()) == GL_INVALID_OPERATION) {
+ return false; // probably not a cubemap
+ }
+ assert(err == GL_NO_ERROR);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
int xsz = img.get_width();
int ysz = img.get_height();
- if(xsz / 4 == ysz / 3) {
+ if((xsz << 8) / 4 == (ysz << 8) / 3) {
// horizontal cross, assume the vertical bit is center-left
return set_cube_multi(img, hcross[0], hcross[1], xsz / 4);
}
- if(xsz / 3 == ysz / 4) {
+ if((xsz << 8) / 3 == (ysz << 8) / 4) {
// vertical cross, assume the horizontal bit is center-top (180-rotated image 5)
return set_cube_multi(img, vcross[0], vcross[1], ysz / 4, (1 << 5));
}
- if(xsz / 3 == ysz / 2) {
+ if((xsz << 8) / 3 == (ysz << 8) / 2) {
// horizontal sixpack
return set_cube_multi(img, hsix[0], hsix[1], ysz / 2);
}
{
Image img;
if(!img.load(fname)) {
- fprintf(stderr, "failed to load 2D texture: %s\n", fname);
+ error_log("failed to load 2D texture: %s\n", fname);
return false;
}
set_image(img);
- printf("loaded 2D texture: %s\n", fname);
+ info_log("loaded 2D texture: %s\n", fname);
return true;
}
{
}
-Texture *TextureSet::get_texture(const char *name, TextureType type) const
+Texture *TextureSet::get_texture(const char *name, TextureType type, const DataMap *dmap) const
{
- std::map<std::string, Texture*>::const_iterator iter = data.find(name);
+ char *fname;
+ int nsize = dmap ? dmap->path_size(name) : 0;
+ if(nsize) {
+ fname = (char*)alloca(nsize);
+ dmap->lookup(name, fname, nsize);
+ //debug_log("texture lookup: %s -> %s\n", name, fname);
+ } else {
+ fname = (char*)name;
+ //debug_log("texture lookup failed, using: %s\n", fname);
+ }
+
+ std::map<std::string, Texture*>::const_iterator iter = data.find(fname);
if(iter != data.end()) {
return iter->second;
}
Texture *res = create();
- data[name] = res;
+ data[fname] = res;
res->create_default(type);
- resman_lookup(rman, name, res);
+ resman_lookup(rman, fname, res);
return res;
}
bool TextureSet::load_tex(Texture *tex, const char *fname)
{
Image *img = new Image;
+ img->name = fname;
if(!img->load(fname)) {
delete img;
return false;
bool TextureSet::done_tex(Texture *tex)
{
+ //debug_log("TextureSet::done_tex [%s]\n", tex->img->name.c_str());
if(!tex->img) {
return false;
}