1
0
forked from 0ad/0ad

no message

This was SVN commit r193.
This commit is contained in:
janwas 2004-04-06 16:17:04 +00:00
parent fa884d356d
commit d6dbf229a5

View File

@ -147,7 +147,7 @@ static int dds_load(const char* fn, const u8* p, size_t size, Tex* t)
else
{
const u32 sd_size = read_le32(&surf->dwSize);
const u32 sd_flags = read_le32(&surf->dwSize);
const u32 sd_flags = read_le32(&surf->dwFlags);
const u32 h = read_le32(&surf->dwHeight);
const u32 w = read_le32(&surf->dwWidth);
const u32 img_size = read_le32(&surf->dwLinearSize);
@ -218,7 +218,7 @@ static int dds_load(const char* fn, const u8* p, size_t size, Tex* t)
if(err)
{
printf("dds_load: %s: %s\n", fn, err);
debug_out("dds_load: %s: %s\n", fn, err);
return -1;
}
@ -289,7 +289,7 @@ static int tga_load(const char* fn, const u8* ptr, size_t size, Tex* t)
if(fmt == ~0)
err = "invalid format or bpp";
if(desc & 0x18)
if(desc & 0x30)
err = "image is not bottom-up and left-to-right";
if(size < hdr_size + img_size)
err = "size < image size";
@ -303,7 +303,7 @@ static int tga_load(const char* fn, const u8* ptr, size_t size, Tex* t)
if(err)
{
printf("tga_load: %s: %s\n", fn, err);
debug_out("tga_load: %s: %s\n", fn, err);
return -1;
}
@ -395,7 +395,7 @@ static int bmp_load(const char* fn, const u8* ptr, size_t size, Tex* t)
if(err)
{
printf("bmp_load: %s: %s\n", fn, err);
debug_out("bmp_load: %s: %s\n", fn, err);
return -1;
}
@ -448,7 +448,7 @@ static int raw_load(const char* fn, const u8* ptr, size_t size, Tex* t)
return 0;
}
printf("raw_load: %s: %s\n", fn, "no matching format found");
debug_out("raw_load: %s: %s\n", fn, "no matching format found");
return -1;
}
@ -508,7 +508,7 @@ static int png_load(const char* fn, const u8* ptr, size_t size, Tex* t)
if(setjmp(png_jmpbuf(png_ptr)))
{
fail:
printf("png_load: %s: %s\n", fn, err? err : "");
debug_out("png_load: %s: %s\n", fn, err? err : "");
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
return -1;
}
@ -618,7 +618,7 @@ static int jp2_load(const char* fn, const u8* ptr, size_t size, Tex* t)
err = "channel precision != 8";
fail:
printf("jp2_load: %s: %s\n", fn, err);
debug_out("jp2_load: %s: %s\n", fn, err);
// TODO: destroy image
return -1;
}
@ -760,11 +760,17 @@ int tex_bind(const Handle h)
glBindTexture(GL_TEXTURE_2D, 0);
return ERR_INVALID_HANDLE;
}
else
#ifndef NDEBUG
if(!glIsTexture(t->id))
{
glBindTexture(GL_TEXTURE_2D, t->id);
return 0;
assert(0 && "tex_bind: Tex.id is not a valid texture");
return -1;
}
#endif
glBindTexture(GL_TEXTURE_2D, t->id);
return 0;
}
@ -775,34 +781,75 @@ int tex_upload(const Handle ht, int filter, int int_fmt)
{
H_DEREF(ht, Tex, t);
// data we will take from Tex
GLsizei w;
GLsizei h;
GLenum fmt;
void* tex_data;
u32 bpp; // not used directly in gl calls
const char* err = 0;
// pointer to texture data
size_t tex_file_size;
void* tex_file = mem_get_ptr(t->hm, &tex_file_size);
if(!tex_file)
err = "texture file not loaded";
// possible causes: texture file header is invalid,
// or file wasn't loaded completely.
if(t->ofs > tex_file_size)
err = "offset to texture data exceeds file size";
tex_data = (char*)tex_file + t->ofs;
// width, height
w = (GLsizei)t->w;
h = (GLsizei)t->h;
// if w or h is 0, texture file probably not loaded successfully.
if(w == 0 || h == 0)
err = "width or height is 0 - texture probably not loaded successfully";
// greater than max supported tex dimension?
// no-op if oglInit not yet called
if(t->w > (uint)max_tex_size || t->h > (uint)max_tex_size)
{
assert(!"tex_upload: image dimensions exceed OpenGL implementation limit");
return 0;
}
if(w > (GLsizei)max_tex_size || h > (GLsizei)max_tex_size)
err = "texture dimensions exceed OpenGL implementation limit";
// both NV_texture_rectangle and subtexture require work for the client
// (changing tex coords) => we'll just disallow non-power of 2 textures.
// TODO: ARB_texture_non_power_of_two
if(!is_pow2(t->w) || !is_pow2(t->h))
if(!is_pow2(w) || !is_pow2(h))
err = "width or height is not a power-of-2";
// texel format
fmt = (GLenum)t->fmt;
if(!fmt)
err = "texel format is 0";
// can't really check against a list of valid formats - loaders
// may define their own. not necessary anyway - if non-0, assume
// loader knows what it's doing, and that the format is valid.
// bits per pixel
bpp = t->bpp;
// half-hearted sanity check: must be divisible by 4.
// don't bother checking all values.
if(bpp % 4 || bpp > 32)
err = "invalid bpp? should be one of {4,8,16,24,32}";
if(err)
{
assert(!"tex_upload: image is not power-of-2");
return 0;
const char* fn = h_filename(ht);
if(!fn)
{
fn = "(could not determine filename)";
assert(0);
}
debug_out("tex_upload: %s: %s\n", fn, err);
assert(0 && "tex_upload failed");
return -1;
}
tex_bind(ht);
// get pointer to image data
size_t size;
void* p = mem_get_ptr(t->hm, &size);
if(!p)
{
assert(0 && "tex_upload: mem object is a NULL pointer");
return 0;
}
const u8* img = (const u8*)p + t->ofs;
int ret = tex_bind(ht);
// we know ht is valid (H_DEREF above), but tex_bind can
// fail in debug builds if Tex.id isn't a valid texture name
if(ret < 0)
return ret;
// set filter
if(!filter)
@ -814,34 +861,71 @@ int tex_upload(const Handle ht, int filter, int int_fmt)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag);
const bool has_alpha = t->fmt == GL_RGBA || t->fmt == GL_BGRA || t->fmt == GL_LUMINANCE_ALPHA || t->fmt == GL_ALPHA;
const bool has_alpha = fmt == GL_RGBA || fmt == GL_BGRA || fmt == GL_LUMINANCE_ALPHA || fmt == GL_ALPHA;
// S3TC compressed
if(t->fmt >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
t->fmt <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
if(fmt >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
fmt <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
{
const int img_size = t->w * t->h * t->bpp / 8;
assert(4+sizeof(DDSURFACEDESC2)+img_size == size && "tex_upload: dds file size mismatch");
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, t->fmt, t->w, t->h, 0, img_size, img);
const int tex_size = w * h * bpp / 8;
assert(4+sizeof(DDSURFACEDESC2)+tex_size == tex_file_size && "tex_upload: dds file size mismatch");
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size, tex_data);
}
// normal
else
{
// calc internal fmt from format and global bpp, if not passed as a param
// internal fmt not explicitly requested. choose one based
// on texture format and the global quality setting tex_bpp.
// we could just let the driver choose, but it's good to allow
// the user to control the actual texture size (for tweaking).
if(!int_fmt)
{
if(t->bpp == 32)
int_fmt = (tex_bpp == 32)? GL_RGBA8 : GL_RGBA4;
else if(t->bpp == 24)
int_fmt = (tex_bpp == 32)? GL_RGB8 : GL_RGB5;
else if(t->bpp == 16)
int_fmt = (tex_bpp == 32)? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE4_ALPHA4;
else if(t->fmt == GL_ALPHA)
int_fmt = (tex_bpp == 32)? GL_ALPHA8 : GL_ALPHA4;
else if(t->fmt == GL_LUMINANCE)
int_fmt = (tex_bpp == 32)? GL_LUMINANCE8 : GL_LUMINANCE4;
// high quality, 32 bit textures (8 bits per component)
if(tex_bpp == 32)
{
switch(fmt)
{
case GL_RGBA:
int_fmt = GL_RGBA8;
break;
case GL_RGB:
int_fmt = GL_RGB8;
break;
case GL_LUMINANCE_ALPHA:
int_fmt = GL_LUMINANCE8_ALPHA8;
break;
case GL_ALPHA:
int_fmt = GL_ALPHA8;
break;
case GL_LUMINANCE:
int_fmt = GL_LUMINANCE8;
break;
}
}
// low quality, 16 bit textures (4 bits per component)
else
return -1;
{
switch(fmt)
{
case GL_RGBA:
int_fmt = GL_RGBA4;
break;
case GL_RGB:
int_fmt = GL_RGB4;
break;
case GL_LUMINANCE_ALPHA:
int_fmt = GL_LUMINANCE4_ALPHA4;
break;
case GL_ALPHA:
int_fmt = GL_ALPHA4;
break;
case GL_LUMINANCE:
int_fmt = GL_LUMINANCE4;
break;
}
}
// failed to choose an internal format
}
// check if SGIS_generate_mipmap is available (once)
@ -851,14 +935,14 @@ int tex_upload(const Handle ht, int filter, int int_fmt)
// manual mipmap gen via GLU (box filter)
if(mipmap && !sgm_avl)
gluBuild2DMipmaps(GL_TEXTURE_2D, int_fmt, t->w, t->h, t->fmt, GL_UNSIGNED_BYTE, img);
gluBuild2DMipmaps(GL_TEXTURE_2D, int_fmt, t->w, t->h, t->fmt, GL_UNSIGNED_BYTE, tex_data);
// auto mipmap gen, or no mipmap
else
{
if(mipmap)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, t->w, t->h, 0, t->fmt, GL_UNSIGNED_BYTE, img);
glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, t->w, t->h, 0, t->fmt, GL_UNSIGNED_BYTE, tex_data);
}
}