mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
gg: add gg.m4, use it in the sokol GLSL examples (#8755)
This commit is contained in:
426
examples/sokol/01_cubes/cube.v
Normal file
426
examples/sokol/01_cubes/cube.v
Normal file
@ -0,0 +1,426 @@
|
||||
/**********************************************************************
|
||||
*
|
||||
* Sokol 3d cube demo
|
||||
*
|
||||
* Copyright (c) 2021 Dario Deledda. All rights reserved.
|
||||
* Use of this source code is governed by an MIT license
|
||||
* that can be found in the LICENSE file.
|
||||
*
|
||||
* TODO:
|
||||
* - add instancing
|
||||
* - add an exampel with shaders
|
||||
**********************************************************************/
|
||||
import gg
|
||||
import gx
|
||||
import math
|
||||
import sokol.sapp
|
||||
import sokol.gfx
|
||||
import sokol.sgl
|
||||
|
||||
const (
|
||||
win_width = 800
|
||||
win_height = 800
|
||||
bg_color = gx.white
|
||||
)
|
||||
|
||||
struct App {
|
||||
mut:
|
||||
gg &gg.Context
|
||||
pip_3d C.sgl_pipeline
|
||||
texture C.sg_image
|
||||
init_flag bool
|
||||
frame_count int
|
||||
mouse_x int = -1
|
||||
mouse_y int = -1
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Texture functions
|
||||
*
|
||||
******************************************************************************/
|
||||
fn create_texture(w int, h int, buf byteptr) C.sg_image {
|
||||
sz := w * h * 4
|
||||
mut img_desc := C.sg_image_desc{
|
||||
width: w
|
||||
height: h
|
||||
num_mipmaps: 0
|
||||
min_filter: .linear
|
||||
mag_filter: .linear
|
||||
// usage: .dynamic
|
||||
wrap_u: .clamp_to_edge
|
||||
wrap_v: .clamp_to_edge
|
||||
label: &byte(0)
|
||||
d3d11_texture: 0
|
||||
}
|
||||
// commen if .dynamic is enabled
|
||||
img_desc.content.subimage[0][0] = C.sg_subimage_content{
|
||||
ptr: buf
|
||||
size: sz
|
||||
}
|
||||
|
||||
sg_img := C.sg_make_image(&img_desc)
|
||||
return sg_img
|
||||
}
|
||||
|
||||
fn destroy_texture(sg_img C.sg_image) {
|
||||
C.sg_destroy_image(sg_img)
|
||||
}
|
||||
|
||||
// Use only if usage: .dynamic is enabled
|
||||
fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr) {
|
||||
sz := w * h * 4
|
||||
mut tmp_sbc := C.sg_image_content{}
|
||||
tmp_sbc.subimage[0][0] = C.sg_subimage_content{
|
||||
ptr: buf
|
||||
size: sz
|
||||
}
|
||||
C.sg_update_image(sg_img, &tmp_sbc)
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Draw functions
|
||||
*
|
||||
******************************************************************************/
|
||||
fn draw_triangle() {
|
||||
sgl.defaults()
|
||||
sgl.begin_triangles()
|
||||
sgl.v2f_c3b(0.0, 0.5, 255, 0, 0)
|
||||
sgl.v2f_c3b(-0.5, -0.5, 0, 0, 255)
|
||||
sgl.v2f_c3b(0.5, -0.5, 0, 255, 0)
|
||||
sgl.end()
|
||||
}
|
||||
|
||||
// vertex specification for a cube with colored sides and texture coords
|
||||
fn cube() {
|
||||
sgl.begin_quads()
|
||||
// edge color
|
||||
sgl.c3f(1.0, 0.0, 0.0)
|
||||
// edge coord
|
||||
// x,y,z, texture cord: u,v
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0)
|
||||
sgl.c3f(0.0, 1.0, 0.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, -1.0, -1.0)
|
||||
sgl.c3f(0.0, 0.0, 1.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0)
|
||||
sgl.c3f(1.0, 0.5, 0.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, -1.0, -1.0)
|
||||
sgl.c3f(0.0, 0.5, 1.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, -1.0, -1.0)
|
||||
sgl.c3f(1.0, 0.0, 0.5)
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, -1.0, 1.0)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, 1.0, 1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, 1.0, -1.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, -1.0, -1.0)
|
||||
sgl.end()
|
||||
}
|
||||
|
||||
fn draw_cubes(app App) {
|
||||
rot := [f32(1.0) * (app.frame_count % 360), 0.5 * f32(app.frame_count % 360)]
|
||||
// rot := [f32(app.mouse_x), f32(app.mouse_y)]
|
||||
|
||||
sgl.defaults()
|
||||
sgl.load_pipeline(app.pip_3d)
|
||||
|
||||
sgl.matrix_mode_projection()
|
||||
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0)
|
||||
|
||||
sgl.matrix_mode_modelview()
|
||||
sgl.translate(0.0, 0.0, -12.0)
|
||||
sgl.rotate(sgl.rad(rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(sgl.rad(rot[1]), 0.0, 1.0, 0.0)
|
||||
cube()
|
||||
sgl.push_matrix()
|
||||
sgl.translate(0.0, 0.0, 3.0)
|
||||
sgl.scale(0.5, 0.5, 0.5)
|
||||
sgl.rotate(-2.0 * sgl.rad(rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(-2.0 * sgl.rad(rot[1]), 0.0, 1.0, 0.0)
|
||||
cube()
|
||||
sgl.push_matrix()
|
||||
sgl.translate(0.0, 0.0, 3.0)
|
||||
sgl.scale(0.5, 0.5, 0.5)
|
||||
sgl.rotate(-3.0 * sgl.rad(2 * rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(3.0 * sgl.rad(2 * rot[1]), 0.0, 0.0, 1.0)
|
||||
cube()
|
||||
sgl.pop_matrix()
|
||||
sgl.pop_matrix()
|
||||
}
|
||||
|
||||
fn cube_t(r f32, g f32, b f32) {
|
||||
sgl.begin_quads()
|
||||
// edge color
|
||||
sgl.c3f(r, g, b)
|
||||
// edge coord
|
||||
// x,y,z, texture cord: u,v
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0)
|
||||
sgl.c3f(r, g, b)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.0, 0.0)
|
||||
sgl.c3f(r, g, b)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0)
|
||||
sgl.c3f(r, g, b)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, 0.0, 0.0)
|
||||
sgl.c3f(r, g, b)
|
||||
sgl.v3f_t2f(1.0, -1.0, -1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(1.0, -1.0, 1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(-1.0, -1.0, 1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(-1.0, -1.0, -1.0, 0.0, 0.0)
|
||||
sgl.c3f(r, g, b)
|
||||
sgl.v3f_t2f(-1.0, 1.0, -1.0, 0.0, 0.25)
|
||||
sgl.v3f_t2f(-1.0, 1.0, 1.0, 0.25, 0.25)
|
||||
sgl.v3f_t2f(1.0, 1.0, 1.0, 0.25, 0.0)
|
||||
sgl.v3f_t2f(1.0, 1.0, -1.0, 0.0, 0.0)
|
||||
sgl.end()
|
||||
}
|
||||
|
||||
fn draw_texture_cubes(app App) {
|
||||
rot := [f32(app.mouse_x), f32(app.mouse_y)]
|
||||
sgl.defaults()
|
||||
sgl.load_pipeline(app.pip_3d)
|
||||
|
||||
sgl.enable_texture()
|
||||
sgl.texture(app.texture)
|
||||
|
||||
sgl.matrix_mode_projection()
|
||||
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 100.0)
|
||||
|
||||
sgl.matrix_mode_modelview()
|
||||
sgl.translate(0.0, 0.0, -12.0)
|
||||
sgl.rotate(sgl.rad(rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(sgl.rad(rot[1]), 0.0, 1.0, 0.0)
|
||||
cube_t(1, 1, 1)
|
||||
sgl.push_matrix()
|
||||
sgl.translate(0.0, 0.0, 3.0)
|
||||
sgl.scale(0.5, 0.5, 0.5)
|
||||
sgl.rotate(-2.0 * sgl.rad(rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(-2.0 * sgl.rad(rot[1]), 0.0, 1.0, 0.0)
|
||||
cube_t(1, 1, 1)
|
||||
sgl.push_matrix()
|
||||
sgl.translate(0.0, 0.0, 3.0)
|
||||
sgl.scale(0.5, 0.5, 0.5)
|
||||
sgl.rotate(-3.0 * sgl.rad(2 * rot[0]), 1.0, 0.0, 0.0)
|
||||
sgl.rotate(3.0 * sgl.rad(2 * rot[1]), 0.0, 0.0, 1.0)
|
||||
cube_t(1, 1, 1)
|
||||
sgl.pop_matrix()
|
||||
sgl.pop_matrix()
|
||||
|
||||
sgl.disable_texture()
|
||||
}
|
||||
|
||||
fn cube_field(app App) {
|
||||
rot := [f32(app.mouse_x), f32(app.mouse_y)]
|
||||
xyz_sz := f32(2.0)
|
||||
field_size := 20
|
||||
|
||||
sgl.defaults()
|
||||
sgl.load_pipeline(app.pip_3d)
|
||||
|
||||
sgl.enable_texture()
|
||||
sgl.texture(app.texture)
|
||||
|
||||
sgl.matrix_mode_projection()
|
||||
sgl.perspective(sgl.rad(45.0), 1.0, 0.1, 200.0)
|
||||
|
||||
sgl.matrix_mode_modelview()
|
||||
|
||||
sgl.translate(field_size, 0.0, -120.0)
|
||||
sgl.rotate(sgl.rad(rot[0]), 0.0, 1.0, 0.0)
|
||||
sgl.rotate(sgl.rad(rot[1]), 1.0, 0.0, 0.0)
|
||||
|
||||
// draw field_size*field_size cubes
|
||||
for y in 0 .. field_size {
|
||||
for x in 0 .. field_size {
|
||||
sgl.push_matrix()
|
||||
z := f32(math.cos(f32(x * 2) / field_size) * math.sin(f32(y * 2) / field_size) * xyz_sz) * (xyz_sz * 5)
|
||||
sgl.translate(x * xyz_sz, z, y * xyz_sz)
|
||||
cube_t(f32(f32(x) / field_size), f32(f32(y) / field_size), 1)
|
||||
sgl.pop_matrix()
|
||||
}
|
||||
}
|
||||
sgl.disable_texture()
|
||||
}
|
||||
|
||||
fn frame(mut app App) {
|
||||
ws := gg.window_size()
|
||||
ratio := f32(ws.width) / ws.height
|
||||
dw := ws.width
|
||||
dh := ws.height
|
||||
ww := int(dh / 3) // not a bug
|
||||
hh := int(dh / 3)
|
||||
x0 := int(f32(dw) * 0.05)
|
||||
// x1 := dw/2
|
||||
y0 := 0
|
||||
y1 := int(f32(dh) * 0.5)
|
||||
|
||||
app.gg.begin()
|
||||
// sgl.defaults()
|
||||
|
||||
// 2d triangle
|
||||
sgl.viewport(x0, y0, ww, hh, true)
|
||||
draw_triangle()
|
||||
|
||||
// colored cubes with viewport
|
||||
sgl.viewport(x0, y1, ww, hh, true)
|
||||
draw_cubes(app)
|
||||
|
||||
// textured cubed with viewport
|
||||
sgl.viewport(0, int(dh / 5), dw, int(dh * ratio), true)
|
||||
draw_texture_cubes(app)
|
||||
|
||||
// textured field of cubes with viewport
|
||||
sgl.viewport(0, int(dh / 5), dw, int(dh * ratio), true)
|
||||
cube_field(app)
|
||||
|
||||
app.frame_count++
|
||||
|
||||
app.gg.end()
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Init / Cleanup
|
||||
*
|
||||
******************************************************************************/
|
||||
fn my_init(mut app App) {
|
||||
app.init_flag = true
|
||||
|
||||
// set max vertices,
|
||||
// for a large number of the same type of object it is better use the instances!!
|
||||
desc := sapp.create_desc()
|
||||
gfx.setup(&desc)
|
||||
sgl_desc := C.sgl_desc_t{
|
||||
max_vertices: 50 * 65536
|
||||
}
|
||||
sgl.setup(&sgl_desc)
|
||||
|
||||
// 3d pipeline
|
||||
mut pipdesc := C.sg_pipeline_desc{}
|
||||
unsafe { C.memset(&pipdesc, 0, sizeof(pipdesc)) }
|
||||
pipdesc.blend.enabled = true
|
||||
pipdesc.blend.src_factor_rgb = gfx.BlendFactor(C.SG_BLENDFACTOR_SRC_ALPHA)
|
||||
pipdesc.blend.dst_factor_rgb = gfx.BlendFactor(C.SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA)
|
||||
pipdesc.depth_stencil = C.sg_depth_stencil_state{
|
||||
depth_write_enabled: true
|
||||
depth_compare_func: gfx.CompareFunc(C.SG_COMPAREFUNC_LESS_EQUAL)
|
||||
}
|
||||
pipdesc.rasterizer = C.sg_rasterizer_state{
|
||||
cull_mode: .back
|
||||
}
|
||||
app.pip_3d = sgl.make_pipeline(&pipdesc)
|
||||
|
||||
// create chessboard texture 256*256 RGBA
|
||||
w := 256
|
||||
h := 256
|
||||
sz := w * h * 4
|
||||
tmp_txt := unsafe { malloc(sz) }
|
||||
mut i := 0
|
||||
for i < sz {
|
||||
unsafe {
|
||||
y := (i >> 0x8) >> 5 // 8 cell
|
||||
x := (i & 0xFF) >> 5 // 8 cell
|
||||
// upper left corner
|
||||
if x == 0 && y == 0 {
|
||||
tmp_txt[i] = byte(0xFF)
|
||||
tmp_txt[i + 1] = byte(0)
|
||||
tmp_txt[i + 2] = byte(0)
|
||||
tmp_txt[i + 3] = byte(0xFF)
|
||||
}
|
||||
// low right corner
|
||||
else if x == 7 && y == 7 {
|
||||
tmp_txt[i] = byte(0)
|
||||
tmp_txt[i + 1] = byte(0xFF)
|
||||
tmp_txt[i + 2] = byte(0)
|
||||
tmp_txt[i + 3] = byte(0xFF)
|
||||
} else {
|
||||
col := if ((x + y) & 1) == 1 { 0xFF } else { 0 }
|
||||
tmp_txt[i] = byte(col) // red
|
||||
tmp_txt[i + 1] = byte(col) // green
|
||||
tmp_txt[i + 2] = byte(col) // blue
|
||||
tmp_txt[i + 3] = byte(0xFF) // alpha
|
||||
}
|
||||
i += 4
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
app.texture = create_texture(w, h, tmp_txt)
|
||||
free(tmp_txt)
|
||||
}
|
||||
}
|
||||
|
||||
fn cleanup(mut app App) {
|
||||
gfx.shutdown()
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* event
|
||||
*
|
||||
******************************************************************************/
|
||||
fn my_event_manager(mut ev sapp.Event, mut app App) {
|
||||
if ev.typ == .mouse_move {
|
||||
app.mouse_x = int(ev.mouse_x)
|
||||
app.mouse_y = int(ev.mouse_y)
|
||||
}
|
||||
if ev.typ == .touches_began || ev.typ == .touches_moved {
|
||||
if ev.num_touches > 0 {
|
||||
touch_point := ev.touches[0]
|
||||
app.mouse_x = int(touch_point.pos_x)
|
||||
app.mouse_y = int(touch_point.pos_y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Main
|
||||
*
|
||||
******************************************************************************/
|
||||
fn main() {
|
||||
// App init
|
||||
mut app := &App{
|
||||
gg: 0
|
||||
}
|
||||
|
||||
app.gg = gg.new_context(
|
||||
width: win_width
|
||||
height: win_height
|
||||
use_ortho: true // This is needed for 2D drawing
|
||||
create_window: true
|
||||
window_title: '3D Cube Demo'
|
||||
user_data: app
|
||||
bg_color: bg_color
|
||||
frame_fn: frame
|
||||
init_fn: my_init
|
||||
cleanup_fn: cleanup
|
||||
event_fn: my_event_manager
|
||||
)
|
||||
|
||||
app.gg.run()
|
||||
}
|
Reference in New Issue
Block a user