21 #include "CaelumPrecompiled.h" 22 #include "CaelumExceptions.h" 23 #include "InternalUtilities.h" 24 #include "PrivatePtr.h" 29 float fx,
float fy, Ogre::Image *img,
bool wrapX)
32 int imgWidth =
static_cast<int>(img->getWidth ());
33 int imgHeight =
static_cast<int>(img->getHeight ());
36 int py = Ogre::Math::IFloor(Ogre::Math::Abs (fy) * (imgHeight - 1));
38 py = std::max(0, std::min(py, imgHeight - 1));
42 float px = fx * (img->getWidth () - 1);
44 px1 = Ogre::Math::IFloor(px);
45 px2 = Ogre::Math::ICeil(px);
50 px1 = (px1 % imgWidth + imgWidth) % imgWidth;
51 px2 = (px2 % imgWidth + imgWidth) % imgWidth;
53 px1 = std::max(0, std::min(px1, imgWidth - 1));
54 px2 = std::max(0, std::min(px2, imgWidth - 1));
58 Ogre::ColourValue c1, c2, cf;
59 c1 = img->getColourAt (px1, py, 0);
60 c2 = img->getColourAt (px2, py, 0);
64 float diff = px - px1;
65 cf = c1 * (1 - diff) + c2 * diff;
72 std::stringstream stream;
73 stream.width(2 *
sizeof(
void *));
75 stream.unsetf(std::ios::dec);
76 stream.setf(std::ios::hex);
77 stream.setf(std::ios::uppercase);
78 stream << reinterpret_cast<ptrdiff_t>(pointer);
83 const Ogre::String& originalName,
84 const Ogre::String& cloneName)
86 Ogre::MaterialPtr scriptMaterial = Ogre::MaterialManager::getSingletonPtr()->getByName(originalName);
87 if (scriptMaterial.isNull()) {
88 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
89 "Can't find material \"" + originalName +
"\"",
97 clonedMaterial->load ();
98 if (clonedMaterial->getBestTechnique () == 0) {
99 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
100 "Can't load material \"" + originalName +
"\": " + clonedMaterial->getUnsupportedTechniquesExplanation(),
104 return clonedMaterial.release();
109 Ogre::CompositorPtr comp = Ogre::CompositorManager::getSingletonPtr()->getByName(name);
111 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
112 "Can't find compositor \"" + name +
"\"",
118 if (comp->getNumSupportedTechniques () == 0) {
119 CAELUM_THROW_UNSUPPORTED_EXCEPTION (
120 "Can't load compositor \"" + name +
"\"",
130 if (Ogre::MeshManager::getSingleton ().resourceExists (name)) {
134 Ogre::LogManager::getSingleton ().logMessage (
135 "Caelum: Creating " + name +
" sphere mesh resource...");
138 Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton ().createManual (name,
RESOURCE_GROUP_NAME);
140 Ogre::SubMesh *sub = msh->createSubMesh ();
143 Ogre::VertexData *vertexData =
new Ogre::VertexData ();
144 msh->sharedVertexData = vertexData;
147 Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;
148 size_t currOffset = 0;
150 vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
151 currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
153 vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
154 currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
156 vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
157 currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT2);
162 vertexData->vertexCount = segments * (segments - 1) + 2;
164 case DT_IMAGE_STARFIELD:
165 vertexData->vertexCount = (segments + 1) * (segments + 1);
168 Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton ().createVertexBuffer (vertexDecl->getVertexSize (0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
169 Ogre::VertexBufferBinding *binding = vertexData->vertexBufferBinding;
170 binding->setBinding (0, vBuf);
172 float *pVertex =
static_cast<float *
>(vBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));
177 sub->indexData->indexCount = 2 * segments * (segments - 1) * 3;
179 case DT_IMAGE_STARFIELD:
180 sub->indexData->indexCount = 2 * (segments - 1) * segments * 3;
183 sub->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton ().createIndexBuffer (Ogre::HardwareIndexBuffer::IT_16BIT, sub->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
184 Ogre::HardwareIndexBufferSharedPtr iBuf = sub->indexData->indexBuffer;
185 unsigned short *pIndices =
static_cast<unsigned short *
>(iBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));
190 fillGradientsDomeBuffers (pVertex, pIndices, segments);
192 case DT_IMAGE_STARFIELD:
193 fillStarfieldDomeBuffers (pVertex, pIndices, segments);
204 sub->useSharedVertices =
true;
205 msh->_setBounds (Ogre::AxisAlignedBox (-1, -1, -1, 1, 1, 1),
false);
206 msh->_setBoundingSphereRadius (1);
209 Ogre::LogManager::getSingleton ().logMessage (
210 "Caelum: generateSphericDome DONE");
213 void InternalUtilities::fillGradientsDomeBuffers (
float *pVertex,
unsigned short *pIndices,
int segments)
215 const float deltaLatitude = Ogre::Math::PI / (float )segments;
216 const float deltaLongitude = Ogre::Math::PI * 2.0 / (float )segments;
219 for (
int i = 1; i < segments; i++) {
220 float r0 = Ogre::Math::Sin (Ogre::Radian (i * deltaLatitude));
221 float y0 = Ogre::Math::Cos (Ogre::Radian (i * deltaLatitude));
223 for (
int j = 0; j < segments; j++) {
224 float x0 = r0 * Ogre::Math::Sin (Ogre::Radian (j * deltaLongitude));
225 float z0 = r0 * Ogre::Math::Cos (Ogre::Radian (j * deltaLongitude));
261 for (
int i = 0; i < segments - 2; i++) {
262 for (
int j = 0; j < segments; j++) {
263 *pIndices++ = segments * i + j;
264 *pIndices++ = segments * i + (j + 1) % segments;
265 *pIndices++ = segments * (i + 1) + (j + 1) % segments;
266 *pIndices++ = segments * i + j;
267 *pIndices++ = segments * (i + 1) + (j + 1) % segments;
268 *pIndices++ = segments * (i + 1) + j;
273 for (
int i = 0; i < segments; i++) {
274 *pIndices++ = segments * (segments - 1);
275 *pIndices++ = (i + 1) % segments;
280 for (
int i = 0; i < segments; i++) {
281 *pIndices++ = segments * (segments - 1) + 1;
282 *pIndices++ = segments * (segments - 2) + i;
283 *pIndices++ = segments * (segments - 2) + (i + 1) % segments;
287 void InternalUtilities::fillStarfieldDomeBuffers (
float *pVertex,
unsigned short *pIndices,
int segments)
289 const float deltaLatitude = Ogre::Math::PI / (float )segments;
290 const float deltaLongitude = Ogre::Math::PI * 2.0 / (float )segments;
293 for (
int i = 0; i <= segments; i++) {
294 float r0 = Ogre::Math::Sin (Ogre::Radian (i * deltaLatitude));
295 float y0 = Ogre::Math::Cos (Ogre::Radian (i * deltaLatitude));
297 for (
int j = 0; j <= segments; j++) {
298 float x0 = r0 * Ogre::Math::Sin (Ogre::Radian (j * deltaLongitude));
299 float z0 = r0 * Ogre::Math::Cos (Ogre::Radian (j * deltaLongitude));
309 *pVertex++ = (float )j / (
float )segments;
310 *pVertex++ = 1 - (y0 * 0.5 + 0.5);
315 int vRowSize = segments + 1;
316 for (
int i = 1; i < segments; i++) {
317 for (
int j = 0; j < segments; j++) {
318 int baseIdx = vRowSize * i + j;
319 *pIndices++ = baseIdx;
320 *pIndices++ = baseIdx + 1;
321 *pIndices++ = baseIdx + vRowSize + 1;
322 *pIndices++ = baseIdx + 1;
323 *pIndices++ = baseIdx;
324 *pIndices++ = baseIdx - vRowSize;
static const Ogre::String pointerToString(void *pointer)
Quickly format a pointer as a string; in hex.
static Ogre::MaterialPtr checkLoadMaterialClone(const Ogre::String &originalName, const Ogre::String &cloneName)
Creates a private clone of a material from a script.
static void generateSphericDome(const Ogre::String &name, int segments, DomeType domeType)
Creates a longitude-latitude sky dome.
DomeType
Enumeration of types of sky domes.
static Ogre::ColourValue getInterpolatedColour(float fx, float fy, Ogre::Image *img, bool wrapX=true)
Gets the interpolated colour between two pixels from an image.
static const String RESOURCE_GROUP_NAME
Resource group name for caelum resources.
static Ogre::CompositorPtr checkCompositorSupported(const Ogre::String &name)
Fetch a compositor by name and check it can be loaded properly.