Commit ee55a3f9 authored by Philip Trettner's avatar Philip Trettner
Browse files

Merge branch 'experimental' of...

Merge branch 'experimental' of dawes.informatik.rwth-aachen.de:/data/git-repository/acgl/libraries/acgl into experimental
parents f29a25d7 ee341708
......@@ -21,7 +21,13 @@ namespace ACGL{
namespace OpenGL{
//! loads the texture and creates mip maps
SharedTexture2D loadTexture2D( const std::string &_filename );
SharedTexture2D loadTexture2D(const std::string& _filename);
//! loads the texture including mipmaps from a DDS file
//! supports DXT1, DXT3 and DXT5 compression
SharedTexture2D loadTexture2DFromDDS (const std::string& _filename);
SharedTexture3D loadTexture3DFromDDS (const std::string& _filename);
SharedTextureCubeMap loadTextureCubeMapFromDDS(const std::string& _filename);
}
}
......@@ -36,7 +36,7 @@ SharedVertexArrayObject loadVertexArrayObject(const std::string& _filename, bool
//! http://www.graphics.rwth-aachen.de/redmine/projects/acgl/wiki/Vao_File_Format
//! A VAO file can contain several named EABs. Only the EAB whose name matches _eabName will be loaded
//! and attached to the VAO. If _eabName is left blank, the first defined EAB will be used.
SharedVertexArrayObject loadVertexArrayObjectVAO(const std::string& _filename, const std::string& _eabName = "");
SharedVertexArrayObject loadVertexArrayObjectFromVAO(const std::string& _filename, const std::string& _eabName = "");
///////////////////////////////////////////////////////////////////////////////////////////////////
// library specific save
......
......@@ -159,6 +159,9 @@
#endif
#else // ACGL_OPENGL_ES
// desktop:
#ifndef __glew_h__
// if glew was already included, don't include anything else
// not the recommended way to do it but possible
#if (defined(__APPLE__) || defined(MACOSX)) && defined(ACGL_OPENGL_PROFILE_FULL)
#if ACGL_OPENGL_VERSION > 21
#warning "On MacOS X only core profile is supported for OpenGL >= 3.2"
......@@ -226,6 +229,9 @@
#endif
#endif // ACGL_OPENGL_PROFILE_CORE
#endif // ACGL_USE_GLEW
#else
#define ACGL_USE_GLEW
#endif // __GLEW__
#endif // ACGL_OPENGL_ES
#endif // ACGL_OPENGL_GL_HH
......@@ -110,6 +110,8 @@ public:
inline GLenum getInternalFormat (void) const { return mInternalFormat; }
inline GLint getMinFilter (void) const { return getParameterI(GL_TEXTURE_MIN_FILTER); }
inline GLint getMagFilter (void) const { return getParameterI(GL_TEXTURE_MAG_FILTER); }
inline GLint getBaseLevel (void) const { return getParameterI(GL_TEXTURE_BASE_LEVEL); }
inline GLint getMaxLevel (void) const { return getParameterI(GL_TEXTURE_MAX_LEVEL); }
inline GLint getMinLOD (void) const { return getParameterI(GL_TEXTURE_MIN_LOD); }
inline GLint getMaxLOD (void) const { return getParameterI(GL_TEXTURE_MAX_LOD); }
inline GLfloat getLODBias (void) const { return getParameterF(GL_TEXTURE_LOD_BIAS); }
......@@ -156,6 +158,12 @@ public:
void setWrap(GLenum _wrapS, GLenum _wrapT = 0, GLenum _wrapR = 0);
#endif
//! lowest defined mipmap level
void setBaseLevel( GLint _level = -1000 );
//! highest defined mipmap level
void setMaxLevel( GLint _level = 1000 );
//! lowest mipmap level to use
void setMinLOD( GLint _lod = -1000 );
......
#ifndef __NV_DDS_H__
#define __NV_DDS_H__
#ifndef NVDDS_PROJECT //defined if building nv_dds library
#if _MSC_VER >= 1300
#ifdef _DLL
#pragma message("Note: including lib: nv_dds.lib\n")
#pragma comment(lib, "nv_dds.lib")
#else
#error "Your project doesn't use the Multithreaded DLL Runtime"
#endif
#endif
#endif
#if defined(WIN32)
# include <windows.h>
#endif
#include <string>
#include <deque>
#include <assert.h>
#if defined(MACOS)
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#else
#include <GL/gl.h>
#include <GL/glext.h>
#endif
namespace nv_dds
{
// surface description flags
const uint32_t DDSF_CAPS = 0x00000001l;
const uint32_t DDSF_HEIGHT = 0x00000002l;
const uint32_t DDSF_WIDTH = 0x00000004l;
const uint32_t DDSF_PITCH = 0x00000008l;
const uint32_t DDSF_PIXELFORMAT = 0x00001000l;
const uint32_t DDSF_MIPMAPCOUNT = 0x00020000l;
const uint32_t DDSF_LINEARSIZE = 0x00080000l;
const uint32_t DDSF_DEPTH = 0x00800000l;
// pixel format flags
const uint32_t DDSF_ALPHAPIXELS = 0x00000001l;
const uint32_t DDSF_FOURCC = 0x00000004l;
const uint32_t DDSF_RGB = 0x00000040l;
const uint32_t DDSF_RGBA = 0x00000041l;
// dwCaps1 flags
const uint32_t DDSF_COMPLEX = 0x00000008l;
const uint32_t DDSF_TEXTURE = 0x00001000l;
const uint32_t DDSF_MIPMAP = 0x00400000l;
// dwCaps2 flags
const uint32_t DDSF_CUBEMAP = 0x00000200l;
const uint32_t DDSF_CUBEMAP_POSITIVEX = 0x00000400l;
const uint32_t DDSF_CUBEMAP_NEGATIVEX = 0x00000800l;
const uint32_t DDSF_CUBEMAP_POSITIVEY = 0x00001000l;
const uint32_t DDSF_CUBEMAP_NEGATIVEY = 0x00002000l;
const uint32_t DDSF_CUBEMAP_POSITIVEZ = 0x00004000l;
const uint32_t DDSF_CUBEMAP_NEGATIVEZ = 0x00008000l;
const uint32_t DDSF_CUBEMAP_ALL_FACES = 0x0000FC00l;
const uint32_t DDSF_VOLUME = 0x00200000l;
// compressed texture types
const uint32_t FOURCC_DXT1 = 0x31545844l; //(MAKEFOURCC('D','X','T','1'))
const uint32_t FOURCC_DXT3 = 0x33545844l; //(MAKEFOURCC('D','X','T','3'))
const uint32_t FOURCC_DXT5 = 0x35545844l; //(MAKEFOURCC('D','X','T','5'))
struct DXTColBlock
{
uint16_t col0;
uint16_t col1;
uint8_t row[4];
};
struct DXT3AlphaBlock
{
uint16_t row[4];
};
struct DXT5AlphaBlock
{
uint8_t alpha0;
uint8_t alpha1;
uint8_t row[6];
};
struct DDS_PIXELFORMAT
{
uint32_t dwSize;
uint32_t dwFlags;
uint32_t dwFourCC;
uint32_t dwRGBBitCount;
uint32_t dwRBitMask;
uint32_t dwGBitMask;
uint32_t dwBBitMask;
uint32_t dwABitMask;
};
struct DDS_HEADER
{
uint32_t dwSize;
uint32_t dwFlags;
uint32_t dwHeight;
uint32_t dwWidth;
uint32_t dwPitchOrLinearSize;
uint32_t dwDepth;
uint32_t dwMipMapCount;
uint32_t dwReserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t dwCaps1;
uint32_t dwCaps2;
uint32_t dwReserved2[3];
};
enum TextureType
{
TextureNone,
TextureFlat, // 1D, 2D, and rectangle textures
Texture3D,
TextureCubemap
};
class CSurface
{
public:
CSurface();
CSurface(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels);
CSurface(const CSurface &copy);
CSurface &operator= (const CSurface &rhs);
virtual ~CSurface();
operator unsigned char*() const;
virtual void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels);
virtual void clear();
inline unsigned int get_width() const { return m_width; }
inline unsigned int get_height() const { return m_height; }
inline unsigned int get_depth() const { return m_depth; }
inline unsigned int get_size() const { return m_size; }
private:
unsigned int m_width;
unsigned int m_height;
unsigned int m_depth;
unsigned int m_size;
unsigned char *m_pixels;
};
class CTexture : public CSurface
{
friend class CDDSImage;
public:
CTexture();
CTexture(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels);
CTexture(const CTexture &copy);
CTexture &operator= (const CTexture &rhs);
~CTexture();
void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels);
void clear();
inline const CSurface &get_mipmap(unsigned int index) const
{
assert(!m_mipmaps.empty());
assert(index < m_mipmaps.size());
return m_mipmaps[index];
}
inline void add_mipmap(const CSurface &mipmap)
{
m_mipmaps.push_back(mipmap);
}
inline unsigned int get_num_mipmaps() const { return (unsigned int)m_mipmaps.size(); }
protected:
inline CSurface &get_mipmap(unsigned int index)
{
assert(!m_mipmaps.empty());
assert(index < m_mipmaps.size());
return m_mipmaps[index];
}
private:
std::deque<CSurface> m_mipmaps;
};
class CDDSImage
{
public:
CDDSImage();
~CDDSImage();
void create_textureFlat(unsigned int format, unsigned int components, const CTexture &baseImage);
void create_texture3D(unsigned int format, unsigned int components, const CTexture &baseImage);
void create_textureCubemap(unsigned int format, unsigned int components,
const CTexture &positiveX, const CTexture &negativeX,
const CTexture &positiveY, const CTexture &negativeY,
const CTexture &positiveZ, const CTexture &negativeZ);
void clear();
bool load(std::string filename, bool flipImage = true);
bool save(std::string filename, bool flipImage = true);
/*
bool upload_texture1D();
bool upload_texture2D(unsigned int imageIndex = 0, GLenum target = GL_TEXTURE_2D);
bool upload_texture3D();
bool upload_textureRectangle();
bool upload_textureCubemap();
*/
inline operator unsigned char*()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0];
}
inline unsigned int get_width()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0].get_width();
}
inline unsigned int get_height()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0].get_height();
}
inline unsigned int get_depth()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0].get_depth();
}
inline unsigned int get_size()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0].get_size();
}
inline unsigned int get_num_mipmaps()
{
assert(m_valid);
assert(!m_images.empty());
return m_images[0].get_num_mipmaps();
}
inline const CSurface &get_mipmap(unsigned int index) const
{
assert(m_valid);
assert(!m_images.empty());
assert(index < m_images[0].get_num_mipmaps());
return m_images[0].get_mipmap(index);
}
inline const CTexture &get_cubemap_face(unsigned int face) const
{
assert(m_valid);
assert(!m_images.empty());
assert(m_images.size() == 6);
assert(m_type == TextureCubemap);
assert(face < 6);
return m_images[face];
}
inline unsigned int get_components() { return m_components; }
inline unsigned int get_format() { return m_format; }
inline TextureType get_type() { return m_type; }
inline bool is_compressed()
{
if ((m_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ||
(m_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) ||
(m_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT))
return true;
else
return false;
}
inline bool is_cubemap() { return (m_type == TextureCubemap); }
inline bool is_volume() { return (m_type == Texture3D); }
inline bool is_valid() { return m_valid; }
inline bool is_dword_aligned()
{
assert(m_valid);
int dwordLineSize = get_dword_aligned_linesize(get_width(), m_components*8);
int curLineSize = get_width() * m_components;
return (dwordLineSize == curLineSize);
}
private:
unsigned int clamp_size(unsigned int size);
unsigned int size_dxtc(unsigned int width, unsigned int height);
unsigned int size_rgb(unsigned int width, unsigned int height);
inline void swap_endian(void *val);
// calculates 4-byte aligned width of image
inline unsigned int get_dword_aligned_linesize(unsigned int width, unsigned int bpp)
{
return ((width * bpp + 31) & -32) >> 3;
}
void flip(CSurface &surface);
void flip_texture(CTexture &texture);
void swap(void *byte1, void *byte2, unsigned int size);
void flip_blocks_dxtc1(DXTColBlock *line, unsigned int numBlocks);
void flip_blocks_dxtc3(DXTColBlock *line, unsigned int numBlocks);
void flip_blocks_dxtc5(DXTColBlock *line, unsigned int numBlocks);
void flip_dxt5_alpha(DXT5AlphaBlock *block);
void write_texture(const CTexture &texture, FILE *fp);
unsigned int m_format;
unsigned int m_components;
TextureType m_type;
bool m_valid;
std::deque<CTexture> m_images;
};
}
#endif
......@@ -5,6 +5,7 @@
**********************************************************************/
#include <ACGL/OpenGL/Data/TextureLoadStore.hh>
#include <ACGL/Base/FileHelpers.hh>
using namespace ACGL;
using namespace ACGL::OpenGL;
......@@ -15,6 +16,13 @@ namespace OpenGL{
SharedTexture2D loadTexture2D( const std::string &_filename )
{
std::string fileEnding = Base::FileHelpers::getFileEnding(_filename);
if(fileEnding == "dds")
{
return loadTexture2DFromDDS(_filename);
}
else
{
SharedTexture2D texture = SharedTexture2D( new Texture2D() );
SharedTextureData data = loadTextureData( _filename );
if (!data) {
......@@ -26,6 +34,7 @@ SharedTexture2D loadTexture2D( const std::string &_filename )
texture->generateMipmaps(); // calculates all remaining mipmap levels
return texture;
}
}
}
......
/***********************************************************************
* Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Data/TextureLoadStore.hh>
#include <nv_dds/nv_dds.h>
#include <fstream>
using namespace ACGL;
using namespace ACGL::OpenGL;
using namespace ACGL::Utils;
using namespace nv_dds;
namespace {
GLenum getDDSInternalFormat(bool compressed, GLenum format)
{
GLenum internal_format = format;
// Internal format for uncompressed color formats
// For compressed textures, internal_format == image.get_format(), i.e. no conversion
if(format == GL_BGRA) internal_format = GL_RGBA;
if(format == GL_BGR) internal_format = GL_RGB;
if(format == GL_RED) internal_format = GL_RED;
return internal_format;
}
// To prevent code duplication, wrap glTexImage calls to take a compressed parameter
void texImage2D(bool compressed, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
if(compressed)
glCompressedTexImage2D(target, level, internalformat, width, height, 0, imageSize, data);
else
glTexImage2D(target, level, internalformat, width, height, 0, format, GL_UNSIGNED_BYTE, data);
}
void texImage3D(bool compressed, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
if(compressed)
glCompressedTexImage3D(target, level, internalformat, width, height, depth, 0, imageSize, data);
else
glTexImage3D(target, level, internalformat, width, height, depth, 0, format, GL_UNSIGNED_BYTE, data);
}
}
namespace ACGL {
namespace OpenGL {
SharedTexture2D loadTexture2DFromDDS(const std::string& _filename)
{
CDDSImage image;
SharedTexture2D texture;
if(image.load(_filename))
{
GLenum internal_format = getDDSInternalFormat(image.is_compressed(), image.get_format());
if(image.is_volume() || image.is_cubemap())
{
ACGL::Utils::error() << _filename << " is not a 2D texture" << std::endl;
}
else
{
// It is a 2D texture
texture = SharedTexture2D(new Texture2D(glm::uvec2(image.get_width(), image.get_height()), internal_format));
texture->bind();
texImage2D(image.is_compressed(), texture->getTarget(), 0, internal_format, image.get_width(), image.get_height(), image.get_format(), image.get_size(), image);
for(unsigned int i = 0; i < image.get_num_mipmaps(); i++)
{
const CSurface& mipmap = image.get_mipmap(i);
texImage2D(image.is_compressed(), texture->getTarget(), i+1, internal_format, mipmap.get_width(), mipmap.get_height(), image.get_format(), mipmap.get_size(), mipmap);
}
texture->setMaxLevel(image.get_num_mipmaps());
}
}
else
{
ACGL::Utils::error() << "could not open " << _filename << std::endl;
}
return texture;
}
SharedTexture3D loadTexture3DFromDDS(const std::string& _filename)
{
CDDSImage image;
SharedTexture3D texture;
if(image.load(_filename))
{
GLenum internal_format = getDDSInternalFormat(image.is_compressed(), image.get_format());
if(image.is_volume())
{
// It is a 3D texture
texture = SharedTexture3D(new Texture3D(glm::uvec3(image.get_width(), image.get_height(), image.get_depth()), internal_format));
texture->bind();
texImage3D(image.is_compressed(), texture->getTarget(), 0, internal_format, image.get_width(), image.get_height(), image.get_depth(), image.get_format(), image.get_size(), image);
for(unsigned int i = 0; i < image.get_num_mipmaps(); i++)
{
const CSurface& mipmap = image.get_mipmap(i);
texImage3D(image.is_compressed(), texture->getTarget(), i+1, internal_format, mipmap.get_width(), mipmap.get_height(), mipmap.get_depth(), image.get_format(), mipmap.get_size(), mipmap);
}
texture->setMaxLevel(image.get_num_mipmaps());
}
else
{
ACGL::Utils::error() << _filename << " is not a 3D texture" << std::endl;
}
}
else
{
ACGL::Utils::error() << "could not open " << _filename << std::endl;
}
return texture;
}
SharedTextureCubeMap loadTextureCubeMapFromDDS(const std::string& _filename)
{
CDDSImage image;
SharedTextureCubeMap texture;
if(image.load(_filename))
{
GLenum internal_format = getDDSInternalFormat(image.is_compressed(), image.get_format());
if(image.is_cubemap())
{
// It is a cube map texture
texture = SharedTextureCubeMap(new TextureCubeMap(glm::uvec2(image.get_width(), image.get_height()), internal_format));
texture->bind();
unsigned int numMipmapLevels = 1000;
for(unsigned int i = 0; i < 6; ++i)
{
GLenum target = GL_INVALID_ENUM;
switch(i)
{
case 0: target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
case 1: target = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
case 2: target = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
case 3: target = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
case 4: target = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
case 5: target = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
}
const CTexture& face = image.get_cubemap_face(i);
<