Skip to content

How to manually draw stuff on a texture

rptr edited this page May 19, 2019 · 3 revisions

How to manually draw stuff on a texture/image?

There is a Urho3D::Image class whose pixel data can be directly accessed and manipulated: http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_image.html

Create a new image and give it the size 1024x1024 and four color channels (RGBA).

    Urho3D::SharedPtr<Urho3D::Image> image=new Urho3D::Image(context);
    image->SetSize(1024,1024,4);
    
    // one can use this SetPixel function with the color type
    SetPixel(0,0,Color(1.0,0.5,0.5,0.75));  
    // or one can use this function which is faster
    SetPixelInt(0,0,0xFF8080C0);
    // or one can directly access the data which is the fastest way:
    // get a pointer to the data. Each pixel with the four channels 
    // (each channel is one byte) can be seen as a 32bit number.
    uint32_t* data=(uint32_t*)_image->GetData();
    // The data size is width * height * channel count.
    // Here 1024*1024*4=4194304 bytes.

    // A pointer to the end:
    uint32_t* data_end=data+image->width()*image->height();  

Since data is a pointer to a 4 byte "structure" it is automatically incremented in full 4 byte steps. data++; would increment it by 4 and data+=width*height; is actually incrementing it by width*height*4 bytes.

for(;data<data_end;++)   // iterate through the whole image
    *data=0xFF8080C0;    // Fill it with a color.

You could use the same approach to manually draw something on it (like a line, text or a gradient).

Use the Image

The image can be converted to a 2D texture: http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_texture2_d.html

Urho3D::SharedPtr<Urho3D::Texture2D> texture=new Urho3D::Texture2D(_context);

If you want to display it on the screen without scaling it, it is better to turn of filtering and only use one mip map level:

texture->SetFilterMode(Urho3D::TextureFilterMode::FILTER_NEAREST);
texture->SetNumLevels(1);

Set the size and type of the texture:

texture->SetSize(width(),height(),Urho3D::Graphics::GetRGBAFormat(),Urho3D::TEXTURE_STATIC);

To fill the texture with data we have two options:

// Give it the image to get the data from.
texture->SetData(image);                            
// Or give it the image data directly (this is faster):
texture->SetData(0,0,0,1024,1024,image->GetData()); 

This Texture2D could be set to a material to use it in the 3D world: http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_material.html#a740b3f6f56769cb6e2414aedead579b4

Or you can make a sprite to display it on the screen:

    Urho3D::SharedPtr<Urho3D::Sprite> sprite=GetSubsystem<Urho3D::UI>()
        ->GetRoot()->CreateChild<Urho3D::Sprite>();
    sprite->SetTexture(texture);
    sprite->SetSize(1024,1024);
    
    // it will use a binary alpha mask if the mode is not set to blend_alpha.
    sprite->SetBlendMode(Urho3D::BlendMode::BLEND_ALPHA);

See the samples or http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_sprite.html for more details.