2021-01-25 01:17:50 +03:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Sokol 3 d 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 .
*
2021-02-15 16:40:28 +03:00
* HOW TO COMPILE SHADERS :
2021-04-08 03:11:41 +03:00
* - download the sokol shader convertor tool from https : //github.com/floooh/sokol-tools-bin
*
2021-02-15 16:40:28 +03:00
* - compile the . glsl shader with :
* linux : sokol - shdc -- input cube_glsl . glsl -- output cube_glsl . h -- slang glsl330
* windows : sokol - shdc . exe -- input cube_glsl . glsl -- output cube_glsl . h -- slang glsl330
*
* -- slang parameter can be :
* - glsl330 : desktop GL
* - glsl100 : GLES2 / WebGL
* - glsl300es : GLES3 / WebGL2
* - hlsl4 : D3D11
* - hlsl5 : D3D11
* - metal_macos : Metal on macOS
* - metal_ios : Metal on iOS device
* - metal_sim : Metal on iOS simulator
* - wgpu : WebGPU
*
* you can have multiple platforms at the same time passing prameter like this : -- slang glsl330 : hlsl5 : metal_macos
* for further infos have a look at the sokol shader tool docs .
*
2021-01-25 01:17:50 +03:00
* TODO :
* - add instancing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
import gg
import gx
2021-02-17 08:47:41 +03:00
// import math
2021-01-25 01:17:50 +03:00
import sokol . sapp
import sokol . gfx
import sokol . sgl
2021-02-15 16:40:28 +03:00
import time
import gg . m4
// GLSL Include and functions
2021-04-19 19:01:47 +03:00
#flag -I @VMODROOT/.
2021-02-15 16:40:28 +03:00
# include "cube_glsl.h" #Please use sokol-shdc to generate the necessary cube_glsl.h file from cube_glsl.glsl (see the instructions at the top of this file)
2021-02-17 08:47:41 +03:00
2021-04-07 21:39:23 +03:00
fn C . cube_shader_desc ( gfx . Backend ) & C . sg_shader_desc
2021-01-25 01:17:50 +03:00
const (
win_width = 800
win_height = 800
bg_color = gx . white
)
struct App {
mut :
2021-02-17 08:47:41 +03:00
gg & gg . Context
pip_3d C . sgl_pipeline
texture C . sg_image
init_flag bool
frame_count int
2021-02-18 12:11:26 +03:00
mouse_x int = - 1
mouse_y int = - 1
2021-02-15 16:40:28 +03:00
// glsl
cube_pip_glsl C . sg_pipeline
cube_bind C . sg_bindings
// time
2021-02-17 08:47:41 +03:00
ticks i64
2021-01-25 01:17:50 +03:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Texture functions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2021-04-05 18:17:45 +03:00
fn create_texture ( w int , h int , buf & byte ) C . sg_image {
2021-01-25 01:17:50 +03:00
sz := w * h * 4
mut img_desc := C . sg_image_desc {
width : w
height : h
num_mipmaps : 0
2021-02-17 08:47:41 +03:00
min_filter : . linear
mag_filter : . linear
// usage: .dynamic
2021-01-25 01:17:50 +03:00
wrap_u : . clamp_to_edge
wrap_v : . clamp_to_edge
label : & byte ( 0 )
d3d11_texture : 0
}
2021-02-15 16:40:28 +03:00
// comment if .dynamic is enabled
2021-04-07 21:39:23 +03:00
img_desc . data . subimage [ 0 ] [ 0 ] = C . sg_range {
2021-01-25 01:17:50 +03:00
ptr : buf
2021-04-07 21:39:23 +03:00
size : size_t ( sz )
2021-01-25 01:17:50 +03:00
}
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
sg_img := C . sg_make_image ( & img_desc )
return sg_img
}
2021-02-17 08:47:41 +03:00
fn destroy_texture ( sg_img C . sg_image ) {
2021-01-25 01:17:50 +03:00
C . sg_destroy_image ( sg_img )
}
// Use only if usage: .dynamic is enabled
2021-04-05 18:17:45 +03:00
fn update_text_texture ( sg_img C . sg_image , w int , h int , buf & byte ) {
2021-01-25 01:17:50 +03:00
sz := w * h * 4
2021-04-07 21:39:23 +03:00
mut tmp_sbc := C . sg_image_data { }
tmp_sbc . subimage [ 0 ] [ 0 ] = C . sg_range {
2021-01-25 01:17:50 +03:00
ptr : buf
2021-04-07 21:39:23 +03:00
size : size_t ( sz )
2021-01-25 01:17:50 +03:00
}
C . sg_update_image ( sg_img , & tmp_sbc )
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Draw functions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
fn draw_triangle ( ) {
sgl . defaults ( )
sgl . begin_triangles ( )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
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 )
2021-02-17 08:47:41 +03:00
// edge coord
// x,y,z, texture cord: u,v
2021-02-18 12:11:26 +03:00
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 )
2021-02-17 08:47:41 +03:00
sgl . v3f_t2f ( - 1.0 , - 1.0 , - 1.0 , - 1.0 , - 1.0 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( 0.0 , 1.0 , 0.0 )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( 0.0 , 0.0 , 1.0 )
2021-02-18 12:11:26 +03:00
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 )
2021-02-17 08:47:41 +03:00
sgl . v3f_t2f ( - 1.0 , - 1.0 , - 1.0 , - 1.0 , - 1.0 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( 1.0 , 0.5 , 0.0 )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( 0.0 , 0.5 , 1.0 )
2021-02-18 12:11:26 +03:00
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 )
2021-02-17 08:47:41 +03:00
sgl . v3f_t2f ( - 1.0 , - 1.0 , - 1.0 , - 1.0 , - 1.0 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( 1.0 , 0.0 , 0.5 )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . end ( )
}
fn draw_cubes ( app App ) {
2021-02-17 08:47:41 +03:00
rot := [ f32 ( 1.0 ) * ( app . frame_count % 360 ) , 0.5 * f32 ( app . frame_count % 360 ) ]
// rot := [f32(app.mouse_x), f32(app.mouse_y)]
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
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 ( )
2021-02-17 08:47:41 +03:00
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 )
2021-02-18 12:11:26 +03:00
sgl . rotate ( 3.0 * sgl . rad ( 2 * rot [ 1 ] ) , 0.0 , 0.0 , 1.0 )
2021-02-17 08:47:41 +03:00
cube ( )
sgl . pop_matrix ( )
2021-01-25 01:17:50 +03:00
sgl . pop_matrix ( )
}
2021-02-17 08:47:41 +03:00
fn cube_texture ( r f32 , g f32 , b f32 ) {
2021-01-25 01:17:50 +03:00
sgl . begin_quads ( )
// edge color
sgl . c3f ( r , g , b )
2021-02-17 08:47:41 +03:00
// edge coord
// x,y,z, texture cord: u,v
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( r , g , b )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( r , g , b )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( r , g , b )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( r , g , b )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . c3f ( r , g , b )
2021-02-18 12:11:26 +03:00
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 )
2021-01-25 01:17:50 +03:00
sgl . end ( )
}
2021-02-15 16:40:28 +03:00
/ *
2021-02-17 08:47:41 +03:00
Cube vertex buffer with packed vertex formats for color and texture coords .
2021-02-15 16:40:28 +03:00
Note that a vertex format which must be portable across all
backends must only use the normalized integer formats
( BYTE4N , UBYTE4N , SHORT2N , SHORT4N ) , which can be converted
to floating point formats in the vertex shader inputs .
The reason is that D3D11 cannot convert from non - normalized
formats to floating point inputs ( only to integer inputs ) ,
and WebGL2 / GLES2 don ' t s u p p o r t i n t e g e r v e r t e x s h a d e r i n p u t s .
* /
struct Vertex_t {
2021-02-17 08:47:41 +03:00
x f32
y f32
z f32
color u32
// u u16
// v u16
2021-02-18 12:11:26 +03:00
u f32
v f32
2021-02-15 16:40:28 +03:00
}
fn init_cube_glsl ( mut app App ) {
2021-02-17 08:47:41 +03:00
// cube vertex buffer
// d := u16(32767/8) // for compatibility with D3D11, 32767 stand for 1
d := f32 ( 1.0 ) // 0.05)
2021-02-15 16:40:28 +03:00
c := u32 ( 0xFFFFFF_FF ) // color RGBA8
2021-02-17 08:47:41 +03:00
vertices := [
2021-02-18 12:11:26 +03:00
// Face 0
Vertex_t { - 1.0 , - 1.0 , - 1.0 , c , 0 , 0 } ,
Vertex_t { 1.0 , - 1.0 , - 1.0 , c , d , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { 1.0 , 1.0 , - 1.0 , c , d , d } ,
Vertex_t { - 1.0 , 1.0 , - 1.0 , c , 0 , d } ,
2021-02-18 12:11:26 +03:00
// Face 1
Vertex_t { - 1.0 , - 1.0 , 1.0 , c , 0 , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { 1.0 , - 1.0 , 1.0 , c , d , 0 } ,
Vertex_t { 1.0 , 1.0 , 1.0 , c , d , d } ,
Vertex_t { - 1.0 , 1.0 , 1.0 , c , 0 , d } ,
2021-02-18 12:11:26 +03:00
// Face 2
Vertex_t { - 1.0 , - 1.0 , - 1.0 , c , 0 , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { - 1.0 , 1.0 , - 1.0 , c , d , 0 } ,
Vertex_t { - 1.0 , 1.0 , 1.0 , c , d , d } ,
Vertex_t { - 1.0 , - 1.0 , 1.0 , c , 0 , d } ,
2021-02-18 12:11:26 +03:00
// Face 3
Vertex_t { 1.0 , - 1.0 , - 1.0 , c , 0 , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { 1.0 , 1.0 , - 1.0 , c , d , 0 } ,
Vertex_t { 1.0 , 1.0 , 1.0 , c , d , d } ,
Vertex_t { 1.0 , - 1.0 , 1.0 , c , 0 , d } ,
2021-02-18 12:11:26 +03:00
// Face 4
Vertex_t { - 1.0 , - 1.0 , - 1.0 , c , 0 , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { - 1.0 , - 1.0 , 1.0 , c , d , 0 } ,
Vertex_t { 1.0 , - 1.0 , 1.0 , c , d , d } ,
Vertex_t { 1.0 , - 1.0 , - 1.0 , c , 0 , d } ,
2021-02-18 12:11:26 +03:00
// Face 5
Vertex_t { - 1.0 , 1.0 , - 1.0 , c , 0 , 0 } ,
2021-03-25 18:53:13 +03:00
Vertex_t { - 1.0 , 1.0 , 1.0 , c , d , 0 } ,
Vertex_t { 1.0 , 1.0 , 1.0 , c , d , d } ,
Vertex_t { 1.0 , 1.0 , - 1.0 , c , 0 , d } ,
2021-02-15 16:40:28 +03:00
]
2021-04-27 08:18:48 +03:00
mut vert_buffer_desc := C . sg_buffer_desc { label : c ' c u b e - v e r t i c e s ' }
2021-02-17 08:47:41 +03:00
unsafe { C . memset ( & vert_buffer_desc , 0 , sizeof ( vert_buffer_desc ) ) }
2021-04-07 21:39:23 +03:00
vert_buffer_desc . size = size_t ( vertices . len * int ( sizeof ( Vertex_t ) ) )
vert_buffer_desc . data = C . sg_range {
ptr : vertices . data
size : size_t ( vertices . len * int ( sizeof ( Vertex_t ) ) )
}
2021-02-17 08:47:41 +03:00
vert_buffer_desc . @ type = . vertexbuffer
// vert_buffer_desc.usage = .immutable
2021-02-15 16:40:28 +03:00
vbuf := gfx . make_buffer ( & vert_buffer_desc )
2021-02-18 12:11:26 +03:00
/* create an index buffer for the cube */
2021-02-15 16:40:28 +03:00
indices := [
2021-02-18 12:11:26 +03:00
u16 ( 0 ) , 1 , 2 , 0 , 2 , 3 ,
6 , 5 , 4 , 7 , 6 , 4 ,
8 , 9 , 10 , 8 , 10 , 11 ,
14 , 13 , 12 , 15 , 14 , 12 ,
16 , 17 , 18 , 16 , 18 , 19 ,
22 , 21 , 20 , 23 , 22 , 20
2021-02-15 16:40:28 +03:00
]
2021-04-27 08:18:48 +03:00
mut index_buffer_desc := C . sg_buffer_desc { label : c ' c u b e - i n d i c e s ' }
2021-02-17 08:47:41 +03:00
unsafe { C . memset ( & index_buffer_desc , 0 , sizeof ( index_buffer_desc ) ) }
2021-04-07 21:39:23 +03:00
index_buffer_desc . size = size_t ( indices . len * int ( sizeof ( u16 ) ) )
index_buffer_desc . data = C . sg_range {
ptr : indices . data
size : size_t ( indices . len * int ( sizeof ( u16 ) ) )
}
2021-02-17 08:47:41 +03:00
index_buffer_desc . @ type = . indexbuffer
2021-02-15 16:40:28 +03:00
ibuf := gfx . make_buffer ( & index_buffer_desc )
2021-02-17 08:47:41 +03:00
// create shader
2021-04-07 21:39:23 +03:00
shader := gfx . make_shader ( C . cube_shader_desc ( C . sg_query_backend ( ) ) )
2021-02-15 16:40:28 +03:00
mut pipdesc := C . sg_pipeline_desc { }
2021-02-17 08:47:41 +03:00
unsafe { C . memset ( & pipdesc , 0 , sizeof ( pipdesc ) ) }
2021-02-15 16:40:28 +03:00
pipdesc . layout . buffers [ 0 ] . stride = int ( sizeof ( Vertex_t ) )
// the constants [C.ATTR_vs_pos, C.ATTR_vs_color0, C.ATTR_vs_texcoord0] are generated bysokol-shdc
2021-02-18 12:11:26 +03:00
pipdesc . layout . attrs [ C . ATTR_vs_pos ] . format = . float3 // x,y,z as f32
pipdesc . layout . attrs [ C . ATTR_vs_color0 ] . format = . ubyte4n // color as u32
pipdesc . layout . attrs [ C . ATTR_vs_texcoord0 ] . format = . float2 // u,v as f32
2021-02-17 08:47:41 +03:00
// pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .short2n // u,v as u16
2021-02-15 16:40:28 +03:00
pipdesc . shader = shader
pipdesc . index_type = . uint16
2021-04-07 21:39:23 +03:00
pipdesc . depth = C . sg_depth_state {
write_enabled : true
compare : gfx . CompareFunc ( C . SG_COMPAREFUNC_LESS_EQUAL )
2021-02-15 16:40:28 +03:00
}
2021-04-07 21:39:23 +03:00
pipdesc . cull_mode = . back
2021-02-17 08:47:41 +03:00
pipdesc . label = ' g l s l _ s h a d e r p i p e l i n e ' . str
2021-02-15 16:40:28 +03:00
app . cube_bind . vertex_buffers [ 0 ] = vbuf
2021-02-17 08:47:41 +03:00
app . cube_bind . index_buffer = ibuf
2021-02-15 16:40:28 +03:00
app . cube_bind . fs_images [ C . SLOT_tex ] = app . texture
app . cube_pip_glsl = gfx . make_pipeline ( & pipdesc )
2021-02-17 08:47:41 +03:00
println ( ' G L S L i n i t D O N E ! ' )
2021-02-15 16:40:28 +03:00
}
2021-02-17 08:47:41 +03:00
fn draw_cube_glsl ( app App ) {
2021-02-15 16:40:28 +03:00
if app . init_flag == false {
return
}
rot := [ f32 ( app . mouse_y ) , f32 ( app . mouse_x ) ]
2021-02-28 00:11:26 +03:00
ws := gg . window_size_real_pixels ( )
2021-02-17 08:47:41 +03:00
// ratio := f32(ws.width)/ws.height
dw := f32 ( ws . width / 2 )
dh := f32 ( ws . height / 2 )
2021-02-15 16:40:28 +03:00
2021-02-17 08:47:41 +03:00
tr_matrix := m4 . calc_tr_matrices ( dw , dh , rot [ 0 ] , rot [ 1 ] , 2.0 )
gfx . apply_viewport ( ws . width / 2 , 0 , ws . width / 2 , ws . height / 2 , true )
2021-02-15 16:40:28 +03:00
// apply the pipline and bindings
gfx . apply_pipeline ( app . cube_pip_glsl )
gfx . apply_bindings ( app . cube_bind )
//***************
// Uniforms
//***************
// passing the view matrix as uniform
// res is a 4x4 matrix of f32 thus: 4*16 byte of size
2021-04-07 21:39:23 +03:00
vs_uniforms_range := C . sg_range {
ptr : & tr_matrix
size : size_t ( 4 * 16 )
}
gfx . apply_uniforms ( C . SG_SHADERSTAGE_VS , C . SLOT_vs_params , & vs_uniforms_range )
2021-02-15 16:40:28 +03:00
// fs uniforms
time_ticks := f32 ( time . ticks ( ) - app . ticks ) / 1000
mut text_res := [
2021-02-17 08:47:41 +03:00
f32 ( 512 ) ,
512 , /* x,y resolution to pass to FS */
time_ticks , /* time as f32 */
0 /* padding 4 Bytes == 1 f32 */ ,
2021-02-15 16:40:28 +03:00
] !
2021-04-07 21:39:23 +03:00
fs_uniforms_range := C . sg_range {
2021-04-25 21:40:38 +03:00
ptr : unsafe { & text_res }
2021-04-07 21:39:23 +03:00
size : size_t ( 4 * 4 )
}
gfx . apply_uniforms ( C . SG_SHADERSTAGE_FS , C . SLOT_fs_params , & fs_uniforms_range )
2021-02-15 16:40:28 +03:00
2021-02-17 08:47:41 +03:00
gfx . draw ( 0 , ( 3 * 2 ) * 6 , 1 )
2021-02-15 16:40:28 +03:00
gfx . end_pass ( )
gfx . commit ( )
}
2021-01-25 01:17:50 +03:00
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 )
2021-02-17 08:47:41 +03:00
cube_texture ( 1 , 1 , 1 )
sgl . push_matrix ( )
2021-02-18 12:11:26 +03:00
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_texture ( 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_texture ( 1 , 1 , 1 )
sgl . pop_matrix ( )
2021-01-25 01:17:50 +03:00
sgl . pop_matrix ( )
sgl . disable_texture ( )
}
fn frame ( mut app App ) {
2021-02-28 00:11:26 +03:00
ws := gg . window_size_real_pixels ( )
2021-02-17 08:47:41 +03:00
ratio := f32 ( ws . width ) / ws . height
2021-02-02 15:09:40 +03:00
dw := ws . width
dh := ws . height
2021-02-17 08:47:41 +03:00
ww := int ( dh / 3 ) // not a bug
hh := int ( dh / 3 )
2021-02-02 15:09:40 +03:00
x0 := int ( f32 ( dw ) * 0.05 )
2021-02-17 08:47:41 +03:00
// x1 := dw/2
2021-01-25 01:17:50 +03:00
y0 := 0
2021-02-02 15:09:40 +03:00
y1 := int ( f32 ( dh ) * 0.5 )
2021-02-17 08:47:41 +03:00
// app.gg.begin()
2021-02-15 16:40:28 +03:00
2021-01-25 01:17:50 +03:00
app . gg . begin ( )
2021-02-15 16:40:28 +03:00
sgl . defaults ( )
2021-01-25 01:17:50 +03:00
// 2d triangle
sgl . viewport ( x0 , y0 , ww , hh , true )
draw_triangle ( )
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
// colored cubes with viewport
sgl . viewport ( x0 , y1 , ww , hh , true )
draw_cubes ( app )
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
// textured cubed with viewport
2021-02-17 08:47:41 +03:00
sgl . viewport ( 0 , int ( dh / 5 ) , dw , int ( dh * ratio ) , true )
2021-01-25 01:17:50 +03:00
draw_texture_cubes ( app )
2021-02-02 15:09:40 +03:00
2021-02-15 16:40:28 +03:00
app . gg . end ( )
// clear
mut color_action := C . sg_color_attachment_action {
2021-02-17 08:47:41 +03:00
action : gfx . Action ( C . SG_ACTION_DONTCARE ) // C.SG_ACTION_CLEAR)
2021-04-07 21:39:23 +03:00
value : C . sg_color {
r : 1.0
g : 1.0
b : 1.0
a : 1.0
}
2021-02-15 16:40:28 +03:00
}
mut pass_action := C . sg_pass_action { }
pass_action . colors [ 0 ] = color_action
gfx . begin_default_pass ( & pass_action , ws . width , ws . height )
// glsl cube
draw_cube_glsl ( app )
2021-01-25 01:17:50 +03:00
app . frame_count ++
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Init / Cleanup
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
fn my_init ( mut app App ) {
// 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 )
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
// 3d pipeline
mut pipdesc := C . sg_pipeline_desc { }
2021-02-17 08:47:41 +03:00
unsafe { C . memset ( & pipdesc , 0 , sizeof ( pipdesc ) ) }
2021-04-07 21:39:23 +03:00
color_state := C . sg_color_state {
blend : C . sg_blend_state {
enabled : true
src_factor_rgb : gfx . BlendFactor ( C . SG_BLENDFACTOR_SRC_ALPHA )
dst_factor_rgb : gfx . BlendFactor ( C . SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA )
}
2021-01-25 01:17:50 +03:00
}
2021-04-07 21:39:23 +03:00
pipdesc . colors [ 0 ] = color_state
pipdesc . depth = C . sg_depth_state {
write_enabled : true
compare : gfx . CompareFunc ( C . SG_COMPAREFUNC_LESS_EQUAL )
2021-01-25 01:17:50 +03:00
}
2021-04-07 21:39:23 +03:00
pipdesc . cull_mode = . back
2021-01-25 01:17:50 +03:00
app . pip_3d = sgl . make_pipeline ( & pipdesc )
2021-02-02 15:09:40 +03:00
2021-01-25 01:17:50 +03:00
// create chessboard texture 256*256 RGBA
w := 256
h := 256
sz := w * h * 4
2021-02-17 08:47:41 +03:00
tmp_txt := unsafe { malloc ( sz ) }
2021-01-25 01:17:50 +03:00
mut i := 0
for i < sz {
unsafe {
2021-02-17 08:47:41 +03:00
y := ( i >> 0x8 ) >> 5 // 8 cell
x := ( i & 0xFF ) >> 5 // 8 cell
2021-01-25 01:17:50 +03:00
// upper left corner
2021-02-17 08:47:41 +03:00
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 )
2021-01-25 01:17:50 +03:00
}
// low right corner
2021-02-17 08:47:41 +03:00
else if x == 7 && y == 7 {
2021-02-18 12:11:26 +03:00
tmp_txt [ i + 0 ] = byte ( 0 )
2021-02-17 08:47:41 +03:00
tmp_txt [ i + 1 ] = byte ( 0xFF )
tmp_txt [ i + 2 ] = byte ( 0 )
tmp_txt [ i + 3 ] = byte ( 0xFF )
2021-01-25 01:17:50 +03:00
} else {
2021-02-17 08:47:41 +03:00
col := if ( ( x + y ) & 1 ) == 1 { 0xFF } else { 128 }
2021-02-18 12:11:26 +03:00
tmp_txt [ i + 0 ] = byte ( col ) // red
tmp_txt [ i + 1 ] = byte ( col ) // green
tmp_txt [ i + 2 ] = byte ( col ) // blue
2021-02-17 08:47:41 +03:00
tmp_txt [ i + 3 ] = byte ( 0xFF ) // alpha
2021-01-25 01:17:50 +03:00
}
i += 4
}
}
2021-02-15 16:40:28 +03:00
app . texture = create_texture ( w , h , tmp_txt )
2021-02-17 08:47:41 +03:00
unsafe { free ( tmp_txt ) }
2021-02-15 16:40:28 +03:00
// glsl
init_cube_glsl ( mut app )
app . init_flag = true
2021-01-25 01:17:50 +03:00
}
fn cleanup ( mut app App ) {
gfx . shutdown ( )
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* event
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2021-02-17 08:47:41 +03:00
fn my_event_manager ( mut ev gg . Event , mut app App ) {
2021-01-25 01:17:50 +03:00
if ev . typ == . mouse_move {
app . mouse_x = int ( ev . mouse_x )
app . mouse_y = int ( ev . mouse_y )
}
2021-02-02 15:09:40 +03:00
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 )
}
}
2021-01-25 01:17:50 +03:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Main
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2021-02-18 12:11:26 +03:00
[ console ] // is needed for easier diagnostics on windows
2021-02-17 08:47:41 +03:00
fn main ( ) {
2021-01-25 01:17:50 +03:00
// App init
mut app := & App {
gg : 0
}
2021-02-15 16:40:28 +03:00
mut a := [ 5 ] int { }
2021-02-17 08:47:41 +03:00
a [ 0 ] = 2
2021-02-15 16:40:28 +03:00
println ( a )
2021-02-17 08:47:41 +03:00
app . gg = gg . new_context (
2021-01-25 01:17:50 +03:00
width : win_width
height : win_height
create_window : true
window_title : ' 3 D C u b e D e m o '
user_data : app
bg_color : bg_color
frame_fn : frame
init_fn : my_init
cleanup_fn : cleanup
event_fn : my_event_manager
2021-02-17 08:47:41 +03:00
)
2021-01-25 01:17:50 +03:00
2021-02-15 16:40:28 +03:00
app . ticks = time . ticks ( )
2021-01-25 01:17:50 +03:00
app . gg . run ( )
}