Drawing Letters With Mouse




GLSL Hacker - Drawing Letters With Mouse

Today, a small code sample (in Lua) that shows how to use the mouse to put where you want on the screen a letter with random parameters (position, scaling, orientation and color).

The texture used for the letter is:


GLSL Hacker - letter A texture

<glsl_hacker>
 
<window name="win3d01" title="Drawing Points with Mouse" 
        width="800" height="600" 
        gl_version_major="2" gl_version_minor="1" />
 
<script name="init_scene" run_mode="INIT" >
  <raw_data><![CDATA[	
 
-- Random generator ------------------------------
--
function Random(a, b)
  if (a > b) then
    local c = b
    b = a
    a = c
  end
  local delta = b-a
  return (a + math.random()*delta)
end
 
function RandomInit()
  math.randomseed(os.time())
end
 
 
 
-- Gets the current size of the 3D window -----------------------    
--
winW, winH = gh_window.getsize()
 
 
-- Creates a font to display some debug info -----------------
--  
font_a = gh_utils.font_create("Tahoma", 14)
 
 
-- Orthographic camera --------------------------------------
--
camera_ortho = gh_camera.create_ortho(-winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
gh_camera.set_position(camera_ortho, 0, 0, 4)
 
 
-- Texture GPU program --------------------------------------
--
texture_prog = gh_node.getid("texture_prog")
 
 
-- Quad for drawing the letters -------------------------------
--
quad = gh_mesh.create_quad(64, 64)
 
 
-- Letter texture -------------------------------
--
local abs_path = 0
tex0 = gh_texture.create_from_file("./letter_a.jpg", 0, abs_path)
 
 
-- Array to store all letters/points -------------------------------
--
all_points = {}
num_points = 0
 
 
-- Initialzation of the random numbers generator ---------------------
--
RandomInit()
 
 
-- Misc inits ------------------------------------------
--
gh_renderer.set_vsync(1)
gh_renderer.set_scissor_state(0)
 
last_time = gh_utils.get_elapsed_time()
last_time_mouse = gh_utils.get_elapsed_time()
		]]></raw_data>
</script> 
 
<script name="update_scene" run_mode="FRAME" >
  <raw_data><![CDATA[	
 
elapsed_time = gh_utils.get_elapsed_time()
local dt = elapsed_time - last_time
last_time = elapsed_time
 
 
-- Mouse position converted to 2D space 
-- where the point 0,0 is at the center of the screen.
--    
local mx, my = gh_input.mouse_getpos()
local px = mx - winW/2
local py = winH/2 - my
 
 
-- Generate a new point.
-- mouse_dt prevents from adding several points during a click.
--
local left_button = 1
local right_button = 2
local state = gh_input.mouse_get_button_state(left_button)
local mouse_dt = elapsed_time - last_time_mouse
if ((mouse_dt > 0.25) and (state == 1)) then
  last_time_mouse = elapsed_time
  local point = { _x=px, _y=py, 
                 _sx=Random(0.5, 2.0), _sy=Random(0.5, 2.0), 
                 _roll=Random(-180, 180), 
                 _r=Random(0.2, 1.0), _g=Random(0.2, 1.0), _b=Random(0.2, 1.0), _a=1 }
  num_points = num_points + 1
  all_points[num_points] = point
end
 
 
 
-- Rendering of all points.
--  
gh_camera.bind(camera_ortho)
 
gh_renderer.clear_color_depth_buffers(0.2, 0.3, 0.4, 1.0, 1.0)
gh_renderer.set_depth_test_state(0)
 
gh_renderer.set_blending_state(1)
local BLEND_FACTOR_SRC_ALPHA = 2
local BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 5
gh_renderer.set_blending_factors(BLEND_FACTOR_SRC_ALPHA, BLEND_FACTOR_ONE_MINUS_SRC_ALPHA)
 
gh_texture.bind(tex0, 0)
gh_gpu_program.bind(texture_prog)
gh_gpu_program.uniform1i(texture_prog, "tex0", 0)
 
for i=1, num_points do
  local p = all_points[i]
  gh_gpu_program.uniform4f(texture_prog, "color", p._r, p._g, p._b, 1)
  gh_object.set_euler_angles(quad, 0, 0, p._roll)
  gh_object.set_scale(quad, p._sx, p._sy, 1)
  gh_object.set_position(quad, p._x, p._y, 0)
  gh_object.render(quad)
end
 
gh_renderer.set_blending_state(0)
 
 
-- Debug info.
--
gh_utils.font_render(font_a, 10, 20, 0.8, 0.8, 0.0, 1.0, string.format("# points: %d", num_points))
 
  ]]></raw_data>
</script> 
 
 
<script name="resize_scene" run_mode="SIZE" >
  <raw_data><![CDATA[	
 
winW, winH = gh_window.getsize(0)
 
gh_camera.update_ortho(camera_ortho, -winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
 
gh_utils.font_set_viewport_info(font_a, 0, 0, winW, winH)
 
  ]]></raw_data>
</script> 
 
<gpu_program name="texture_prog" >
  <raw_data_vs><![CDATA[	 
#version 120
void main()
{	
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
  gl_TexCoord[0] = gl_MultiTexCoord0;
}
  ]]></raw_data_vs>
  <raw_data_ps><![CDATA[	 
#version 120
uniform sampler2D tex0;
uniform vec4 color;
void main(void)
{
  vec2 uv = gl_TexCoord[0].xy;
  uv.y *= -1.;
  vec4 c = texture2D(tex0, uv);
  gl_FragColor = c.rgbr * color;
}  
  ]]></raw_data_ps>
</gpu_program>
 
</glsl_hacker>

This demo will be available in the next update of the code sample pack.