Jason McKesson avatar Jason McKesson committed d72cfb5 Merge

Merge

Comments (0)

Files changed (11)

Tut 14 Textures Are Not Pictures/Material Texture.cpp

 
 	try
 	{
-		pImageSet.reset(glimg::loaders::stb::LoadFromFile("data\\main.tga"));
+		pImageSet.reset(glimg::loaders::dds::LoadFromFile("data\\main.dds"));
 		std::auto_ptr<glimg::Image> pImage(pImageSet->GetImage(0, 0, 0));
 
 		glimg::Dimensions dims = pImage->GetDimensions();
 		glGenTextures(1, &g_shineTexture);
 		glBindTexture(GL_TEXTURE_2D, g_shineTexture);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, dims.width, dims.height, 0,
-			GL_RGB, GL_UNSIGNED_BYTE, pImage->GetImageData());
+			GL_RED, GL_UNSIGNED_BYTE, pImage->GetImageData());
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
 		glBindTexture(GL_TEXTURE_2D, 0);
Add a comment to this file

Tut 14 Textures Are Not Pictures/data/main.tga

Removed
Old image

glimg/Test/windows.cpp

 	TestImageFormats();
 
 //	glimg::ImageSet *pImgSet = glimg::loaders::test::TestImage2D();
-	glimg::ImageSet *pImgSet = glimg::loaders::stb::LoadFromFile("bitmap.png");
+	glimg::ImageSet *pImgSet = glimg::loaders::dds::LoadFromFile("main.dds");
+//	glimg::ImageSet *pImgSet = glimg::loaders::stb::LoadFromFile("bitmap.png");
 
 	texture = glimg::CreateTexture(pImgSet, 0);
 	glBindTexture(GL_TEXTURE_2D, texture);
 
 	delete pImgSet;
 
+
 	while(!done)									// Loop That Runs While done=FALSE
 	{
 		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// Is There A Message Waiting?

glimg/include/glimg/DdsLoader.h

+
+#ifndef GLIMG_DIRECT_DRAW_SURFACE_LOADER_H
+#define GLIMG_DIRECT_DRAW_SURFACE_LOADER_H
+
+#include <string>
+#include "ImageSet.h"
+
+namespace glimg
+{
+	namespace loaders
+	{
+		namespace dds
+		{
+			class DdsLoaderException : public std::exception
+			{
+			public:
+
+				virtual const char *what() {return message.c_str();}
+
+			protected:
+				std::string message;
+			};
+
+			class DdsFileNotFoundException : public DdsLoaderException
+			{
+			public:
+				explicit DdsFileNotFoundException(const std::string &filename)
+				{
+					message = "The file \"" + filename + "\" could not be found.";
+				}
+			};
+
+			class DdsFileMalformedException : public DdsLoaderException
+			{
+			public:
+				DdsFileMalformedException(const std::string &filename, const std::string &msg)
+				{
+					if(filename.empty())
+						message = "The data is not a properly formatted DDS.\n";
+					else
+						message = "The file \"" + filename + "\" is not a proper DDS file.\n";
+
+					message += msg;
+				}
+			};
+
+			class DdsFileUnsupportedException : public DdsLoaderException
+			{
+			public:
+				DdsFileUnsupportedException(const std::string &filename, const std::string &msg)
+				{
+					if(filename.empty())
+						message = "The data uses DDS features that are not yet supported.\n";
+					else
+						message = "The file \"" + filename + "\" uses DDS features that are not yet supported.\n";
+
+					message += msg;
+				}
+			};
+
+			ImageSet *LoadFromFile(const std::string &filename);
+			ImageSet *LoadFromMemory(const unsigned char *buffer, size_t bufSize);
+		}
+	}
+}
+
+#endif //GLIMG_DIRECT_DRAW_SURFACE_LOADER_H

glimg/include/glimg/Loaders.h

 
 #include "TestLoader.h"
 #include "StbLoader.h"
+#include "DdsLoader.h"
 
 
 #endif //GLIMG_LOADERS_H

glimg/include/glimg/TextureGenerator.h

 	{
 		unsigned int format;
 		unsigned int type;
+		unsigned int blockByteCount;
 	};
 
 	OpenGLUploadData GetUploadFormatType(const ImageFormat &format, unsigned int forceConvertBits);

glimg/source/DdsLoader.cpp

+
+#include <vector>
+#include <stdio.h>
+#include "glimg/ImageSet.h"
+#include "ImageSetImpl.h"
+#include "glimg/ImageCreator.h"
+#include "glimg/DdsLoader.h"
+#include "DdsLoaderInt.h"
+
+#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
+
+namespace glimg
+{
+namespace loaders
+{
+namespace dds
+{
+	namespace
+	{
+		typedef std::vector<unsigned char> FileBuffer;
+
+		class DDSStorage : public glimg::MemoryObject
+		{
+		public:
+			explicit DDSStorage(FileBuffer &transferOwnership)
+			{
+				pixelData.swap(transferOwnership);
+			}
+
+			virtual ~DDSStorage() {}
+
+			FileBuffer pixelData;
+
+			const unsigned char *Data() const {return &pixelData[0];}
+		};
+
+		void ThrowIfHeaderInvalid(const ddsHeader &header)
+		{
+			//TODO: Implement;
+		}
+
+		//Will either generate this or return the actual one.
+		dds10Header GetDDS10Header(const ddsHeader &header, const FileBuffer &ddsData)
+		{
+			if(header.ddspf.dwFourCC == DDS10_FOUR_CC)
+			{
+				dds10Header header10;
+				size_t offsetToNewHeader = 4 + sizeof(ddsHeader);
+
+				memcpy(&header10, &ddsData[offsetToNewHeader], sizeof(dds10Header));
+
+				return header10;
+			}
+
+			//Compute the header manually. Namely, compute the DXGI_FORMAT for the given
+			//data.
+			dds10Header header10;
+			
+			//Get dimensionality. Assume 2D unless otherwise stated.
+			header10.resourceDimension = DDS_DIMENSION_TEXTURE2D;
+			if((header.dwCaps2 & DDSCAPS2_VOLUME) && (header.dwFlags & DDSD_DEPTH))
+				header10.resourceDimension = DDS_DIMENSION_TEXTURE3D;
+
+			//Get cubemap.
+			DWORD cubemapTest = header.dwCaps2 & DDSCAPS2_CUBEMAP_ALL;
+			if(cubemapTest == 0)
+			{
+				header10.miscFlag = 0;
+			}
+			else
+			{
+				//All faces must be specified or none. Otherwise unsupported.
+				if(cubemapTest != DDSCAPS2_CUBEMAP_ALL)
+					throw DdsFileUnsupportedException(std::string(), "All cubemap faces must be specified.");
+				header10.miscFlag = DDS_RESOURCE_MISC_TEXTURECUBE;
+			}
+
+			//Array size is... zero?
+			header10.arraySize = 0;
+
+			//Use the old-style format.
+			header10.dxgiFormat = DXGI_FORMAT_UNKNOWN;
+
+			return header10;
+		}
+
+		glimg::Dimensions GetDimensions(const ddsHeader &header, const dds10Header &header10)
+		{
+			Dimensions dims;
+			dims.numDimensions = 1;
+			dims.width = header.dwWidth;
+			if(header.dwFlags & DDSD_HEIGHT)
+			{
+				dims.numDimensions = 2;
+				dims.height = header.dwHeight;
+			}
+			if(header.dwFlags & DDSD_DEPTH)
+			{
+				dims.numDimensions = 3;
+				dims.depth = header.dwDepth;
+			}
+
+			return dims;
+		}
+
+		struct OldDdsFmtMatch
+		{
+			DWORD dwFlags;
+			DWORD bitDepth;
+			DWORD rBitmask;
+			DWORD gBitmask;
+			DWORD bBitmask;
+			DWORD aBitmask;
+			DWORD fourCC;
+		};
+
+		struct OldDdsFormatConv
+		{
+			ImageFormat fmt;
+			OldDdsFmtMatch ddsFmt;
+		};
+
+		bool DoesMatchFormat(const OldDdsFmtMatch &ddsFmt, const ddsHeader &header)
+		{
+			if(!(header.ddspf.dwFlags & ddsFmt.dwFlags))
+				return false;
+
+			if(ddsFmt.dwFlags & DDPF_FOURCC)
+			{
+				//None of the bit counts matter. Just check the fourCC
+				if(ddsFmt.fourCC != header.ddspf.dwFourCC)
+					return false;
+			}
+			else
+			{
+				//Check the bitcounts, not the fourCC.
+				if(header.ddspf.dwRGBBitCount != ddsFmt.bitDepth)
+					return false;
+				if(ddsFmt.rBitmask && header.ddspf.dwRBitMask != ddsFmt.rBitmask)
+					return false;
+				if(ddsFmt.gBitmask && header.ddspf.dwGBitMask != ddsFmt.gBitmask)
+					return false;
+				if(ddsFmt.bBitmask && header.ddspf.dwBBitMask != ddsFmt.bBitmask)
+					return false;
+				if(ddsFmt.aBitmask && header.ddspf.dwABitMask != ddsFmt.aBitmask)
+					return false;
+			}
+
+			return true;
+		}
+
+		OldDdsFormatConv g_oldFmtConvert[] =
+		{
+#include "OldDdsFmtConv.inc"
+		};
+
+		ImageFormat GetImageFormat(const ddsHeader &header, const dds10Header &header10)
+		{
+			if(header10.dxgiFormat != DXGI_FORMAT_UNKNOWN)
+			{
+				//TODO: implement.
+				return ImageFormat();
+			}
+
+			for(int convIx = 0; convIx < ARRAY_COUNT(g_oldFmtConvert); convIx++)
+			{
+				if(DoesMatchFormat(g_oldFmtConvert[convIx].ddsFmt, header))
+					return g_oldFmtConvert[convIx].fmt;
+			}
+
+			throw DdsFileUnsupportedException(std::string(), "Could not use the DDS9's image format.");
+		}
+
+		void GetImageCounts(int &numArrays, int &numMipmaps, int &numFaces,
+			const ddsHeader &header, const dds10Header &header10)
+		{
+			if(header.dwFlags & DDSD_MIPMAPCOUNT)
+				numMipmaps = header.dwMipMapCount;
+			else
+				numMipmaps = 1;
+
+			if(header10.miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE)
+				numFaces = 6;
+			else
+				numFaces = 1;
+
+			if(header10.arraySize > 1)
+				numArrays = header10.arraySize;
+			else
+				numArrays = 1;
+		}
+
+		size_t GetByteOffsetToData(const ddsHeader &header)
+		{
+			size_t byteOffset = sizeof(ddsHeader) + 4;
+
+			if(header.ddspf.dwFourCC == DDS10_FOUR_CC)
+			{
+				byteOffset += sizeof(dds10Header);
+			}
+
+			return byteOffset;
+		}
+
+		size_t GetImageByteSize(const ImageFormat &fmt, const glimg::Dimensions &dims,
+			int mipmapLevel);
+
+		//Takes ownership of ddsData;
+		ImageSet *ProcessDDSData(FileBuffer &ddsData, const std::string &filename = std::string())
+		{
+			//Check the first 4 bytes.
+			unsigned int magicTest = 0;
+			memcpy(&magicTest, &ddsData[0], 4);
+			if(magicTest != DDS_MAGIC_NUMBER)
+				throw DdsFileMalformedException(filename, "The Magic number is missing from the file.");
+
+			if(ddsData.size() < sizeof(ddsHeader) + 4)
+				throw DdsFileMalformedException(filename, "The data is way too small to store actual information.");
+
+			//Now, get a DDS header.
+			ddsHeader header;
+			memcpy(&header, &ddsData[4], sizeof(ddsHeader));
+
+			ThrowIfHeaderInvalid(header);
+
+			//Collect info from the DDS file.
+			dds10Header header10 = GetDDS10Header(header, ddsData);
+			glimg::Dimensions dims = GetDimensions(header, header10);
+			ImageFormat fmt = GetImageFormat(header, header10);
+
+			int numMipmaps = 0;
+			int numArrays = 0;
+			int numFaces = 0;
+			GetImageCounts(numArrays, numMipmaps, numFaces, header, header10);
+
+			const size_t baseOffset = GetByteOffsetToData(header);
+
+			std::vector<size_t> imageOffsets;
+			imageOffsets.reserve(numMipmaps * numArrays * numFaces);
+
+			//Temporary.
+			if(numMipmaps != 1 || numArrays != 1 || numFaces != 1)
+				throw DdsFileUnsupportedException(filename, "foo");
+
+			imageOffsets.push_back(baseOffset);
+
+
+			//Build the image creator. No more exceptions, except for those thrown by.
+			//the ImageCreator.
+			DDSStorage *pMemory = new DDSStorage(ddsData);
+
+			ImageCreator imgCreator(pMemory, dims, numArrays, numMipmaps, numFaces, fmt);
+			std::vector<size_t>::const_iterator it = imageOffsets.begin();
+			for(int arrayIx = 0; arrayIx < numArrays; arrayIx++)
+			{
+				for(int faceIx = 0; faceIx < numFaces; faceIx++)
+				{
+					for(int mipmapLevel = 0; mipmapLevel < numMipmaps; mipmapLevel++)
+					{
+						imgCreator.AddImage(pMemory->Data() + *it, arrayIx, mipmapLevel, faceIx);
+						++it;
+					}
+				}
+			}
+			return imgCreator.CreateImage();
+		}
+	}
+
+	ImageSet * loaders::dds::LoadFromFile( const std::string &filename )
+	{
+		//Load the file.
+		FILE *pFile = fopen(filename.c_str(),"rb");
+		if(!pFile)
+			throw DdsFileNotFoundException(filename);
+
+		fseek(pFile, 0, SEEK_END);
+		long int fileSize = ftell(pFile);
+		fseek(pFile, 0, SEEK_SET);
+
+		FileBuffer fileData;
+		fileData.reserve(fileSize);
+		fileData.resize(fileSize);
+
+		fread(&fileData[0], fileSize, 1, pFile);
+		fclose(pFile);
+
+		return ProcessDDSData(fileData, filename);
+	}
+
+	ImageSet * LoadFromMemory( const unsigned char *buffer, size_t bufSize )
+	{
+		FileBuffer fileData(buffer, buffer + bufSize);
+
+		return ProcessDDSData(fileData);
+	}
+}
+}
+}

glimg/source/DdsLoaderInt.h

+
+#ifndef GLIMG_DIRECT_DRAW_SURFACE_INTERNAL_LOADER_H
+#define GLIMG_DIRECT_DRAW_SURFACE_INTERNAL_LOADER_H
+
+
+namespace glimg
+{
+	namespace
+	{
+		typedef unsigned int DWORD;
+
+		enum MagicNumbers
+		{
+			DDS_MAGIC_NUMBER		= 0x20534444,	//"DDS "
+			DDS10_FOUR_CC			= 0x30314458,	//"DX10"
+
+			DDSFOURCC_DXT1			= 0x31545844, //"DXT1"
+			DDSFOURCC_DXT3			= 0x33545844, //"DXT3"
+			DDSFOURCC_DXT5			= 0x35545844, //"DXT5"
+		};
+
+		struct ddsPixelFormat
+		{
+			DWORD			dwSize;
+			DWORD			dwFlags;
+			DWORD			dwFourCC;
+			DWORD			dwRGBBitCount;
+			DWORD			dwRBitMask;
+			DWORD			dwGBitMask;
+			DWORD			dwBBitMask;
+			DWORD			dwABitMask;
+		};
+
+		enum ddsPixelFormatFlags
+		{
+			DDPF_ALPHAPIXELS		= 0x00000001,
+			DDPF_ALPHA				= 0x00000002,
+			DDPF_FOURCC				= 0x00000004,
+			DDPF_RGB				= 0x00000040,
+			DDPF_YUV				= 0x00000200,
+			DDPF_LUMINANCE			= 0x00020000,
+		};
+
+		struct ddsHeader
+		{
+			DWORD			dwSize;
+			DWORD			dwFlags;
+			DWORD			dwHeight;
+			DWORD			dwWidth;
+			DWORD			dwPitchOrLinearSize;
+			DWORD			dwDepth;
+			DWORD			dwMipMapCount;
+			DWORD			dwReserved1[11];
+			ddsPixelFormat	ddspf;
+			DWORD			dwCaps;
+			DWORD			dwCaps2;
+			DWORD			dwCaps3;
+			DWORD			dwCaps4;
+			DWORD			dwReserved2;
+		};
+
+		enum ddsFlags
+		{
+			DDSD_CAPS                   = 0x00000001,
+			DDSD_HEIGHT                 = 0x00000002,
+			DDSD_WIDTH                  = 0x00000004,
+			DDSD_PITCH                  = 0x00000008,
+			DDSD_PIXELFORMAT            = 0x00001000,
+			DDSD_MIPMAPCOUNT            = 0x00020000,
+			DDSD_LINEARSIZE             = 0x00080000,
+			DDSD_DEPTH                  = 0x00800000,
+		};
+
+		enum ddsCaps
+		{
+			DDSCAPS_COMPLEX				= 0x00000008,
+			DDSCAPS_MIPMAP				= 0x00400000,
+			DDSCAPS_TEXTURE				= 0x00001000,
+		};
+
+		enum ddsCaps2
+		{
+			DDSCAPS2_CUBEMAP			= 0x00000200,
+			DDSCAPS2_CUBEMAP_POSITIVEX	= 0x00000400,
+			DDSCAPS2_CUBEMAP_NEGATIVEX	= 0x00000800,
+			DDSCAPS2_CUBEMAP_POSITIVEY	= 0x00001000,
+			DDSCAPS2_CUBEMAP_NEGATIVEY	= 0x00002000,
+			DDSCAPS2_CUBEMAP_POSITIVEZ	= 0x00004000,
+			DDSCAPS2_CUBEMAP_NEGATIVEZ	= 0x00008000,
+			DDSCAPS2_VOLUME				= 0x00200000,
+
+			DDSCAPS2_CUBEMAP_ALL		= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX |
+											DDSCAPS2_CUBEMAP_NEGATIVEX | DDSCAPS2_CUBEMAP_POSITIVEY |
+											DDSCAPS2_CUBEMAP_NEGATIVEY | DDSCAPS2_CUBEMAP_POSITIVEZ |
+											DDSCAPS2_CUBEMAP_NEGATIVEZ,
+		};
+
+		struct dds10Header
+		{
+			DWORD			dxgiFormat;
+			DWORD			resourceDimension;
+			DWORD			miscFlag;
+			DWORD			arraySize;
+			DWORD			reserved;
+		};
+
+		enum dds10ResourceDimensions
+		{
+			DDS_DIMENSION_TEXTURE1D		= 2,
+			DDS_DIMENSION_TEXTURE2D		= 3,
+			DDS_DIMENSION_TEXTURE3D		= 4,
+		};
+
+		enum dds10MiscFlags
+		{
+			DDS_RESOURCE_MISC_TEXTURECUBE	= 0x00000004,
+		};
+
+		enum DXGI_FORMAT
+		{
+			DXGI_FORMAT_UNKNOWN                      = 0,
+			DXGI_FORMAT_R32G32B32A32_TYPELESS        = 1,
+			DXGI_FORMAT_R32G32B32A32_FLOAT           = 2,
+			DXGI_FORMAT_R32G32B32A32_UINT            = 3,
+			DXGI_FORMAT_R32G32B32A32_SINT            = 4,
+			DXGI_FORMAT_R32G32B32_TYPELESS           = 5,
+			DXGI_FORMAT_R32G32B32_FLOAT              = 6,
+			DXGI_FORMAT_R32G32B32_UINT               = 7,
+			DXGI_FORMAT_R32G32B32_SINT               = 8,
+			DXGI_FORMAT_R16G16B16A16_TYPELESS        = 9,
+			DXGI_FORMAT_R16G16B16A16_FLOAT           = 10,
+			DXGI_FORMAT_R16G16B16A16_UNORM           = 11,
+			DXGI_FORMAT_R16G16B16A16_UINT            = 12,
+			DXGI_FORMAT_R16G16B16A16_SNORM           = 13,
+			DXGI_FORMAT_R16G16B16A16_SINT            = 14,
+			DXGI_FORMAT_R32G32_TYPELESS              = 15,
+			DXGI_FORMAT_R32G32_FLOAT                 = 16,
+			DXGI_FORMAT_R32G32_UINT                  = 17,
+			DXGI_FORMAT_R32G32_SINT                  = 18,
+			DXGI_FORMAT_R32G8X24_TYPELESS            = 19,
+			DXGI_FORMAT_D32_FLOAT_S8X24_UINT         = 20,
+			DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS     = 21,
+			DXGI_FORMAT_X32_TYPELESS_G8X24_UINT      = 22,
+			DXGI_FORMAT_R10G10B10A2_TYPELESS         = 23,
+			DXGI_FORMAT_R10G10B10A2_UNORM            = 24,
+			DXGI_FORMAT_R10G10B10A2_UINT             = 25,
+			DXGI_FORMAT_R11G11B10_FLOAT              = 26,
+			DXGI_FORMAT_R8G8B8A8_TYPELESS            = 27,
+			DXGI_FORMAT_R8G8B8A8_UNORM               = 28,
+			DXGI_FORMAT_R8G8B8A8_UNORM_SRGB          = 29,
+			DXGI_FORMAT_R8G8B8A8_UINT                = 30,
+			DXGI_FORMAT_R8G8B8A8_SNORM               = 31,
+			DXGI_FORMAT_R8G8B8A8_SINT                = 32,
+			DXGI_FORMAT_R16G16_TYPELESS              = 33,
+			DXGI_FORMAT_R16G16_FLOAT                 = 34,
+			DXGI_FORMAT_R16G16_UNORM                 = 35,
+			DXGI_FORMAT_R16G16_UINT                  = 36,
+			DXGI_FORMAT_R16G16_SNORM                 = 37,
+			DXGI_FORMAT_R16G16_SINT                  = 38,
+			DXGI_FORMAT_R32_TYPELESS                 = 39,
+			DXGI_FORMAT_D32_FLOAT                    = 40,
+			DXGI_FORMAT_R32_FLOAT                    = 41,
+			DXGI_FORMAT_R32_UINT                     = 42,
+			DXGI_FORMAT_R32_SINT                     = 43,
+			DXGI_FORMAT_R24G8_TYPELESS               = 44,
+			DXGI_FORMAT_D24_UNORM_S8_UINT            = 45,
+			DXGI_FORMAT_R24_UNORM_X8_TYPELESS        = 46,
+			DXGI_FORMAT_X24_TYPELESS_G8_UINT         = 47,
+			DXGI_FORMAT_R8G8_TYPELESS                = 48,
+			DXGI_FORMAT_R8G8_UNORM                   = 49,
+			DXGI_FORMAT_R8G8_UINT                    = 50,
+			DXGI_FORMAT_R8G8_SNORM                   = 51,
+			DXGI_FORMAT_R8G8_SINT                    = 52,
+			DXGI_FORMAT_R16_TYPELESS                 = 53,
+			DXGI_FORMAT_R16_FLOAT                    = 54,
+			DXGI_FORMAT_D16_UNORM                    = 55,
+			DXGI_FORMAT_R16_UNORM                    = 56,
+			DXGI_FORMAT_R16_UINT                     = 57,
+			DXGI_FORMAT_R16_SNORM                    = 58,
+			DXGI_FORMAT_R16_SINT                     = 59,
+			DXGI_FORMAT_R8_TYPELESS                  = 60,
+			DXGI_FORMAT_R8_UNORM                     = 61,
+			DXGI_FORMAT_R8_UINT                      = 62,
+			DXGI_FORMAT_R8_SNORM                     = 63,
+			DXGI_FORMAT_R8_SINT                      = 64,
+			DXGI_FORMAT_A8_UNORM                     = 65,
+			DXGI_FORMAT_R1_UNORM                     = 66,
+			DXGI_FORMAT_R9G9B9E5_SHAREDEXP           = 67,
+			DXGI_FORMAT_R8G8_B8G8_UNORM              = 68,
+			DXGI_FORMAT_G8R8_G8B8_UNORM              = 69,
+			DXGI_FORMAT_BC1_TYPELESS                 = 70,
+			DXGI_FORMAT_BC1_UNORM                    = 71,
+			DXGI_FORMAT_BC1_UNORM_SRGB               = 72,
+			DXGI_FORMAT_BC2_TYPELESS                 = 73,
+			DXGI_FORMAT_BC2_UNORM                    = 74,
+			DXGI_FORMAT_BC2_UNORM_SRGB               = 75,
+			DXGI_FORMAT_BC3_TYPELESS                 = 76,
+			DXGI_FORMAT_BC3_UNORM                    = 77,
+			DXGI_FORMAT_BC3_UNORM_SRGB               = 78,
+			DXGI_FORMAT_BC4_TYPELESS                 = 79,
+			DXGI_FORMAT_BC4_UNORM                    = 80,
+			DXGI_FORMAT_BC4_SNORM                    = 81,
+			DXGI_FORMAT_BC5_TYPELESS                 = 82,
+			DXGI_FORMAT_BC5_UNORM                    = 83,
+			DXGI_FORMAT_BC5_SNORM                    = 84,
+			DXGI_FORMAT_B5G6R5_UNORM                 = 85,
+			DXGI_FORMAT_B5G5R5A1_UNORM               = 86,
+			DXGI_FORMAT_B8G8R8A8_UNORM               = 87,
+			DXGI_FORMAT_B8G8R8X8_UNORM               = 88,
+			DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM   = 89,
+			DXGI_FORMAT_B8G8R8A8_TYPELESS            = 90,
+			DXGI_FORMAT_B8G8R8A8_UNORM_SRGB          = 91,
+			DXGI_FORMAT_B8G8R8X8_TYPELESS            = 92,
+			DXGI_FORMAT_B8G8R8X8_UNORM_SRGB          = 93,
+			DXGI_FORMAT_BC6H_TYPELESS                = 94,
+			DXGI_FORMAT_BC6H_UF16                    = 95,
+			DXGI_FORMAT_BC6H_SF16                    = 96,
+			DXGI_FORMAT_BC7_TYPELESS                 = 97,
+			DXGI_FORMAT_BC7_UNORM                    = 98,
+			DXGI_FORMAT_BC7_UNORM_SRGB               = 99,
+			DXGI_FORMAT_FORCE_UINT                   = 0xffffffffUL 
+		};
+
+	}
+}
+
+
+#endif //GLIMG_DIRECT_DRAW_SURFACE_INTERNAL_LOADER_H	

glimg/source/OldDdsFmtConv.inc

+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGBA, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_RGB | DDPF_ALPHAPIXELS, 32, 0xff, 0xff00, 0xff0000, 0xff000000, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGBX, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_RGB, 32, 0xff, 0xff00, 0xff0000, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGB, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_RGB, 24, 0xff, 0xff00, 0xff0000, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGB, ORDER_BGRA, BD_PER_COMP_8, 1},
+{DDPF_RGB, 24, 0xff0000, 0xff00, 0xff, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGB, ORDER_RGBA, BD_PACKED_16_BIT_565, 1},
+{DDPF_RGB, 16, 0xf800, 0x7e0, 0x1f, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGBA, ORDER_BGRA, BD_PACKED_16_BIT_1555_REV, 1},
+{DDPF_RGB, 16, 0x7c00, 0x3e0, 0x1f, 0x8000, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RGBA, ORDER_BGRA, BD_PACKED_16_BIT_4444_REV, 1},
+{DDPF_RGB, 16, 0xf00, 0xf0, 0xf, 0xf000, 0}},
+
+{{DT_COMPRESSED_BC1, FMT_COLOR_RGB, ORDER_COMPRESSED, BD_COMPRESSED, 1},
+{DDPF_FOURCC, 0, 0, 0, 0, 0, DDSFOURCC_DXT1}},
+
+{{DT_COMPRESSED_BC2, FMT_COLOR_RGBA, ORDER_COMPRESSED, BD_COMPRESSED, 1},
+{DDPF_FOURCC, 0, 0, 0, 0, 0, DDSFOURCC_DXT3}},
+
+{{DT_COMPRESSED_BC3, FMT_COLOR_RGBA, ORDER_COMPRESSED, BD_COMPRESSED, 1},
+{DDPF_FOURCC, 0, 0, 0, 0, 0, DDSFOURCC_DXT5}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RG, ORDER_RGBA, BD_PER_COMP_16, 1},
+{DDPF_RGB, 32, 	0xffff, 0xffff0000, 0, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RG, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_RGB, 16, 	0xffff, 0xffff0000, 0, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RED, ORDER_RGBA, BD_PER_COMP_16, 1},
+{DDPF_LUMINANCE, 16, 0xffff, 0, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RED, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_LUMINANCE, 8, 0xff, 0, 0, 0}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RG, ORDER_RGBA, BD_PER_COMP_16, 1},
+{DDPF_LUMINANCE | DDPF_ALPHAPIXELS, 16, 0xffff, 0, 0, 0xffff0000}},
+
+{{DT_NORM_UNSIGNED_INTEGER, FMT_COLOR_RG, ORDER_RGBA, BD_PER_COMP_8, 1},
+{DDPF_LUMINANCE | DDPF_ALPHAPIXELS, 8, 0xff, 0, 0, 0xff00}},
+

glimg/source/StbLoader.cpp

 			const void *Data() const {return &pixelData[0];}
 		};
 
-
 		ImageSet *BuildImageSetFromIntegerData(const unsigned char *pixelData,
 			int width, int height, int numComp)
 		{

glimg/source/TextureGenerator.cpp

 		OpenGLUploadData ret;
 		ret.type = 0xFFFFFFFF;
 		ret.format = 0xFFFFFFFF;
+		ret.blockByteCount = 0;
 
 		BaseDataType eType = GetDataType(format, forceConvertBits);
 		if(eType >= DT_NUM_UNCOMPRESSED_TYPES)
+		{
+			switch(eType)
+			{
+			case DT_COMPRESSED_BC1:
+			case DT_COMPRESSED_UNSIGNED_BC4:
+			case DT_COMPRESSED_SIGNED_BC4:
+				ret.blockByteCount = 8;
+				break;
+			default:
+				ret.blockByteCount = 16;
+				break;
+			}
 			return ret;
+		}
 
 		ret.type = GetOpenGLType(format, eType, forceConvertBits);
 		ret.format = GetOpenGLFormat(format, eType, forceConvertBits);
 			//Too old to bother checking.
 		}
 
+		GLuint CalcCompressedImageSize(GLuint width, GLuint height, const OpenGLUploadData &upload)
+		{
+			GLuint columnCount = (width + 3) / 4;
+			GLuint rowCount = (height + 3) / 4;
+			return columnCount * upload.blockByteCount * rowCount;
+		}
+
+		void TexImage1D(GLenum texTarget, GLuint mipmap, GLuint internalFormat,
+			GLuint width, const OpenGLUploadData &upload, const void *pPixelData)
+		{
+			if(upload.blockByteCount)
+			{
+				GLuint byteCount = CalcCompressedImageSize(width, 1, upload);
+				glCompressedTexImage1D(texTarget, mipmap, internalFormat, width, 0,
+					byteCount, pPixelData);
+			}
+			else
+			{
+				glTexImage1D(texTarget, mipmap, internalFormat, width, 0,
+					upload.format, upload.type, pPixelData);
+			}
+		}
+
+		void TexImage2D(GLenum texTarget, GLuint mipmap, GLuint internalFormat,
+			GLuint width, GLuint height, const OpenGLUploadData &upload, const void *pPixelData)
+		{
+			if(upload.blockByteCount)
+			{
+				GLuint byteCount = CalcCompressedImageSize(width, height, upload);
+				glCompressedTexImage2D(texTarget, mipmap, internalFormat, width, height, 0,
+					byteCount, pPixelData);
+			}
+			else
+			{
+				glTexImage2D(texTarget, mipmap, internalFormat, width, height, 0,
+					upload.format, upload.type, pPixelData);
+			}
+		}
+
+		void TexImage3D(GLenum texTarget, GLuint mipmap, GLuint internalFormat,
+			GLuint width, GLuint height, GLuint depth, const OpenGLUploadData &upload,
+			const void *pPixelData)
+		{
+			if(upload.blockByteCount)
+			{
+				//compressed array textures are stored as 4x4x1 sheets.
+				GLuint byteCount = CalcCompressedImageSize(width, height, upload) * depth;
+				glCompressedTexImage3D(texTarget, mipmap, internalFormat, width, height, depth, 0,
+					byteCount, pPixelData);
+			}
+			else
+			{
+				glTexImage3D(texTarget, mipmap, internalFormat, width, height, depth, 0,
+					upload.format, upload.type, pPixelData);
+			}
+		}
+
 		void Build1DArrayTexture(unsigned int textureName, const detail::ImageSetImpl *pImage,
 			unsigned int forceConvertBits, GLuint internalFormat, const OpenGLUploadData &upload)
 		{
 				const detail::MipmapLevel &mipData = pImage->GetMipmapLevel(mipmap);
 				Dimensions dims = pImage->GetDimensions(mipmap);
 
-				if(mipData.bFullLayer)
-				{
-					glTexImage1D(GL_TEXTURE_1D, mipmap, internalFormat, dims.width, 0,
-						upload.format, upload.type, mipData.fullPixelData.pPixelData);
-				}
-				else
-				{
-					assert(mipData.individualDataList.size() == 1);
-					glTexImage1D(GL_TEXTURE_1D, mipmap, internalFormat, dims.width, 0,
-						upload.format, upload.type, mipData.individualDataList[0].pPixelData);
-				}
+				const void *pPixelData = mipData.bFullLayer ?
+					mipData.fullPixelData.pPixelData : mipData.individualDataList[0].pPixelData;
+
+				TexImage1D(GL_TEXTURE_1D, mipmap, internalFormat, dims.width,
+					upload, pPixelData);
 			}
 
 			FinalizeTexture(GL_TEXTURE_1D, pImage);
 			{
 				const detail::MipmapLevel &mipData = pImage->GetMipmapLevel(mipmap);
 				Dimensions dims = pImage->GetDimensions(mipmap);
+				const void *pPixelData = mipData.bFullLayer ?
+					mipData.fullPixelData.pPixelData : mipData.individualDataList[0].pPixelData;
 
-				if(mipData.bFullLayer)
-				{
-					glTexImage2D(GL_TEXTURE_2D, mipmap, internalFormat, dims.width, dims.height, 0,
-						upload.format, upload.type, mipData.fullPixelData.pPixelData);
-				}
-				else
-				{
-					assert(mipData.individualDataList.size() == 1);
-					glTexImage2D(GL_TEXTURE_2D, mipmap, internalFormat, dims.width, dims.height, 0,
-						upload.format, upload.type, mipData.individualDataList[0].pPixelData);
-				}
+				TexImage2D(GL_TEXTURE_2D, mipmap, internalFormat, dims.width, dims.height,
+					upload, pPixelData);
 			}
 
 			FinalizeTexture(GL_TEXTURE_2D, pImage);
 			{
 				const detail::MipmapLevel &mipData = pImage->GetMipmapLevel(mipmap);
 				Dimensions dims = pImage->GetDimensions(mipmap);
+				const void *pPixelData = mipData.bFullLayer ?
+					mipData.fullPixelData.pPixelData : mipData.individualDataList[0].pPixelData;
 
-				if(mipData.bFullLayer)
-				{
-					glTexImage3D(GL_TEXTURE_3D, mipmap, internalFormat, dims.width, dims.height, dims.depth, 0,
-						upload.format, upload.type, mipData.fullPixelData.pPixelData);
-				}
-				else
-				{
-					assert(mipData.individualDataList.size() == 1);
-					glTexImage3D(GL_TEXTURE_3D, mipmap, internalFormat, dims.width, dims.height, dims.depth, 0,
-						upload.format, upload.type, mipData.individualDataList[0].pPixelData);
-				}
+				TexImage3D(GL_TEXTURE_2D, mipmap, internalFormat, dims.width, dims.height, dims.depth,
+					upload, pPixelData);
 			}
 
 			FinalizeTexture(GL_TEXTURE_3D, pImage);
 		GLuint textureName = 0;
 		glGenTextures(1, &textureName);
 
-		CreateTexture(textureName, pImage, forceConvertBits);
+		try
+		{
+			CreateTexture(textureName, pImage, forceConvertBits);
+		}
+		catch(...)
+		{
+			glDeleteTextures(1, &textureName);
+			throw;
+		}
 
 		return textureName;
 	}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.