Okay, so some time has passed since I found a solution to my problems, unfortunately, not online, so I hope this helps anyone who has similar problems.
When creating any texture, you should always make texels of size 2^n * 2^m
, where m and n are the width and height of the texture. This was my first mistake, although I did not understand it at that time.
I did not notice this because my main texture atlas was based on this principle and had a texture of 1024 x 1024. What I did not take into account was the size of the texture that I created as a texture index. Since my map was 10 x 10, I created a 10 x 10 texture for indexes, I assume that it is somehow stretched (not sure how it works in the backend) is 16 x 16 or 8 x 8, mixing texels together, how did he do it.
The first thing that prompted me was that I scaled my canvas in Photoshop and found that the mixed colors that he created were the same as those that I received at the output of ogre3d.
Anyway, move on.
As soon as I realized this, I was able to create a texture in Ogre and transfer it as follows
//Create index material Ogre::TexturePtr indexTexture = Ogre::TextureManager::getSingleton().createManual("indexTexture","General",Ogre::TextureType::TEX_TYPE_2D, 16, 16, 0, Ogre::PixelFormat::PF_BYTE_BGRA, Ogre::TU_DEFAULT); Ogre::HardwarePixelBufferSharedPtr pixelBuffer = indexTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); Ogre::uint8 counter = 0; for (size_t j = 0; j < 16; j++) { for(size_t i = 0; i < 16; i++) { if(i==8 || i==7) { *pDest++ = 3; // B *pDest++ = 0; // G *pDest++ = 0; // R *pDest++ = 0; // A } else { *pDest++ = 1; // B *pDest++ = 0; // G *pDest++ = 0; // R *pDest++ = 0; // A } counter++; } } pixelBuffer->unlock();
So now I have a texture that I can use as an index with some values ββthat I added for testing, these values ββwill eventually be filled at runtime by clicking on the fragment.
Now, in order to convey this texture, I had to transfer it to the correct technique and transfer it to my material, this was done as follows:
Ogre::MaterialPtr material = Ogre::MaterialPtr(Ogre::MaterialManager::getSingleton().getByName("PlainTexture")); float mapSize = 16; float tas = 2; material->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("mapSize",mapSize); material->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("tas",tas); material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("indexTexture");
It also skips two values: mapSize is the size of the map itself in tiles (assuming its square), and t is the size of the texture atlas (the number of different squares of the texture across the width of the atlas).
In order for my material to understand that I just went through, I had to slightly modify my material file as follows:
// CG Pixel shader definition fragment_program PlainTexture_PS cg { source GameObjStandard.cg entry_point main_plain_texture_fp profiles arbfp1 default_params { param_named tas float param_named } }
And my pass was also redefined.
pass { // Make this pass use the vertex shader defined above vertex_program_ref PlainTexture_VS { } // Make this pass use the pixel shader defined above fragment_program_ref PlainTexture_PS { } texture_unit 0 { filtering none } texture_unit 1 { texture textureatlas.png 2d tex_address_mode clamp filtering anisotropic } }
Then I rewrote the cg fragment fragment program to take into account the changes I made.
void main_plain_texture_fp( float2 uv0 : TEXCOORD0, // UV interpolated for current pixel out float4 color : COLOR, // Output color we want to write uniform float tas, uniform float mapSize, // Model Level Inputs uniform sampler2D Tex0: TEXUNIT0, uniform sampler2D Tex1: TEXUNIT1) { //get the index position by truncating the uv coordinates float2 flooredIndexes = floor(uv0); //get the colour of the index texture Tex0 at this floored coordinate float4 indexColour = tex2D(Tex0, ((1.0/mapSize) * flooredIndexes)+(0.5/mapSize)); //calculate the uv offset required for texture atlas range = 0 - 255 float indexValue = (255 * indexColour.b) + (255 * indexColour.g) + (255 * indexColour.r); //float indexValue = (tas * tas) - indexValue0; if(indexValue < tas*tas) { float row = floor(indexValue/tas); float col = frac(indexValue/tas) * tas; float uvFraction = 1.0/tas; float uBase = col * uvFraction; float vBase = 1 - ((tas - row) * uvFraction); float uOffset = frac(uv0.x)/tas; float vOffset = (frac(uv0.y))/tas; float uNew = uBase + uOffset; float vNew = vBase + vOffset; float2 uvNew = {uNew, vNew}; if(frac(uv0.x) > 0.99 || frac(uv0.x) < 0.01) { float4 color1 = {1,1,1,0}; color = (0.2*color1) + (0.8*tex2D(Tex1,uvNew)); } else if(frac(uv0.y) > 0.99 || frac(uv0.y) < 0.01) { float4 color1 = {1,1,1,0}; color = (0.2*color1) + (0.8*tex2D(Tex1,uvNew)); } else { color = tex2D(Tex1,uvNew); } } else { float4 color2 = {0.0,0,0,0}; color = color2; } }
This calculates the correct texel needed from the texture satin, it also overlaps the weak grid on top, combining 80% texel color and 20% white.
If the texture atlas does not have a color index indicated by the index texture, then it simply displays black (this is basically the case that it is very easy to notice.
The following is an example output using a 2 x 2 texture atlas.