1 | // tCubemap.h  |
2 | //  |
3 | // A cubemap is simply a collection of 6 tTextures. By convention each tTexture has layers of the same pixel format. A  |
4 | // tCubemap may be created from a dds file (assuming the dds file contains a cubemap) or from multiple tTextures. When  |
5 | // construction from a dds is performed, it chooses a different image to load into the tTexture for each cubemap side.  |
6 | // When constructing from tTextures directly it is the user's responsibility to supply the necessary tTextures in the  |
7 | // correct format before constructing a tCubemap. tCubemaps can also save and load themselves into a tChunk-based  |
8 | // format. They do this by looping through their tTextures and calling their individual Save/Load functions.  |
9 | //  |
10 | // ATI has a tool called CubeMapGen 1.1 which is useful for making your own cube map dds files. Its installer also  |
11 | // installs some example dds cube maps to play with. The CubeMapGen tool (as of v1.1) does NOT generate valid DXT1  |
12 | // compressed cubemap files. The header is incorrect and the data is not compressed.  |
13 | //  |
14 | // nVidia's DDS tools can also generate dds cubemaps straight from photoshop. Just pull down the combo-box that usually  |
15 | // says "2D TEXTURE" and there'll be an option for cubemaps. The nVidia dds plugin for photoshop does not have this  |
16 | // issues with texture compression and cubemaps.  |
17 | //  |
18 | // The order of the images for a cubemap are +x -x +y -y +z -z. In the CubeMapGen tool the option for OpenGL and DX  |
19 | // coord systems only affects the export of cube map faces -- it does not, apparently, affect the output dds cubemap.  |
20 | // i.e. It seems the faces should always be specified using a LH coord system. The OpenGL calls for specifying a  |
21 | // cubemap are also left handed which is inconsistent with other parts of the OpenGL API.  |
22 | //  |
23 | // Copyright (c) 2006, 2017 Tristan Grimmer.  |
24 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
25 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
26 | //  |
27 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
29 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
30 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
31 | // PERFORMANCE OF THIS SOFTWARE.  |
32 |   |
33 | #pragma once  |
34 | #include <System/tChunk.h>  |
35 | #include "Image/tTexture.h"  |
36 | namespace tImage  |
37 | {  |
38 |   |
39 |   |
40 | class tCubemap : public tLink<tCubemap>  |
41 | {  |
42 | public:  |
43 | // Creates an empty and initially invalid tCubemap. You must manually call Set or Load.  |
44 | tCubemap() { }  |
45 |   |
46 | // Construct from a ddsfile. The dds file must contain a cubemap or the object will be left invalid.  |
47 | tCubemap(const tString& ddsFile) { Load(ddsFile); }  |
48 |   |
49 | // Construct from 6 non-dds image files directly. You do not need them all to be valid. tCubemap supports having one  |
50 | // to six sides. Use LH coord system. See tTexture for the last 6 processing arguments.  |
51 | tCubemap  |
52 | (  |
53 | const tString& imageFilePosX, const tString& imageFileNegX,  |
54 | const tString& imageFilePosY, const tString& imageFileNegY,  |
55 | const tString& imageFilePosZ, const tString& imageFileNegZ,  |
56 | bool generateMipMaps, tPixelFormat pixelFormat = tPixelFormat::Auto,  |
57 | tTexture::tQuality quality = tTexture::tQuality::Production,  |
58 | int forceWidth = 0, int forceHeight = 0  |
59 | ) { Load(imageFilePosX, imageFileNegX, imageFilePosY, imageFileNegY, imageFilePosZ, imageFileNegZ, generateMipMaps, pixelFormat, quality, forceWidth,forceHeight); }  |
60 |   |
61 | // Constructs from an in-memory tImageDDS object. The passed in object will be invalid afterwards.  |
62 | tCubemap(tImageDDS& ddsObj) { Set(ddsObj); }  |
63 |   |
64 | // Constructs from 6 in-memory tPicture objects. The passed in objects will be invalid afterwards. You do not need  |
65 | // them all to be valid. tCubemap supports having one to six sides. Use LH coord system. See tTexture for the last  |
66 | // 6 processing arguments.  |
67 | tCubemap  |
68 | (  |
69 | tPicture& imagePosX, tPicture& imageNegX,  |
70 | tPicture& imagePosY, tPicture& imageNegY,  |
71 | tPicture& imagePosZ, tPicture& imageNegZ,  |
72 | bool generateMipMaps, tPixelFormat pixelFormat = tPixelFormat::Auto,  |
73 | tTexture::tQuality quality = tTexture::tQuality::Production,  |
74 | int forceWidth = 0, int forceHeight = 0  |
75 | ) { Set(imagePosX, imageNegX, imagePosY, imageNegY, imagePosZ, imageNegZ, generateMipMaps, pixelFormat, quality, forceWidth,forceHeight); }  |
76 | virtual ~tCubemap() { Clear(); }  |
77 |   |
78 | // At least one side must be valid for the cubemap to be valid.  |
79 | bool IsValid() const;  |
80 | void Clear();  |
81 | bool AllSidesOpaque() const;  |
82 |   |
83 | // The load and set calls all return success. If the input is non const, it invalidates the passed in object.  |
84 | bool Load(const tString& ddsFile, bool reverseRowOrder = true);  |
85 | bool Load  |
86 | (  |
87 | const tString& imageFilePosX, const tString& imageFileNegX,  |
88 | const tString& imageFilePosY, const tString& imageFileNegY,  |
89 | const tString& imageFilePosZ, const tString& imageFileNegZ,  |
90 | bool generateMipMaps, tPixelFormat = tPixelFormat::Auto,  |
91 | tTexture::tQuality = tTexture::tQuality::Production,  |
92 | int forceWidth = 0, int forceHeight = 0  |
93 | );  |
94 | bool Set(tImageDDS&);  |
95 | bool Set  |
96 | (  |
97 | tPicture& imagePosX, tPicture& imageNegX,  |
98 | tPicture& imagePosY, tPicture& imageNegY,  |
99 | tPicture& imagePosZ, tPicture& imageNegZ,  |
100 | bool generateMipMaps, tPixelFormat = tPixelFormat::Auto,  |
101 | tTexture::tQuality = tTexture::tQuality::Production,  |
102 | int forceWidth = 0, int forceHeight = 0  |
103 | );  |
104 |   |
105 | enum class tSide  |
106 | {  |
107 | Invalid = -1,  |
108 | PosX, Right = PosX,  |
109 | NegX, Left = NegX,  |
110 | PosY, Top = PosY,  |
111 | NegY, Bottom = NegY,  |
112 | PosZ, Front = PosZ,  |
113 | NegZ, Back = NegZ,  |
114 | NumSides  |
115 | };  |
116 | tTexture* GetSide(tSide);  |
117 |   |
118 | // Save and Load to tChunk format.  |
119 | void Save(tChunkWriter&) const;  |
120 | void Load(const tChunk&);  |
121 |   |
122 | // Cubemaps are considered equal if all their individual tTextures represent the same cubemap side and all the  |
123 | // tTextures are equal. Invalid cubemaps are not equal to anything, including other invalids.  |
124 | bool operator==(const tCubemap&) const;  |
125 | bool operator!=(const tCubemap& src) const { return !(*this == src); }  |
126 |   |
127 | private:  |
128 |   |
129 | struct SideTex  |
130 | {  |
131 | SideTex() : Side(tSide::Invalid), Texture() { }  |
132 | tSide Side;  |
133 | tTexture Texture;  |
134 | };  |
135 |   |
136 | // Not all sides are required to be valid.  |
137 | SideTex Sides[int(tSide::NumSides)];  |
138 | };  |
139 |   |
140 |   |
141 | }  |
142 | |