2 * Horde3D file format converter
4 * Copyright (C) 2009 Mathias Gottschlag
6 * This file is part of OpenStranded
8 * OpenStranded is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * OpenStranded is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with OpenStranded. If not, see <http://www.gnu.org/licenses/>.
22 #include "eal/horde3d/converter.hh"
26 #include <FreeImage.h>
31 static void writeMipmap(std::ofstream
&file
, int level
, FIBITMAP
*image
)
33 int width
= FreeImage_GetWidth(image
);
34 for (int i
= 0; i
< level
; i
++)
37 FIBITMAP
*mipmap
= FreeImage_Rescale(image
, width
, width
, FILTER_BILINEAR
);
38 // Convert bitmap data
39 if (width
< 4) width
= 4;
40 squish::u8
*targetdata
= new squish::u8
[width
* width
/ 2];
41 squish::u8
*currentblock
= targetdata
;
42 for (int y
= 0; y
< width
; y
+= 4)
44 for (int x
= 0; x
< width
; x
+= 4)
46 squish::u8 source
[16 * 4];
47 for (int i
= 0; i
< 16; i
++)
50 FreeImage_GetPixelColor(mipmap
, width
- (x
+ (i
% 4)) - 1, width
- (y
+ i
/ 4) - 1, &color
);
51 ((unsigned int*)source
)[i
] = *(unsigned int*)&color
;
53 squish::Compress(source
, currentblock
, squish::kDxt1
);
58 file
.write((const char*)targetdata
, width
* width
/ 2);
61 FreeImage_Unload(mipmap
);
63 Horde3DConverter::Horde3DConverter(std::string basedir
)
65 this->basedir
= basedir
;
67 FreeImage_Initialise(false);
69 Horde3DConverter::~Horde3DConverter()
74 Horde3DConverter::convertSkybox(std::string name
)
76 // Check whether file already exists
77 std::ifstream
testfile((basedir
+ "/extra/horde3d/models/skies/" + name
+ ".scene.xml").c_str());
82 printf("Source: %s\n", (basedir
+ "/skies/" + name
+ "_dn.jpg").c_str());
83 FIBITMAP
*dn
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_dn.jpg").c_str());
84 if (!dn
) return false;
85 FIBITMAP
*up
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_up.jpg").c_str());
86 FIBITMAP
*bk
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_bk.jpg").c_str());
87 FIBITMAP
*fr
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_fr.jpg").c_str());
88 FIBITMAP
*lf
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_lf.jpg").c_str());
89 FIBITMAP
*rt
= FreeImage_Load(FIF_JPEG
, (basedir
+ "/skies/" + name
+ "_rt.jpg").c_str());
90 // Create output image
91 int width
= FreeImage_GetWidth(dn
);
92 int height
= FreeImage_GetHeight(dn
);
93 printf("Sky: %d/%d\n", width
, height
);
95 std::ofstream ddsfile
;
96 ddsfile
.open((basedir
+ "/extra/horde3d/models/skies/" + name
+ ".dds").c_str(), std::ofstream::binary
);
97 const char *magic
= "DDS ";
98 ddsfile
.write(magic
, 4);
100 ddsfile
.write((const char*)&size
, 4);
102 ddsfile
.write((const char*)&flags
, 4);
103 ddsfile
.write((const char*)&height
, 4);
104 ddsfile
.write((const char*)&width
, 4);
105 size
= width
* height
/ 2;
106 ddsfile
.write((const char*)&size
, 4);
108 ddsfile
.write((const char*)&depth
, 4);
110 int mipmapsize
= width
;
111 while (mipmapsize
> 0)
116 ddsfile
.write((const char*)&mipmaps
, 4);
117 int reserved
[11] = {0};
118 ddsfile
.write((const char*)&reserved
, 44);
121 ddsfile
.write((const char*)&size
, 4);
123 ddsfile
.write((const char*)&flags
, 4);
125 ddsfile
.write(magic
, 4);
126 ddsfile
.write((const char*)&reserved
, 20);
128 int caps
= 0x00401008;
129 ddsfile
.write((const char*)&caps
, 4);
131 ddsfile
.write((const char*)&caps
, 4);
132 ddsfile
.write((const char*)&reserved
, 8);
133 ddsfile
.write((const char*)&reserved
, 4);
135 FIBITMAP
*rt2
= FreeImage_ConvertTo32Bits(rt
);
136 for (int i
= 0; i
< mipmaps
; i
++)
138 writeMipmap(ddsfile
, i
, rt2
);
140 FIBITMAP
*lf2
= FreeImage_ConvertTo32Bits(lf
);
141 for (int i
= 0; i
< mipmaps
; i
++)
143 writeMipmap(ddsfile
, i
, lf2
);
145 FIBITMAP
*up2
= FreeImage_RotateClassic(up
, 270);
146 FreeImage_Unload(up
);
148 up2
= FreeImage_ConvertTo32Bits(up
);
149 for (int i
= 0; i
< mipmaps
; i
++)
151 writeMipmap(ddsfile
, i
, up2
);
153 FIBITMAP
*dn2
= FreeImage_ConvertTo32Bits(dn
);
154 for (int i
= 0; i
< mipmaps
; i
++)
156 writeMipmap(ddsfile
, i
, dn2
);
158 FIBITMAP
*fr2
= FreeImage_ConvertTo32Bits(fr
);
159 for (int i
= 0; i
< mipmaps
; i
++)
161 writeMipmap(ddsfile
, i
, fr2
);
163 FIBITMAP
*bk2
= FreeImage_ConvertTo32Bits(bk
);
164 for (int i
= 0; i
< mipmaps
; i
++)
166 writeMipmap(ddsfile
, i
, bk2
);
170 FreeImage_Unload(dn2
);
171 FreeImage_Unload(up2
);
172 FreeImage_Unload(bk2
);
173 FreeImage_Unload(fr2
);
174 FreeImage_Unload(lf2
);
175 FreeImage_Unload(rt2
);
176 FreeImage_Unload(dn
);
177 FreeImage_Unload(up
);
178 FreeImage_Unload(bk
);
179 FreeImage_Unload(fr
);
180 FreeImage_Unload(lf
);
181 FreeImage_Unload(rt
);
182 // Create material file
183 std::ofstream
material((basedir
+ "/extra/horde3d/models/skies/" + name
+ ".material.xml").c_str());
184 material
<< "<Material>\n";
185 material
<< "\t<Shader source=\"shaders/skybox.shader\"/>\n";
186 material
<< "\t<Sampler name=\"albedoMap\" map=\"models/skies/" << name
<< ".dds\" />\n";
187 material
<< "</Material>\n";
190 std::ofstream
model((basedir
+ "/extra/horde3d/models/skies/" + name
+ ".scene.xml").c_str());
191 model
<< "<Model name=\"skybox_" << name
<< "\" geometry=\"models/skybox/skybox.geo\">\n";
192 model
<< "\t<Mesh name=\"Box01\" material=\"models/skies/" << name
<< ".material.xml\" tx=\"0\""
193 " ty=\"0\" tz=\"-1\" rx=\"-90\" ry=\"0\" rz=\"-180\" sx=\"2\" sy=\"2\" sz=\"2\""
194 " batchStart=\"0\" batchCount=\"36\" vertRStart=\"0\" vertREnd=\"23\" />\n";
195 model
<< "</Model>\n";