0
\$\begingroup\$

I'm currently trying to build a game with Ogre3D that is basically a moving vehicle that leaves a green trail (2D manual mesh) in it's path, what i'm trying to achieve is exactly what this image shows: enter image description here

My problem is that i need to change, by some method/technique, the color of the intersected path where the two meshes overlap (red area). I've been searching around the Ogre forum and found this thread http://www.ogre3d.org/forums/viewtopic.php?f=2&t=47674, I've replicated that solution in my code but now on the screen i only see the intersected path. I'm a total newbie in stencil buffers and in Ogre generally, so I'm still not sure if this is the best approach to solve my problem. should I try another method rather than applying a stencil buffer? vertex/fragment shader code that could help?

Any advice or direction that you could provide will be very appreciated. Thanks a lot

***** UPDATE *****

According to JasonPh's answers i've managed to start adding some code:

1) Create manual texture

Ogre::TextureManager* tmgr = Ogre::TextureManager::getSingletonPtr();
gkString mMapTextureName = "pathTexture";
if (!tmgr->resourceExists(mMapTextureName)) {
    Ogre::TexturePtr ptr = tmgr->createManual(mMapTextureName,
                           Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                           Ogre::TEX_TYPE_2D,
                           480,  // Width
                           640,    // Height
                           1, // Depth
                           0,
                           Ogre::PF_A8R8G8B8,
                           Ogre::TU_RENDERTARGET);

    ptr->createInternalResources();
    ptr->load();

    Ogre::RenderTexture* pathTexture = ptr->getBuffer()->getRenderTarget();
    gkEngine* engine = gkEngine::getSingletonPtr();
    Ogre::Camera* camera = engine->getActiveScene()->getMainCamera()->getCamera();
    pathTexture->addViewport(camera);
    pathTexture->getViewport(0)->setClearEveryFrame(true);
    pathTexture->getViewport(0)->setBackgroundColour(Ogre::ColourValue::Black);
    pathTexture->getViewport(0)->setOverlaysEnabled(false);
    pathTexture->setAutoUpdated(true);
}

2) Create material from scratch and use the previously created texture. This material is then assigned to my "path" entity.

Ogre::MaterialManager* mmgr = Ogre::MaterialManager::getSingletonPtr();
mMaterialName = uniqueMaterialName("pathMaterial");
mMaterial = mmgr->create(mMaterialName, "General");

Ogre::Technique* tec = mMaterial->getTechnique(0);
tec->setSchemeName("ShaderGeneratorDefaultScheme");
Ogre::Pass* pass = tec->getPass(0);
pass->setVertexProgram("pathMaterial/vs", false);
pass->setFragmentProgram("pathMaterial/fs", false);
pass->setCullingMode(Ogre::CULL_NONE);
pass->setColourWriteEnabled(true);
pass->setLightingEnabled(true);
Ogre::TextureUnitState* tus = pass->createTextureUnitState();
tus->setTextureFiltering(Ogre::TFO_NONE);
tus->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP, Ogre::TextureUnitState::TAM_CLAMP, Ogre::TextureUnitState::TAM_CLAMP);
tus->setTexture(tmgr->getByName(mMapTextureName));

mMaterial->prepare();
mMaterial->load();

3) Fragment shader code

uniform sampler2D pathTexture; 

void main() 
{ 
   vec4 color = texture2D(pathTexture, gl_TexCoord[0].xy); =  
   if(color == vec4(0.0, 1.0, 0.0, 1) //green
       gl_FragColor = vec4(1.0, 0.0, 0.0, 1) //red
   else
       gl_FragColor = vec4(0.0, 1.0, 0.0, 1) //green       
}

This still needs some fixes to work, so new questions have emerged:

1) Do I realy need to render "pathTexture" on screen to this to work? Maybe that texture could only be used to decide pixel colors an then discard it?

2) To only use "pathTexture" as an "input" for my shader, should I add a second pass on my material file with "pathTexture" as a texture unit?

Thanks!

\$\endgroup\$
0
\$\begingroup\$

First you will want to render your path to a separate texture(let's call it "pathTexure"), and when you create it you will fill it with white. When you render a pixel that is part of the path, you will check if the pixel is green, if it is you will set that pixel to red, else set it to green. Finally, you add the "pathTexure" onto whatever you are drawing on the scene(cars, backgrounds, etc.).

\$\endgroup\$
  • \$\begingroup\$ Thanks for your answer, how exactly can I implement this step: "...you will check if the pixel is green...", fragment shader? \$\endgroup\$ – EzeEst Nov 1 '16 at 19:58
  • \$\begingroup\$ Yes you can do it using the fragment shader. You can sample the texture at the current texture coordinate. \$\endgroup\$ – JasonPh Nov 1 '16 at 20:49
  • \$\begingroup\$ Ok, let's see if I'm getting this right: 1- Render the actual path into a texture (pathTexture). 2- When rendering a new path (white) check (in fragment shader) against pathTexture if the pixel to be rendered is already green, then decide with that info. Is this right?. Thanks again. \$\endgroup\$ – EzeEst Nov 2 '16 at 17:39
  • \$\begingroup\$ Yes, and at the end add the pathTexture with whatever you are drawing on the scene. \$\endgroup\$ – JasonPh Nov 2 '16 at 18:20
  • \$\begingroup\$ Added some code to my post \$\endgroup\$ – EzeEst Nov 7 '16 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.