Draw highlited 2d region on golf field

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
QProgrammer
Posts: 11
Joined: Sat Jun 14, 2014 12:06 pm

Draw highlited 2d region on golf field

Post by QProgrammer »

Hello

Im working on a simulation program which contains a flat golf field.

I used a Box shape for ground with a green grass texture.

I want to high lite some areas on this box. for example a 2d circle around Pole or golf ball.
Take a look at these two screen-shots and you will understand what im looking for :

Image

Image

Thats exactly what im looking for,checkout the Circle and Square shapes in first screen shot.

Whats the correct way (or possible solutions) to achieve that?

Thanks for your help :wink:
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Draw highlited 2d region on golf field

Post by hendu »

Many options:

1. Additional box per highlight with a transparent texture
2. With your grass shader
3. ????
QProgrammer
Posts: 11
Joined: Sat Jun 14, 2014 12:06 pm

Re: Draw highlited 2d region on golf field

Post by QProgrammer »

Hi
Thanks for your answer. i thought shader should be the right approach.

Can anyone give me a hint how to start doing it?
I know what shaders are and how they work in general, what i dont know is how to program this kind of shader and
how can i pass position of overlay texture that i want to show?

i really appreciate if some one can help me to move in the right direction.
Is there any similar example or resource i can study to see how it works? (Not a reference of learning shaders in general)

thanks
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Draw highlited 2d region on golf field

Post by smso »

The following code fragments maybe helpful:

Code: Select all

using namespace irr;
 
core::array<video::S3DVertex> Vertices;
core::array<u16> Indices;
 
void setupPixmapQuad()
{
    Vertices.set_used(4);
 
    //S3DVertex => pos, normal, color, texcoords
    video::SColor color(128, 255, 255, 255);
    Vertices[0] = video::S3DVertex(-1.f, 0.f, -1.f,  0.f, 1.f, 0.f,  color,  0.f, 1.f);
    Vertices[1] = video::S3DVertex(-1.f, 0.f,  1.f,  0.f, 1.f, 0.f,  color,  0.f, 0.f);
    Vertices[2] = video::S3DVertex( 1.f, 0.f,  1.f,  0.f, 1.f, 0.f,  color,  1.f, 0.f);
    Vertices[3] = video::S3DVertex( 1.f, 0.f, -1.f,  0.f, 1.f, 0.f,  color,  1.f, 1.f);
    
    Indices.set_used(6);
    
    Indices[0] = 0;
    Indices[1] = 1;
    Indices[2] = 2;
    Indices[3] = 2;
    Indices[4] = 3;
    Indices[5] = 0;
    
}
 
void drawPixmap(IrrlichtDevice* device, const core::vector3df& pos, video::ITexture* tex, f32 scale)
{
    scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera();
    if (!camera)
        return;
 
    ////////////////////////////////////////////////////////////////////////////
    core::matrix4 m1;
    
    camera->updateAbsolutePosition();
    core::vector3df target = camera->getTarget() - camera->getAbsolutePosition();
    target.Y = 0.0f;
 
    if (!core::iszero(target.getLengthSQ()))
    {
        target.normalize();
        core::vector3df zdir(0.0f, 0.0f, 1.0f);
    
        core::quaternion q;
        q.rotationFromTo(zdir, target);
    
        core::vector3df eulerRadians;
        q.toEuler(eulerRadians);
    
        m1.setRotationRadians(eulerRadians);
    }
 
    ////////////////////////////////////////////////////////////////////////////
    core::matrix4 m2;
    
    //core::vector3df pos = node->getPos();
    core::vector3df p = pos;
    f32 YOffset = 0.05f;
    p.Y += YOffset;
 
    m2.setTranslation(p);
    m2.setScale(scale);
    
    
    ////////////////////////////////////////////////////////////////////////////
    video::IVideoDriver* driver = device->getVideoDriver();
    driver->setTransform(video::ETS_WORLD, m2*m1);
 
    video::SMaterial PixmapMaterial;
    PixmapMaterial.Lighting = false;
    PixmapMaterial.BackfaceCulling = false;
    PixmapMaterial.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
    
    if (tex)
        PixmapMaterial.setTexture(0, tex);
    driver->setMaterial(PixmapMaterial);
    
    driver->drawIndexedTriangleList
    (
        Vertices.const_pointer(), 4,
        Indices.const_pointer(), 2
    );
    
    driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
    
}
Ripped from
navinode_view.cpp and navinode_view.h
of:
http://irrlicht.sourceforge.net/forum/v ... =9&t=46437

Regards,
smso
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Draw highlited 2d region on golf field

Post by hendu »

Generating texcoords is a bit involved for someone with no shader experience. As long as your highlight can be computed parametrically (a uniform circle, for example), you can just pass the center+radius of each highlight, and if the current pixel is inside that radius, make it white etc.
QProgrammer
Posts: 11
Joined: Sat Jun 14, 2014 12:06 pm

Re: Draw highlited 2d region on golf field

Post by QProgrammer »

Hello

Thank you so much smso . That code is really helpful.
I will try to utilize that in my code.

hendu ,
your approach sound interesting and easy. But what i need to know is how to pass those parameters to Shader?

for example i want to draw a circle at point X,Y with radios R on one side of my BOX node.
How should i convert these coordinates to something that shader can understand?

I know i can access textcoords in shader, but how to find my desire coords (position of circle) and how to pass it to shader, that i need to know.
CuteAlien
Admin
Posts: 9930
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Draw highlited 2d region on golf field

Post by CuteAlien »

The thing with shaders is... that once you start with them this is one of the easiest tasks. Because the hard part will be getting a working shader that does all the lighting correct as well. Once you're done with that you'll be good enough to figure out a circle on the floor. Not saying you shouldn't use shaders - if you want to do that study the shader tutorial. It explains how to do stuff like pass variables to shaders (you do that in OnSetConstants of a class derived from IShaderConstantSetCallBack and you pass that callback-class to the shader when creating it).

As long as you have a flat floor I would simply model the circle. The put it on floor-height (+ a small epsilon value to prevent z-buffer troubles, but not too much or it starts to float). Then you can put animations on it. So put different animations in that model for different states. The only tricky part then is how to handle the borders of your field. If borders are higher the highlight will just vanish below the border which might be fine. Otherwise you will probably have to put some manual work in the order of rendering of scenenodes. Like rendering first the floor. Then rendering that circle object with z-buffer settings ignored (so it's drawn on top). And last render the players and stuff that should show up above those circles (you can work with 2-3 different scenemanager for that for example).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
QProgrammer
Posts: 11
Joined: Sat Jun 14, 2014 12:06 pm

Re: Draw highlited 2d region on golf field

Post by QProgrammer »

Hello

Thank you a lot for your answer. I appreciate that.
In fact I really like to use shaders for this to learn more about shaders so i can utilize them in my future projects as well.

I reviewed Irrlicht shader tutorial throughly and examined many GLES tutorials to have a better understanding.

So far i have few questions and doubts that i am not sure about.

1- Imagine i can show a circle on my box shape with shader. When i want to move this circle to another position, do i need to recreate shader again? (to pass new parameters to shader)


Understanding this one is making me crazy :

2- as far as i know , to manipulate texture pixels, i need to have UV coords of texture in that certain position.

Now, take a look at attached picture.

>I have my box and its position and dimension.
>I want to show my circle on this box at a specified position(X = distance from left side of the box and Y = distance from top of the box)

My question is, HOW can i convert that X,Y to textcoords so i can send them to shader as parameters and use them inside shader?
(is that what i should do, right? or maybe im wrong?)

i cant figure out this part, hope someone can help me to understand how it works.

Image

kind regards
gerdb
Posts: 194
Joined: Wed Dec 02, 2009 8:21 pm
Location: Dresden, Germany

Re: Draw highlited 2d region on golf field

Post by gerdb »

So, a rect has a width 'w' and a height 'h'

w = x_max - x_min = delta_x
h = y_max - y_min = delta_y

x in range [ x_min, x_max ] has proportional u (texcoord) in range [ 0, 1 ]
y in range [ y_min, y_max ] has proportional v (texcoord) in range [ 1, 0 ]

( word that is important to understand: its the type of connection between both scales )
( more simple: the higher x, the higher u; the higher y, the lower v )

so the (linear) transforms from x/y to u/v are:

u = (x - x_min) / ( x_max - x_min ) = (x - x_min) / w
v = 1 - (y - y_min) / ( y_max - y_min ) = 1 - (y - y_min) / h

for the other transforms just solve the equations for x and y

x = u * w + x_min
y = (1-v) * h + y_min
Post Reply