X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftexture2d.cpp;h=455c7314cb4d2a04676b1ac6e6612884e95ef212;hb=a361efc05fcad11b2918f3cd7abdebe794b131d8;hp=c6137d73b60f41c0adeb62f5d6547406a64b9cf2;hpb=5318aa4fd553be4ce0bc428e73592b787842cdea;p=libs%2Fgl.git diff --git a/source/texture2d.cpp b/source/texture2d.cpp index c6137d73..455c7314 100644 --- a/source/texture2d.cpp +++ b/source/texture2d.cpp @@ -5,122 +5,72 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ -#include #include "except.h" +#include "ilwrap.h" #include "texture2d.h" using namespace std; +#include + namespace Msp { namespace GL { -Texture2D::Texture2D() +Texture2D::Texture2D(): + width(0), + height(0) { target=GL_TEXTURE_2D; + bind(); } -/** -Uploads an image into the texture. Direct wrapper for glTexImage2D. -*/ -void Texture2D::image(int level, int ifmt, sizei wd, sizei ht, int border, GLenum fmt, GLenum type, void *data) +void Texture2D::storage(PixelFormat fmt, sizei wd, sizei ht, int brd) +{ + if(width>0) + throw InvalidState("Texture storage may only be specified once"); + if(wd==0 || ht==0) + throw InvalidParameterValue("Invalid texture dimensions"); + + ifmt=fmt; + width=wd; + height=ht; + border=brd; +} + +void Texture2D::image(int level, PixelFormat fmt, GLenum type, const void *data) { + if(width==0) + throw InvalidState("Texture storage has not been specified"); + maybe_bind(); - glTexImage2D(target, level, ifmt, wd, ht, border, fmt, type, data); - width_=wd; - height_=ht; + glTexImage2D(target, level, ifmt, width, height, border, fmt, type, data); } -/** -Uploads an image into the texture, with a simpler interface. -*/ -void Texture2D::image(int level, sizei wd, sizei ht, TextureFormat tfmt, void *data) +void Texture2D::sub_image(int level, int x, int y, sizei wd, sizei ht, PixelFormat fmt, GLenum type, const void *data) { - int ifmt; - int fmt; - int type; - - switch(tfmt) - { - case LUMINANCE8: ifmt=GL_LUMINANCE; fmt=GL_LUMINANCE; type=GL_UNSIGNED_BYTE; break; - case LUMINANCE8_ALPHA8: ifmt=GL_LUMINANCE_ALPHA; fmt=GL_LUMINANCE_ALPHA; type=GL_UNSIGNED_BYTE; break; - case RGB8: ifmt=GL_RGB; fmt=GL_RGB; type=GL_UNSIGNED_BYTE; break; - case RGBA8: ifmt=GL_RGBA; fmt=GL_RGBA; type=GL_UNSIGNED_INT_8_8_8_8_REV; break; - case BGR8: ifmt=GL_RGB; fmt=GL_BGR; type=GL_UNSIGNED_BYTE; break; - case BGRA8: ifmt=GL_RGBA; fmt=GL_BGRA; type=GL_UNSIGNED_INT_8_8_8_8_REV; break; - default: throw InvalidParameterValue("Invalid texture format"); - } - - image(level, ifmt, wd, ht, 0, fmt, type, data); + if(width==0) + throw InvalidState("Texture storage has not been specified"); + + maybe_bind(); + + glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data); } -/** -Loads an image from a file and uploads it into the texture. Currently assumes -the file to be a PNG image. -*/ -void Texture2D::image(const string &fn) +void Texture2D::load_image(const string &fn) { - FILE *file=fopen(fn.c_str(), "r"); - if(!file) throw Exception("Couldn't open "+fn); - - char sig[8]; - fread(sig, 8, 1, file); - if(png_sig_cmp((png_byte *)sig, 0, 8)) - throw Exception("Not a PNG image"); - - png_struct *pngs=png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - png_info *pngi=png_create_info_struct(pngs); - - if(setjmp(png_jmpbuf(pngs))) - { - png_destroy_read_struct(&pngs, &pngi, 0); - fclose(file); - throw Exception("PNG error"); - } - png_init_io(pngs, file); - png_set_sig_bytes(pngs, 8); - - png_read_info(pngs, pngi); - - unsigned wd=png_get_image_width(pngs, pngi); - unsigned ht=png_get_image_height(pngs, pngi); - unsigned depth=png_get_bit_depth(pngs, pngi); - unsigned ctype=png_get_color_type(pngs, pngi); - - if(ctype==PNG_COLOR_TYPE_PALETTE || depth<8) - { - png_destroy_read_struct(&pngs, &pngi, 0); - fclose(file); - throw Exception("Invalid color type or bit depth"); - } - - if(depth==16) - png_set_strip_16(pngs); - - TextureFormat fmt; - unsigned planes; - - switch(ctype) - { - case PNG_COLOR_TYPE_GRAY: fmt=LUMINANCE8; planes=1; break; - case PNG_COLOR_TYPE_GRAY_ALPHA: fmt=LUMINANCE8_ALPHA8; planes=2; break; - case PNG_COLOR_TYPE_RGB: fmt=RGB8; planes=3; break; - case PNG_COLOR_TYPE_RGB_ALPHA: fmt=RGBA8; planes=4; break; - default: throw Exception("Invalid color type"); - } - - png_byte *data=new png_byte[wd*ht*planes]; - png_byte *row_ptrs[ht]; - for(unsigned i=0; i