Search code examples
c++backgroundrgbogre3dogre

access viewport pixel values in ogre


I'm working on ogre project by using C++. Normally I use viewport:setbackground() but this cause whole window same colour. This time I want to load different R, G, B values for each viewport's pixel. My window is 600*600 and I have to load RGB values for each pixel. How can I solve this question ?


Solution

  • If you want to set a background you can do this:

    Create a rectangle that fill all viewport

    Rectangle2D* rect = new Rectangle2D(true);
    rect->setCorners(-1.0, 1.0, 1.0, -1.0);
    rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
    rect->setBoundingBox(AxisAlignedBox(-100000.0 * Vector3::UNIT_SCALE, 100000.0 * Vector3::UNIT_SCALE));
    SceneNode * node = sceneManager->createChildSceneNode("Background");
    node->attachObject(rect);
    

    Create a material and texture

    TexturePtr texture = TextureManager::getSingleton().createManual("BackgroundTex", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 600, 600, 0, PF_R8G8B8, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
    MaterialPtr material = MaterialManager::getSingleton().create("BackgroundMat", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Technique* technique = material->createTechnique();
    technique->createPass();
    technique->getPass(0)->setLightingEnabled(false);
    technique->getPass(0)->createTextureUnitState("BackgroundTex");
    rect->setMaterial("BackgroundMat");
    

    Now you can copy your RGB data directly to texture framebuffer:

    texture->getBuffer()->blitFromMemory(PixelBox(600, 600, 1, PF_R8G8B8, (void*) data));
    

    EDIT 2011-11-10

    data must be a valid pointer to a framebuffer of raw RGB. You can initialize it:

    unsigned char* data = new unsigned char[600 * 600 * 3];
    

    And than write yellow directly to pixel at position x,y.

    unsigned char* red = &data[(x + y * width) * 3];
    unsigned char* blue = &data[(x + y * width) * 3 + 1];
    unsigned char* green = &data[(x + y * width) * 3 + 2];
    *red = 255;
    *blue = 0;
    *green = 255;
    

    Or write directly to texture->getBuffer() (Ogre API: HardwarePixelBuffer)

    unsigned char* data = (unsigned char*)texture->getBuffer()->lock();
    

    ... write directly to pixelbuffer ...

    texture->getBuffer()->unlock();
    

    This example can be generalized for other width, length, format etc... You can use more optimized code to find pixel inside the buffer, this is just an example.