View Full Version : Billboards - placing text on the screen.

11-20-2012, 11:04 AM
Ok, so this is going to be a bit long but I have been pulling my hair out over this for weeks. I am trying to place text on the screen using 1 quad (2xtris) for each letter and then referencing a texture map for the character. I have billboarding working as far as the text always facing the camera but I cannot seem to get it to always draw in a particular part of the screen. My camera view looks both up/down and side to side. I have it so that it will draw in the same place when I move the camera front and back and side to side or when I rotate it on the Y axis but for some reason I can't nail down how to keep the text locked into the screen when I look "up and down." I can manipulate the code such that Y axis rotations work OR x-z axes work but not both simultaneously. Code is in Euphoria but similar enough to C that it should be understandable:

Camera Code:
xpos, ypos and zpos are just floats updated by keyboard.
lookupdown = incline up or down rotation (x/z axis)
heading = azimuth (y axis)

xCamera = { -xpos, -ypos, -zpos, heading, lookupdown, {}, 0, 0}

tmat2 = get_rotation_matrix(2, heading)
tmat1 = get_rotation_matrix(1, lookupdown)
tmat1 = get_mult_matrix(tmat1, tmat2)
tmat2 = get_translate_matrix(xCamera[1], xCamera[2], xCamera[3])

xCamera[6] = get_mult_matrix(tmat1, tmat2) -- native eu sequence with matrix

xCamera[7] = seq_to_matrixf(xCamera[6]) -- converts to and returns a C array with matrix------
String rendering code:

tmat1 = convert_sphere_to_cartesian(11, -lookupdown, -heading) -- radius, -incline, -heading

kxpos = tmat1[1]
kypos = tmat1[2]
kzpos = tmat1[3]

tmat2 = get_rotation_matrix(2, -heading)
tmat1 = get_rotation_matrix(1, -lookupdown)
tmat1 = get_mult_matrix(tmat2, tmat1)

matrix1 = get_translate_matrix(-xCamera[1]+kxpos , -xCamera[2]-kypos , -xCamera[3]-kzpos )
matrix1 = get_mult_matrix(matrix1, tmat1)

fmat = seq_to_matrixf(matrix1)

gl_uniformMatrix4fv(glprogs[2][3][1], 1, GL_FALSE, fmat) -- push model matrix
gl_uniformMatrix4fv(glprogs[2][3][2], 1, GL_FALSE, xCamera[7] ) -- push billboard view matrix
gl_uniformMatrix4fv(glprogs[2][3][3], 1, GL_FALSE, PerspectiveMatrixArray ) -- push perspective matrix------
convert_sphere_to_cartesian function:

global function convert_sphere_to_cartesian(atom radius, atom incl, atom azim) <-- atoms are just float variables

sequence xyz

xyz = {0, 0, 0}

incl *= (2 * 0.0087266) -- convert to radians
azim *= (2 * 0.0087266)

xyz[1] = (radius * sin(azim)) * cos(incl)
xyz[2] = (radius * sin(azim)) * sin(incl)
xyz[3] = radius * cos(azim)

return xyz

end function------

#version 130 // Prog1: Standard tile/object shaders
attribute vec3 v_coord;
attribute vec2 t_coord;
varying vec2 f_texcoord;
uniform mat4 m_perspective;
uniform mat4 m_transform;
uniform mat4 v_transform;

void main(void) {
vec3 xcoord;

xcoord = v_coord * vec3(-1, 1, 1);

gl_Position = m_perspective * v_transform * m_transform * vec4(xcoord.xyz, 1.0);

f_texcoord = t_coord;

#version 130 // Prog1: Standard tile/object shaders
varying vec2 f_texcoord; // with masking on bright white
uniform sampler2D vtexture;
uniform int shadow_flag; // holds shading value

void main(void) {
vec4 scol;
vec4 tmp;
float sc;

sc = .1 * shadow_flag;

scol = texture(vtexture, f_texcoord);
if (scol.x <= .15 && scol.y <= .15 && scol.z <= .15) // near-black colors are masked out
scol = texture(vtexture, f_texcoord) * vec4(sc, sc, sc, 0.0);
scol = texture(vtexture, f_texcoord) * vec4(sc, sc, sc, 1.0);

gl_FragColor = scol;


I just want the text in the above image to stay in the viewport regardless of the direction the camera is facing.

Thanks in advance for any help and let me know if I need to supply more code.

Steve A.

carsten neumann
11-20-2012, 03:20 PM
It is probably easiest to switch to an orthographic projection and use that to draw the text on top of your scene (with depth testing disabled), just make sure you render it after everything else.

11-21-2012, 07:35 AM
It is probably easiest to switch to an orthographic projection and use that to draw the text on top of your scene (with depth testing disabled), just make sure you render it after everything else.

Thanks for the info Carsten. Does anyone know of a good place on how to do that using modern opengl? I have been poking around all morning and it seems like everything is using fixed function or a bit vague.

Disregard, I have it figured out.