Operations that involve displaying 2d graphics such as text, shapes, images on to the screen.
2D Graphics
Examples
Filter
Operations that involve displaying 2d graphics such as text, shapes, images on to the screen.
// main draw loop
gl.clear_color(0.1, 0.0, 0.2, 1.0)
gl.clear(.color_buffer_bit)
state.draw_quad()
state.draw_tri()
fn create_shader(vert_src, frag_src string) u32 {
// vertex shader
vert := gl.create_shader(.vertex_shader)
gl.shader_source(vert, vert_src)
gl.compile_shader(vert)
if gl.get_shader_compile_status(vert) == 0 {
log := gl.get_shader_info_log(vert)
println('shader $vert compilation failed')
println(log)
exit(1)
}
// fragment shader
frag := gl.create_shader(.fragment_shader)
gl.shader_source(frag, frag_src)
gl.compile_shader(frag)
if gl.get_shader_compile_status(frag) == 0 {
log := gl.get_shader_info_log(frag)
println('fragment $frag shader compilation failed')
println(log)
exit(1)
}
// link shaders
shader_program := gl.create_program()
gl.attach_shader(shader_program, vert)
gl.attach_shader(shader_program, frag)
gl.link_program(shader_program)
// check for linking errors
success := gl.get_program_link_status(shader_program)
if success == 0 {
log := gl.get_program_info_log(shader_program)
println('shader compilation failed')
println('vertex source = $vert_src')
println('fragment source = $frag_src')
println(log)
exit(1)
}
gl.delete_shader(vert)
gl.delete_shader(frag)
return shader_program
}
fn (state mut AppState) create_buffers() {
vertex_data := [
// positions // colors // texture coords
0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, // top right
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, // bottom right
-0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, // bottom left
-0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0 // top left
]!
index_data := [
u16(0), 1, 3, 1, 2, 3
]!
state.vao = gl.gen_vertex_array()
gl.bind_vertex_array(state.vao)
state.vbo = gl.gen_buffer()
gl.bind_buffer(.array_buffer, state.vbo)
gl.buffer_data_f32(.array_buffer, vertex_data, .static_draw)
state.ibo = gl.gen_buffer()
gl.bind_buffer(.element_array_buffer, state.ibo)
gl.buffer_data_u16(.element_array_buffer, index_data, .static_draw)
// position attribute
gl.vertex_attrib_pointer(0, 3, .float, .gl_false, 8 * sizeof(f32), C.NULL)
gl.enable_vertex_attrib_array(0)
// color attribute
gl.vertex_attrib_pointer(1, 3, .float, .gl_false, 8 * sizeof(f32), (3 * sizeof(f32)))
gl.enable_vertex_attrib_array(1)
// texture coord attribute
gl.vertex_attrib_pointer(2, 2, .float, .gl_false, 8 * sizeof(f32), (6 * sizeof(f32)))
gl.enable_vertex_attrib_array(2)
}
fn create_tri_buffers() Mesh {
vertex_data := [
// positions // tex coords // colors
-1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, // bottom left
1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, // bottom right
0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0 // top
]!
index_data := [
u16(0), 1, 2
]!
vao := gl.gen_vertex_array()
gl.bind_vertex_array(vao)
vbo := gl.gen_buffer()
gl.bind_buffer(.array_buffer, vbo)
gl.buffer_data_f32(.array_buffer, vertex_data, .static_draw)
ibo := gl.gen_buffer()
gl.bind_buffer(.element_array_buffer, ibo)
gl.buffer_data_u16(.element_array_buffer, index_data, .static_draw)
// position attribute
gl.vertex_attrib_pointer(0, 2, .float, .gl_false, 8 * sizeof(f32), C.NULL)
gl.enable_vertex_attrib_array(0)
// texture coord attribute
gl.vertex_attrib_pointer(2, 2, .float, .gl_false, 8 * sizeof(f32), 2 * sizeof(f32))
gl.enable_vertex_attrib_array(2)
// color attribute
gl.vertex_attrib_pointer(2, 4, .float, .gl_false, 8 * sizeof(f32), 2 * sizeof(f32))
gl.enable_vertex_attrib_array(2)
return Mesh { vao, vbo, ibo }
}
fn (state mut AppState) load_textures() {
image.set_flip_vertically_on_load(true)
state.tex = gl.gen_texture()
gl.bind_texture(.texture_2d, state.tex)
// set the texture wrapping parameters
gl.tex_parameteri(.texture_2d, .texture_wrap_s, C.GL_REPEAT)
gl.tex_parameteri(.texture_2d, .texture_wrap_t, C.GL_REPEAT)
// set texture filtering parameters
gl.tex_parameteri(.texture_2d, .texture_min_filter, C.GL_LINEAR)
gl.tex_parameteri(.texture_2d, .texture_mag_filter, C.GL_LINEAR)
img := image.load('assets/container.jpg')
gl.tex_image_2d(.texture_2d, 0, .rgb, img.width, img.height, 0, .rgb, .unsigned_byte, img.data)
img.free()
state.tex2 = gl.gen_texture()
gl.bind_texture(.texture_2d, state.tex2)
// set the texture wrapping parameters
gl.tex_parameteri(.texture_2d, .texture_wrap_s, C.GL_REPEAT)
gl.tex_parameteri(.texture_2d, .texture_wrap_t, C.GL_REPEAT)
// set texture filtering parameters
gl.tex_parameteri(.texture_2d, .texture_min_filter, C.GL_LINEAR)
gl.tex_parameteri(.texture_2d, .texture_mag_filter, C.GL_LINEAR)
img2 := image.load('assets/face.png')
gl.tex_image_2d(.texture_2d, 0, .rgba, img2.width, img2.height, 0, .rgba, .unsigned_byte, img2.data)
img2.free()
gl.use_program(state.program1)
gl.uniform1i(gl.get_uniform_location(state.program1, "texture1"), 0)
gl.uniform1i(gl.get_uniform_location(state.program1, "texture2"), 1)
}
fn (state AppState) draw_quad() {
gl.use_program(state.program1)
gl.active_texture(.texture0)
gl.bind_texture(.texture_2d, state.tex)
gl.active_texture(.texture1)
gl.bind_texture(.texture_2d, state.tex2)
gl.bind_vertex_array(state.vao)
gl.draw_elements(.triangle_fan, 6, .unsigned_short, C.NULL)
}
fn (state AppState) draw_tri() {
gl.use_program(state.program2)
gl.active_texture(.texture0)
gl.bind_texture(.texture_2d, 0)
gl.active_texture(.texture1)
gl.bind_texture(.texture_2d, 0)
gl.bind_vertex_array(state.tri_mesh.vao)
gl.draw_elements(.triangle_fan, 3, .unsigned_short, C.NULL)
}
Fills a polygon with a color.
#setup vars
$OutputFile = "C:\Users\cs1dah\Downloads\result.jpg"
$bmp = new-object System.Drawing.Bitmap 400,400
$brushWhite = [System.Drawing.Brushes]::White
$brushBlack = [System.Drawing.Brushes]::Black
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
$graphics.FillRectangle($brushBg,0,0,$bmp.Width,$bmp.Height)
#define points
[System.Drawing.Point]$pt1 = [System.Drawing.Point]::new(100,100)
[System.Drawing.Point]$pt2 = [System.Drawing.Point]::new(100,150)
[System.Drawing.Point]$pt3 = [System.Drawing.Point]::new(150,150)
#create array of points
[System.Drawing.Point[]]$PolyPoints = ($pt1,$pt2,$pt3)
$graphics.FillPolygon($brushBlack, $PolyPoints)
$bmp.Save($OutputFile)
# Tidy Up
$bmp.Dispose()
# launch Output file
& $OutputFile
This code snippet draws text by loading a font via rusttype and computes the vertex data needed to draw a string and feeds that to an OpenGL shader. Supports arbitrary font sizes and colors. This is a nice way to draw text with raw opengl without a framework.
use glow::*;
use text;
fn main() {
// Setup window gl context ...
// possibly_current_ctx is something that you can create from glutin.
let gl = glow::Context::from_loader_function(|s| {
possibly_current_ctx.get_proc_address(s) as *const _
});
let mut gfx_ctx = Graphics::create(gl);
gfx_ctx.init_font();
// Inside some render loop.
gfx_ctx.current_font_size = 18;
gfx_ctx.current_fill_color = graphics::Color::create_rgba(r, g, b, a);
gfx_ctx.fill_text(&text, x, y);
}
pub struct Graphics {
pub gl: T,
pub current_fill_color: Color,
pub current_font_size: f32,
}
impl Graphics {
pub fn create(gl: T) -> Self {
unsafe {
// Initialize the shader program.
// Unsafe since we're using glow.
// Not shown here are also buffer initializations.
let text_program = Self::create_program(&gl, text::VERT_300_SRC, text::FRAG_300_SRC);
Graphics:: {
gl: gl,
simple_program: gl_simple_program,
current_fill_color: Color::create_rgba(0.0, 0.0, 0.0, 0.0),
current_font_size: 20.0,
projection_transform_matrix: projection_transform_matrix,
text_program: gl_text_program,
font: None,
}
}
}
pub fn init_font(&mut self) {
// Load default font.
let font = text::FontTexture::new(self, &include_bytes!("Montserrat-Regular.ttf")[..],
70, text::ascii_character_list());
self.font = Some(font);
}
pub fn fill_text(&mut self, text: &str, x: f32, y: f32) {
pub current_fill_color: Color,
pub current_font_size: f32,
let font = self.font.as_ref().unwrap();
text::fill_text(self, &font, text, x, y, &self.current_fill_color, self.current_font_size);
}
}