I'm creating a simple fallout1-like multiplayer game using Ogre 1.9.0. Several topics I've created on this forum last week was all about it
But now I get something very strange. This is how I see my game when playing it with my friend:
My config: Win7, D3D9, debug build
My friend's config: Win10, D3D9, release build
And he has this nightmare:
I can't test my app on his machine because we are living in defferent cities and he doesn't even have the debugger
So, the list of problems:
1) He isn't able to see the whole map texture
2) Instead of lightmap that is responsible for field of view he has random shadowed/illuminated zones
3) Very strange way of how the models are moving. It is not his problem, it just appears it release mode. To understand what it means I've made two short movies:
1. How it should be (debug mode)
[youtube]A5CcUzHiHxM[/youtube]
2. How it is in the release mode
[youtube]acTKF9W2DxI[/youtube]
So, the robot moves... actually, I don't know how it's in english, but, maybe, jerkily or spasmodically? Google translate says so
For moving the robot I use technique described in Intermediate Tutorial 1
How you can mention there also is a problem with FOV, but I think that this problem is somewhere inside my code that has no contacts with the Ogre (although I can't get it: how one and the same code may be working another way in release mode I don't have any "#ifdef _DEBUG"-like stuff in it).
What I'm doing and (I think) what is the reason of these bugs:
For lightmapping I take the "rockwall.tga" texture from Ogre standart texture pack, clone it 25 times so I get a big manual texture. Then I create another big texture of the same size and make it white and grey on light and dark cells, respectively, then make a manual material. I took this method from manual (that topic is about it)
I think it is the reason because in the old version of my game (where was no lightmapping and creating manual textures) there are no such terrible bugs.
This is how I create the big map texture:
Code: Select all
Ogre::TexturePtr sourceTexture = Ogre::TextureManager::getSingleton().load("rockwall.tga", "General");
// Create the texture
const int sourceWidth = sourceTexture->getWidth(),
sourceHeight = sourceTexture->getHeight();
const int N = 5; // NxN texture grid
auto m_GroundTexture = Ogre::TextureManager::getSingleton().createManual(
"GroundTexture", // name
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, // type
sourceWidth*N, // width
sourceHeight*N, // height
0, // number of mipmaps
sourceTexture->getFormat(), // pixel format
Ogre::TU_DEFAULT);
// Get the pixel buffer
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = m_GroundTexture->getBuffer(),
sourcePixelBuffer = sourceTexture->getBuffer();
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
sourcePixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
const Ogre::PixelBox& rockBox = sourcePixelBuffer->getCurrentLock();
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
Ogre::uint8* pSource = static_cast<Ogre::uint8*>(rockBox.data);
// copying the first N texture instances
for (int j = 0; j < sourceHeight; ++j) {
for (int k = 0; k < N; ++k) {
memcpy(pDest, pSource, sourceWidth*4);
pDest += sourceWidth*4;
}
pSource += sourceWidth*4;
}
// then copy leftover (N-1)*N instances from already copied N
for (int k = 1; k < N; ++k) {
memcpy(pDest, pixelBox.data, sourceWidth*sourceHeight*4*N);
pDest += sourceWidth*sourceHeight*4*N;
}
// Unlock the pixel buffer
pixelBuffer->unlock();
sourcePixelBuffer->unlock();
sourceTexture->unload();
Code: Select all
auto m_LightmapTexture = Ogre::TextureManager::getSingleton().createManual(
"LightmapTexture",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D,
sourceWidth*N, sourceHeight*N,
0,
Ogre::PF_A8R8G8B8,
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
m_pLightmapTexture = m_LightmapTexture.getPointer();
pixelBuffer = m_LightmapTexture->getBuffer();
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
const Ogre::PixelBox& pixelBoxL = pixelBuffer->getCurrentLock();
pDest = static_cast<Ogre::uint8*>(pixelBoxL.data);
const int lightmapWidth = m_LightmapTexture->getWidth(),
lightmapHeight = m_LightmapTexture->getHeight();
// shomehow the pixel format is B8G8R8X8, although I've been asking for A8R8G8B8
// COLOUR_SHADOW_VALUE == 127
for (int i = 0; i < lightmapWidth * lightmapHeight; ++i) {
*pDest++ = COLOUR_SHADOW_VALUE; //blue
*pDest++ = COLOUR_SHADOW_VALUE; //green
*pDest++ = COLOUR_SHADOW_VALUE; //red
++pDest;
}
pixelBuffer->unlock();
Code: Select all
auto mapMaterial = Ogre::MaterialManager::getSingleton().create(
"GroundMaterial", // name
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mapMaterial->getTechnique(0)->getPass(0)->createTextureUnitState();
mapMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(m_GroundTexture);
mapMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setColourOperation(Ogre::LBO_MODULATE);
mapMaterial->getTechnique(0)->createPass();
mapMaterial->getTechnique(0)->getPass(1)->setSceneBlending(Ogre::SBT_MODULATE);
mapMaterial->getTechnique(0)->getPass(1)->createTextureUnitState();
mapMaterial->getTechnique(0)->getPass(1)->getTextureUnitState(0)->setTexture(m_LightmapTexture);
mapMaterial->getTechnique(0)->getPass(1)->getTextureUnitState(0)->setColourOperation(Ogre::LBO_MODULATE);
m_GroundMaterialHandle = mapMaterial->getHandle(); // for future access
Code: Select all
FieldOfView lm = *m_pGameMap->getCurFOV(); // 2d int array, positive value means that the cell is visible now
FieldOfView& lm_old = *m_pRenderedFOV; // current rendered FOV
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = m_pLightmapTexture->getBuffer();
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
const Ogre::PixelBox& pixelBoxL = pixelBuffer->getCurrentLock();
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBoxL.data);
const int W = m_pGameMap->getWidth(), H = m_pGameMap->getHeight();
const int Width = m_pLightmapTexture->getWidth(),
Height = m_pLightmapTexture->getHeight(),
Width_1 = m_pLightmapTexture->getWidth()/float(W) + 0.5f, //width of one cell
Height_1 = m_pLightmapTexture->getHeight()/float(H) + 0.5f; //height of one cell
// Width and height of texture are divisible by W and H
int y_render, x_render;
for (int x = 0; x < W; ++x)
for (int y = 0; y < H; ++y) {
if ((lm(x, y) > 0) && lm_old(x, y) <= 0) { // if the cell was not visible and is now
y_render = H - y; // some black magic, never mind, that's not a point now, I'm stuck with the textures, not with the incorrect FOV
x_render = W - x;
pDest = static_cast<Ogre::uint8*>(pixelBoxL.data) +
(Width * Height_1 * (y_render - 1) + Width_1 * (x_render - 1))*4;
for (int j = 0; j < Height_1; ++j) {
memcpy(pDest, m_LightLine, Width_1*4); //m_LightLine is an array with the values of 255
pDest += Width*4;
}
} else if ((lm(x, y) <= 0) && lm_old(x, y) > 0) { // if the cell is now invisible and was visible
y_render = H - y;
x_render = W - x;
pDest = static_cast<Ogre::uint8*>(pixelBoxL.data) +
(Width * Height_1 * (y_render - 1) + Width_1 * (x_render - 1))*4;
for (int j = 0; j < Height_1; ++j) {
memcpy(pDest, m_DarkLine, Width_1*4); //m_DarkLine is an array with the values of 127
pDest += Width*4;
}
} // else the cell visibility remains unchanged and there is no need to change the illumination
}
pixelBuffer->unlock();
lm_old = std::move( lm );
Thanks for your attention, I would be very grateful for any help!