Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Icon drawing in 3d

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2011
    Posts
    18

    Icon drawing in 3d

    Hi

    I'm drawing some 2d icons in 3d game using billboarding(they should always face the camera). They purpose is to sign specific places in the scene.
    How can I keep icon(image ) sizes small and correct looking while drawing in 3d perspective projection? Is there any known relation between original icon size in pixels and the size to to be given in 3d metric space?

    Thanks

  2. #2
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,261

    Re: Icon drawing in 3d

    try:
    Code :
    You have:
    vec3 IconPos; // where the icon is
    mat4 mvp; // model-view-projection matrix
    float invWidth = 1.0/640; 
    float invHeight= 1.0/480;
    int iconSize=32; // if you want to see it always 32x32px big
    //-----------------
    vec4 clip = mvp * vec4(IconPos,1.0);
    float dx = iconSize * invWidth * 0.5 * clip.w;
    float dy = iconSize * invHeight * 0.5 * clip.w;
     
     
    vec4 vout[4];
    vout[0] = vec4(clip.x - dx, clip.y + dy, clip.z,clip.w);
    vout[1] = vec4(clip.x - dx, clip.y - dy, clip.z,clip.w);
    vout[2] = vec4(clip.x + dx, clip.y - dy, clip.z,clip.w);
    vout[3] = vec4(clip.x + dx, clip.y + dy, clip.z,clip.w);
     
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
     
    glBegin(GL_QUADS);
    	glTexCoord2f(0,0);	glVertex4fv(&vout[0].x);
    	glTexCoord2f(0,1);	glVertex4fv(&vout[1].x);
    	glTexCoord2f(1,1);	glVertex4fv(&vout[2].x);
    	glTexCoord2f(1,0);	glVertex4fv(&vout[3].x);
    glEnd();

  3. #3
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Icon drawing in 3d

    @llian,
    I tried the code you posted and it works very, very well.

    How did you ever figure out that:
    Code :
    vout[0] = vec4(clip.x - dx, clip.y + dy, clip.z,clip.w);
    vout[1] = vec4(clip.x - dx, clip.y - dy, clip.z,clip.w);
    vout[2] = vec4(clip.x + dx, clip.y - dy, clip.z,clip.w);
    vout[3] = vec4(clip.x + dx, clip.y + dy, clip.z,clip.w);
    would ever work?

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,732

    Re: Icon drawing in 3d

    I'm guessing he employed math All he's doing is computing positions that will effectively reverse the perspective projection, thus keeping it at the correct size.

  5. #5
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,261

    Re: Icon drawing in 3d

    I figured the 4 vertices should have the same z and w, and backtraced how to "unproject" xy.

  6. #6
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Icon drawing in 3d

    I can see you were unprojecting the icon position into clip space, but the next step you took was a stroke of genius in my opinion as it's not immediately obvious to me that the key to this technique is dx * clip.w to 'perspectively' correct the icon size.

    float dx = iconSize * invWidth * 0.5 * clip.w;
    float dy = iconSize * invHeight * 0.5 * clip.w;

    I suppose if you figure that the next step in the FF pipeline is to perform a perspective divide with a computed clip-space w (just as you did), then it all makes sense as you have just reversed the projection.

    Anyway, well done!

  7. #7
    Junior Member Newbie
    Join Date
    Jul 2011
    Posts
    18

    Re: Icon drawing in 3d

    Yes, MANY THANKS to Ilian. Sorry for late update. It solved my problem and seems like I'll use this approach a lot.

  8. #8
    Junior Member Newbie
    Join Date
    Jul 2011
    Posts
    18

    Re: Icon drawing in 3d

    Hi
    Sorry for bringing it up again.
    But now I copied the code to another project where my metric space is relatively large[-2500,2500] and when I do rendering it doesnt work anymore. I can't see the icons anymore.
    It looks like clip vector values are the problem.

    Please take a look at my code:

    Code :
     
    GLfloat matProj[16];
    GLfloat matModelProj[16];
    float InvWidth = 1.0/winWidth;
    float InvHeight= 1.0/winHeight;
    float vClip[4],vPos[4] = {icon.x,icon.y,icon.fz,1.0f};
     
    glBindTexture(GL_TEXTURE_2D, icon.TexID);
    glEnable(GL_TEXTURE_2D);				 
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	 
    glEnable(GL_BLEND);
     
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glPushMatrix();
     
     
     glGetFloatv(GL_PROJECTION_MATRIX, matProj);
     glMultMatrixf(matProj);
     glGetFloatv(GL_MODELVIEW_MATRIX,matModelProj);
     
     //multiply modelview-proj matrix with position
     Matrix4MultiplyByVector(matModelProj,vPos,vClip);  
     float dx = (float)icon.SizeX * (float)winWidth *0.5f * vClip[3];
     float dy = (float)icon.SizeY * (float)winHeight *0.5f * vClip[3];
     
     float vScr1[4] = {vClip[0] - dx, vClip[1] + dy, vClip[2],vClip[3]};
     float vScr2[4] = {vClip[0] - dx, vClip[1] - dy, vClip[2],vClip[3]};
     float vScr3[4] = {vClip[0] + dx, vClip[1] - dy, vClip[2],vClip[3]};
     float vScr4[4] = {vClip[0] + dx, vClip[1] + dy, vClip[2],vClip[3]};
     
     
     glPopMatrix();
     glBegin(GL_QUADS);
            glTexCoord2f(0,0);	glVertex4fv(vScr1);
    	glTexCoord2f(0,1);	glVertex4fv(vScr2);
    	glTexCoord2f(1,1);	glVertex4fv(vScr3);
    	glTexCoord2f(1,0);	glVertex4fv(vScr4);
     glEnd();
     
     glDisable(GL_BLEND);
     glDisable(GL_TEXTURE_2D);

    Thanks


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •