1 typedef struct model model
;
2 typedef struct submodel submodel
;
3 typedef struct model_vert model_vert
;
4 typedef struct scene scene
;
5 typedef struct sdf_primative sdf_primative
;
6 typedef enum esdf_type esdf_type
;
22 v4f origin
; /* xyz, yaw */
86 static void scene_init( scene
*pscene
)
89 pscene
->indices
= NULL
;
90 pscene
->vertex_count
= 0;
91 pscene
->indice_count
= 0;
92 pscene
->shadowers
= NULL
;
93 pscene
->shadower_count
= 0;
94 pscene
->shadower_cap
= 0;
96 v3_fill( pscene
->bbx
[0], 999999.9f
);
97 v3_fill( pscene
->bbx
[1], -999999.9f
);
99 static int noise_ready
= 0;
104 u8
*buf
= malloc( 256*256*2 );
106 for( int i
=0; i
<256*256; i
++ )
108 u8 val
= rand()&0xff;
112 for( int y
=0; y
<256; y
++ )
114 for( int x
=0; x
<256; x
++ )
116 u8
*pr
= &buf
[(y
*256+x
)*2],
117 *pg
= &buf
[(((y
+17)&0xff)*256+((x
+37)&0xff))*2+1];
122 /* TODO: This texture should be delted somewhere */
123 glGenTextures( 1, &tex_dual_noise
);
124 glBindTexture( GL_TEXTURE_2D
, tex_dual_noise
);
125 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RG
, 256, 256, 0, GL_RG
,
126 GL_UNSIGNED_BYTE
, buf
);
135 /* https://www.shadertoy.com/view/4sfGzS */
136 #define SHADER_VALUE_NOISE_3D \
137 "uniform sampler2D uTexNoise;" \
139 "float noise( vec3 x )" \
141 "vec3 i = floor(x);" \
142 "vec3 f = fract(x);" \
143 "f = f*f*(3.0-2.0*f);" \
144 "vec2 uv = (i.xy+vec2(37.0,17.0)*i.z) + f.xy;" \
145 "vec2 rg = texture( uTexNoise, (uv+0.5)/256.0).yx;"\
146 "return mix( rg.x, rg.y, f.z );" \
149 "const mat3 m = mat3( 0.00, 0.80, 0.60," \
150 "-0.80, 0.36, -0.48," \
151 "-0.60, -0.48, 0.64 );" \
153 "float fractalNoise( vec3 x )" \
157 "f = 0.5000*noise( q ); q = m*q*2.01;" \
158 "f += 0.2500*noise( q ); q = m*q*2.02;" \
159 "f += 0.1250*noise( q ); q = m*q*2.03;" \
160 "f += 0.0625*noise( q ); q = m*q*2.01;" \
164 SHADER_DEFINE( shader_debug_vcol
,
165 "layout (location=0) in vec3 a_co;"
166 "layout (location=1) in vec3 a_norm;"
167 "layout (location=2) in vec4 a_colour;"
168 "layout (location=3) in vec2 a_uv;"
172 "uniform float uTime;"
173 "uniform float uSwayAmt;"
180 "vec3 compute_sway( vec3 pos )"
182 "vec4 sines = vec4( sin(uTime + pos.x)*1.0,"
183 "sin(uTime*1.2 + pos.z*2.0)*1.1,"
184 "sin(uTime*2.33)*0.5,"
185 "sin(uTime*0.6 + pos.x*0.3)*1.3 );"
187 "vec3 offset = vec3( sines.x+sines.y*sines.w, 0.0, sines.x+sines.z );"
188 "return pos + offset*a_colour.r*uSwayAmt;"
193 "vec3 swaypos = compute_sway( a_co );"
194 "gl_Position = uPv * uMdl * vec4( swaypos, 1.0 );"
195 "aColour = a_colour;"
197 "aNorm = normalize(mat3(uMdl) * a_norm);"
201 "out vec4 FragColor;"
204 "uniform sampler2D uTexMain;"
205 "uniform sampler2D uTexGradients;"
207 /* Include */ SHADER_VALUE_NOISE_3D
216 "vec4 colour = vec4(1.0,0.0,0.5,1.0);"
217 "vec4 diffuse = texture( uTexMain, aUv );"
221 "colour = vec4(aNorm * 0.5 + 0.5, 1.0);"
229 "float light = dot(aNorm, vec3(0.2,0.8,0.1));"
230 "vec3 grid3 = fract(aCo);"
232 "colour = vec4(vec3(light)*(1.0-grid3*0.3),1.0);"
236 "colour = vec4( aUv, 0.0, 1.0 );"
240 "if( diffuse.a < 0.45 ) discard;"
245 "float r1 = fractalNoise(aCo);"
246 "colour = vec4( vec3(r1), 1.0 );"
250 "if( diffuse.a < 0.45 ) discard;"
251 "float lighting = 1.0 - aColour.g;"
252 "colour = vec4(vec3(pow(lighting,1.6)*(diffuse.r*0.7+0.5)),1.0);"
256 "if( diffuse.a < 0.45 ) discard;"
257 "float light = 1.0 - aColour.g;"
258 "light = pow(light,1.6)*(diffuse.r*0.7+0.5);"
259 "float r1 = fractalNoise(aCo*0.01);"
261 "vec2 gradUV = vec2(light*1.9,r1+aColour.b*0.1);"
262 "vec4 gradient_sample = texture( uTexGradients, gradUV );"
263 "colour = aColour*light;"
266 "FragColor = colour;"
269 UNIFORMS({ "uPv", "uMode", "uTexMain", "uTexGradients", "uTexNoise", \
270 "uTime", "uSwayAmt", "uMdl" })
274 * Helper functions for file offsets
276 static submodel
*model_get_submodel( model
*mdl
, int id
)
278 return ((submodel
*)(mdl
+1)) + id
;
281 static model_vert
*model_vertex_base( model
*mdl
)
283 return (model_vert
*)model_get_submodel( mdl
, mdl
->layer_count
);
286 static u32
*model_indice_base( model
*mdl
)
288 return (u32
*)(model_vertex_base( mdl
) + mdl
->vertex_count
);
291 static model_vert
*submodel_vert_data( model
*mdl
, submodel
*sub
)
293 return model_vertex_base(mdl
) + sub
->vertex_start
;
296 static u32
*submodel_indice_data( model
*mdl
, submodel
*sub
)
298 return model_indice_base(mdl
) + sub
->indice_start
;
301 /* Returns -1 if not found */
302 static int submodel_get( model
*mdl
, const char *name
)
304 for( int i
=0; i
<mdl
->layer_count
; i
++ )
306 if( !strcmp( model_get_submodel(mdl
,i
)->name
, name
))
315 static void *buffer_reserve( void *buffer
, u32 count
, u32
*cap
, u32 amount
,
318 if( count
+amount
> *cap
)
320 *cap
= VG_MAX( (*cap
)*2, (*cap
)+amount
);
322 return realloc( buffer
, (*cap
) * emsize
);
329 * Append a model into the scene with a given transform
331 static void scene_add_model( scene
*pscene
, model
*mdl
, int id
,
332 v3f pos
, float yaw
, float scale
)
334 submodel
*submodel
= model_get_submodel( mdl
, id
);
336 pscene
->verts
= buffer_reserve( pscene
->verts
, pscene
->vertex_count
,
337 &pscene
->vertex_cap
, submodel
->vertex_count
, sizeof(model_vert
) );
338 pscene
->indices
= buffer_reserve( pscene
->indices
, pscene
->indice_count
,
339 &pscene
->indice_cap
, submodel
->indice_count
, sizeof(u32
) );
341 if( submodel
->sdf_type
)
343 pscene
->shadowers
= buffer_reserve( pscene
->shadowers
,
344 pscene
->shadower_count
, &pscene
->shadower_cap
, 1,
345 sizeof( struct shadower
));
347 struct shadower
*shadower
=
348 &pscene
->shadowers
[ pscene
->shadower_count
++ ];
350 shadower
->sdf
= submodel
->sdf
;
351 shadower
->sdf_type
= submodel
->sdf_type
;
353 v2_muls( shadower
->sdf
.info
, scale
, shadower
->sdf
.info
);
354 v3_muls( shadower
->sdf
.origin
, scale
, shadower
->sdf
.origin
);
355 v3_add( pos
, shadower
->sdf
.origin
, shadower
->sdf
.origin
);
358 /* Transform and place vertices */
359 model_vert
*src_verts
= submodel_vert_data( mdl
, submodel
);
360 u32
*src_indices
= submodel_indice_data( mdl
, submodel
);
363 m4x3_identity( mtx
);
364 m4x3_translate( mtx
, pos
);
365 m4x3_rotate_y( mtx
, yaw
);
366 m4x3_scale( mtx
, scale
);
369 box_copy( submodel
->bbx
, bbxnew
);
370 m4x3_transform_aabb( mtx
, bbxnew
);
371 box_concat( pscene
->bbx
, bbxnew
);
374 m4x3_to_3x3( mtx
, rotation
);
376 float rand_hue
= vg_randf();
378 for( u32 i
=0; i
<submodel
->vertex_count
; i
++ )
380 model_vert
*pvert
= &pscene
->verts
[ pscene
->vertex_count
+i
],
381 *src
= &src_verts
[ i
];
383 m4x3_mulv( mtx
, src
->co
, pvert
->co
);
384 m3x3_mulv( rotation
, src
->norm
, pvert
->norm
);
386 v4_copy( src
->colour
, pvert
->colour
);
387 v2_copy( src
->uv
, pvert
->uv
);
389 float rel_y
= src
->co
[1] / submodel
->bbx
[1][1];
390 pvert
->colour
[0] = rel_y
;
391 pvert
->colour
[2] = rand_hue
;
394 for( u32 i
=0; i
<submodel
->indice_count
; i
++ )
396 u32
*pidx
= &pscene
->indices
[ pscene
->indice_count
+i
];
397 *pidx
= src_indices
[i
] + pscene
->vertex_count
;
400 pscene
->vertex_count
+= submodel
->vertex_count
;
401 pscene
->indice_count
+= submodel
->indice_count
;
404 static void scene_shadow_sphere( scene
*pscene
, v3f sphere
,
405 v4f params
, v3f lightdir
)
407 for( int i
=0; i
<pscene
->vertex_count
; i
++ )
409 model_vert
*vert
= &pscene
->verts
[i
];
412 v3_sub( sphere
, vert
->co
, delta
);
414 float d
= v3_dot( lightdir
, delta
);
417 v3_muls( lightdir
, d
, closest
);
418 float dist
= v3_dist( closest
, delta
),
419 shading
= vg_maxf( dist
- params
[0], 0.0f
);
421 shading
= vg_minf( shading
* params
[1], 1.0f
);
422 vert
->colour
[1] *= shading
;
426 static void scene_shadow_gradient( scene
*pscene
, int comp
,
427 float start
, float length
)
429 float scale
= 1.0f
/ length
;
431 for( int i
=0; i
<pscene
->vertex_count
; i
++ )
433 model_vert
*vert
= &pscene
->verts
[i
];
434 float shading
= start
+ vert
->co
[comp
] * scale
;
436 vert
->colour
[1] = shading
;
441 static int sample_scene_height( scene
*pscene
, v3f pos
)
443 for( int i
=0; i
<pscene
->indice_count
/3; i
++ )
445 u32
*tri
= &pscene
->indices
[i
*3];
448 if( triangle_raycast(
449 pscene
->verts
[ tri
[0] ].co
,
450 pscene
->verts
[ tri
[1] ].co
,
451 pscene
->verts
[ tri
[2] ].co
, pos
, &height
))
460 static void sample_scene_normal( scene
*pscene
, v3f pos
, v3f normal
)
462 for( int i
=0; i
<pscene
->indice_count
/3; i
++ )
464 u32
*tri
= &pscene
->indices
[i
*3];
467 if( triangle_raycast(
468 pscene
->verts
[ tri
[0] ].co
,
469 pscene
->verts
[ tri
[1] ].co
,
470 pscene
->verts
[ tri
[2] ].co
, pos
, &height
))
474 v3_sub( pscene
->verts
[ tri
[1] ].co
,
475 pscene
->verts
[ tri
[0] ].co
,
478 v3_sub( pscene
->verts
[ tri
[2] ].co
,
479 pscene
->verts
[ tri
[0] ].co
,
482 v3_cross( v0
, v1
, normal
);
483 v3_normalize( normal
);
494 * Experimental SDF based shadows
496 * https://iquilezles.org/articles/distfunctions/
498 static float sd_cone( v3f co
, sdf_primative
*prim
)
500 float bound
= prim
->info
[1]*1.75f
;
501 if( v3_dist2( prim
->origin
, co
) > bound
*bound
)
505 v3_sub( co
, prim
->origin
, p
);
507 float h
= prim
->info
[1];
508 v2f c
= { prim
->info
[2], prim
->info
[3] };
511 v2_muls( (v2f
){ c
[0]/c
[1], -1.0f
}, h
, q
);
513 w
[0] = v2_length( (v2f
){ p
[0], p
[2] } );
516 v2_muladds( w
, q
, -vg_clampf( v2_dot(w
,q
)/v2_dot(q
,q
), 0.0f
, 1.0f
), a
);
517 v2_muladd( w
, q
, (v2f
){ vg_clampf( w
[0]/q
[0], 0.0f
, 1.0f
), 1.0f
}, b
);
519 float k
= vg_signf( q
[1] ),
520 d
= vg_minf( v2_dot( a
,a
), v2_dot( b
,b
) ),
521 s
= vg_maxf( k
*(w
[0]*q
[1]-w
[1]*q
[0]), k
*(w
[1]-q
[1]) );
523 return sqrtf(d
)*vg_signf(s
);
526 #define CACHE_AMBIENT_SHAPES
528 static float scene_ambient_sample( scene
*pscene
, v3f pos
, v3f dir
)
532 #ifdef CACHE_AMBIENT_SHAPES
533 static struct shadower
*local_shadowers
[32];
534 static int local_shadower_count
= 0;
535 static v3f local_shadower_last
= { -99999.9f
, -999999.9f
, -9999999.9f
};
537 if( v3_dist2( pos
, local_shadower_last
) > 10.0f
*10.0f
)
539 local_shadower_count
= 0;
540 v3_copy( pos
, local_shadower_last
);
542 for( int k
=0; k
<pscene
->shadower_count
; k
++ )
544 struct shadower
*shadower
= &pscene
->shadowers
[k
];
546 if( sd_cone( pos
, &shadower
->sdf
) <= 20.0f
)
548 local_shadowers
[ local_shadower_count
++ ] = shadower
;
549 if( local_shadower_count
== vg_list_size( local_shadowers
) )
556 for( int j
=0; j
<5; j
++ )
559 v3_muladds( pos
, dir
, 1.5f
*(float)j
, tracepos
);
561 float mindist
= 99999.9f
;
563 #ifndef CACHE_AMBIENT_SHAPES
565 for( int k
=0; k
<pscene
->shadower_count
; k
++ ){
566 struct shadower
*shadower
= &pscene
->shadowers
[k
];
569 for( int k
=0; k
<local_shadower_count
; k
++ ){
570 struct shadower
*shadower
= local_shadowers
[k
];
573 float dist
= vg_maxf( 0.0f
, sd_cone( tracepos
, &shadower
->sdf
));
574 mindist
= vg_minf( mindist
, dist
);
578 accum
+= vg_clampf( 1.0f
- mindist
, 0.0f
, 1.0f
)*0.2f
;
585 #define JUST_DO_EVERY_VERT
587 static void scene_compute_occlusion( scene
*pscene
)
589 v3f sundir
= { 0.2f
, 0.9f
, 0.2f
};
590 v3_normalize( sundir
);
592 /* TODO: Make this sample grid be dynamically required.
594 * 1. Only resample the light grid (1x1x1), when a vertex is outside the
597 * 2. Reorder all vertices so that each group of vertices that fit in a
598 * cube are next to eachother in the buffer. This will save cache
601 * for the sorting algorithm, i think we can already assume that *most
602 * vertices will be quite close to eachother. so instead of doing an
603 * exhaustive search we can reorder 1k chunks at a time.
607 v3_sub( pscene
->bbx
[1], pscene
->bbx
[0], sample_area
);
608 v3_ceil( sample_area
, sample_area
);
609 int ax
= sample_area
[0],
614 float *samplegrid
= malloc( ax
*ay
*az
* sizeof(float) );
616 for( int x
=0; x
<ax
; x
++ ){
617 for( int y
=0; y
<ay
; y
++ ){
618 for( int z
=0; z
<az
; z
++ )
620 v3f sample_pos
= { x
,y
,z
};
621 v3_add( pscene
->bbx
[0], sample_pos
, sample_pos
);
622 float accum
= scene_ambient_sample( pscene
, sample_pos
, sundir
);
624 samplegrid
[x
+ y
*ax
+ z
*ax
*ay
] = accum
;
627 v3i cube_pos
= { -999999, -999999, -999999 };
628 int cube_resamples
= 0, hits
= 0, misses
= 0;
630 float s0
=0.0f
,s1
=0.0f
,s2
=0.0f
,s3
=0.0f
,s4
=0.0f
,s5
=0.0f
,s6
=0.0f
,s7
=0.0f
;
633 for( int i
=0; i
<pscene
->vertex_count
; i
++ )
635 model_vert
*vert
= &pscene
->verts
[i
];
639 v3_sub( vert
->co
, pscene
->bbx
[0], q
);
641 v3_copy( vert
->co
, q
);
651 #ifndef JUST_DO_EVERY_VERT
661 s0
= samplegrid
[ x
+ y
*ax
+ z
*ax
*ay
],
662 s1
= samplegrid
[(x
+1) + y
*ax
+ z
*ax
*ay
],
663 s2
= samplegrid
[ x
+ (y
+1)*ax
+ z
*ax
*ay
],
664 s3
= samplegrid
[(x
+1) + (y
+1)*ax
+ z
*ax
*ay
],
665 s4
= samplegrid
[ x
+ y
*ax
+ (z
+1)*ax
*ay
],
666 s5
= samplegrid
[(x
+1) + y
*ax
+ (z
+1)*ax
*ay
],
667 s6
= samplegrid
[ x
+ (y
+1)*ax
+ (z
+1)*ax
*ay
],
668 s7
= samplegrid
[(x
+1) + (y
+1)*ax
+ (z
+1)*ax
*ay
],
670 if( x
!=cube_pos
[0] || y
!=cube_pos
[1] || z
!=cube_pos
[2] )
676 s0
= scene_ambient_sample( pscene
, (v3f
){ x
,y
,z
}, sundir
);
677 s1
= scene_ambient_sample( pscene
, (v3f
){ x
+1,y
,z
}, sundir
);
678 s2
= scene_ambient_sample( pscene
, (v3f
){ x
,y
+1,z
}, sundir
);
679 s3
= scene_ambient_sample( pscene
, (v3f
){ x
+1,y
+1,z
}, sundir
);
680 s4
= scene_ambient_sample( pscene
, (v3f
){ x
,y
,z
+1 }, sundir
);
681 s5
= scene_ambient_sample( pscene
, (v3f
){ x
+1,y
,z
+1 }, sundir
);
682 s6
= scene_ambient_sample( pscene
, (v3f
){ x
,y
+1,z
+1 }, sundir
);
683 s7
= scene_ambient_sample( pscene
, (v3f
){ x
+1,y
+1,z
+1 }, sundir
);
694 s0_s1
= vg_lerpf( s0
, s1
, q
[0] ),
695 s2_s3
= vg_lerpf( s2
, s3
, q
[0] ),
696 s4_s5
= vg_lerpf( s4
, s5
, q
[0] ),
697 s6_s7
= vg_lerpf( s6
, s7
, q
[0] ),
699 s0s1_s2s3
= vg_lerpf( s0_s1
, s2_s3
, q
[1] ),
700 s4s5_s6s7
= vg_lerpf( s4_s5
, s6_s7
, q
[1] ),
701 s0s1s2s3_s4s5s6s7
= vg_lerpf( s0s1_s2s3
, s4s5_s6s7
, q
[2] );
703 vert
->colour
[1] = s0s1s2s3_s4s5s6s7
;
705 vert
->colour
[1] = scene_ambient_sample( pscene
, vert
->co
, sundir
);
710 int cube_resamples
= -1, misses
= 0, hits
= 0;
713 int static_samples
= ax
*ay
*az
,
714 vertex_samples
= pscene
->vertex_count
;
716 if( cube_resamples
< static_samples
)
717 vg_success( "Walking cube beat static grid (%d<%d. %d)!\n",
718 cube_resamples
, static_samples
, vertex_samples
);
720 vg_warn( "Walking cube was worse than static grid (%d<%d. %d).\n",
721 cube_resamples
, static_samples
, vertex_samples
);
723 vg_info( "Hits; %d, misses: %d\n", hits
, misses
);
731 for( int i
=0; i
<pscene
->vertex_count
; i
++ )
733 model_vert
*vert
= &pscene
->verts
[i
];
736 for( int j
=0; j
<5; j
++ )
739 v3_copy( vert
->co
, tracepos
);
740 v3_muladds( tracepos
, sundir
, 1.5f
*(float)j
, tracepos
);
742 float mindist
= 99999.9f
;
744 for( int k
=0; k
<pscene
->shadower_count
; k
++ )
746 struct shadower
*shadower
= &pscene
->shadowers
[k
];
747 float dist
= vg_maxf( 0.0f
, sd_cone( tracepos
, &shadower
->sdf
));
748 mindist
= vg_minf( mindist
, dist
);
751 accum
+= vg_clampf( 1.0f
- mindist
, 0.0f
, 1.0f
)*0.2f
;
754 vert
->colour
[1] = vg_minf( accum
, 1.0f
);
758 static void scene_upload( scene
*pscene
)
760 glGenVertexArrays( 1, &pscene
->vao
);
761 glGenBuffers( 1, &pscene
->vbo
);
762 glGenBuffers( 1, &pscene
->ebo
);
763 glBindVertexArray( pscene
->vao
);
765 glBindBuffer( GL_ARRAY_BUFFER
, pscene
->vbo
);
766 glBufferData( GL_ARRAY_BUFFER
, pscene
->vertex_count
*sizeof(model_vert
),
767 pscene
->verts
, GL_STATIC_DRAW
);
769 glBindVertexArray( pscene
->vao
);
770 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER
, pscene
->ebo
);
771 glBufferData( GL_ELEMENT_ARRAY_BUFFER
, pscene
->indice_count
*sizeof(u32
),
772 pscene
->indices
, GL_STATIC_DRAW
);
774 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
,
775 sizeof(model_vert
), (void*)0 );
776 glEnableVertexAttribArray( 0 );
778 glVertexAttribPointer( 1, 3, GL_FLOAT
, GL_FALSE
,
779 sizeof(model_vert
), (void *)offsetof(model_vert
, norm
) );
780 glEnableVertexAttribArray( 1 );
782 glVertexAttribPointer( 2, 4, GL_FLOAT
, GL_FALSE
,
783 sizeof(model_vert
), (void *)offsetof(model_vert
, colour
) );
784 glEnableVertexAttribArray( 2 );
786 glVertexAttribPointer( 3, 2, GL_FLOAT
, GL_FALSE
,
787 sizeof(model_vert
), (void *)offsetof(model_vert
, uv
) );
788 glEnableVertexAttribArray( 3 );
792 vg_info( "Scene upload\n" );
793 vg_info( " indices:%u\n", pscene
->indice_count
);
794 vg_info( " verts:%u\n", pscene
->vertex_count
);
797 float scene_tree_sway
= 0.1f
;
798 static void scene_draw( scene
*pscene
, int count
, int start
)
800 SHADER_USE( shader_debug_vcol
);
802 glUniformMatrix4fv( SHADER_UNIFORM( shader_debug_vcol
, "uPv" ),
803 1, GL_FALSE
, (float *)vg_pv
);
805 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uMode" ), debugview
);
806 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexMain" ), 0 );
808 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexGradients" ), 1 );
809 vg_tex2d_bind( &tex_gradients
, 1 );
811 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexNoise" ), 2 );
812 glActiveTexture( GL_TEXTURE2
);
813 glBindTexture( GL_TEXTURE_2D
, tex_dual_noise
);
815 glUniform1f( SHADER_UNIFORM( shader_debug_vcol
, "uTime" ), vg_time
);
816 glUniform1f( SHADER_UNIFORM( shader_debug_vcol
, "uSwayAmt" ),
819 glBindVertexArray( pscene
->vao
);
823 glDrawElements( GL_TRIANGLES
, pscene
->indice_count
,
830 glDrawElements( GL_TRIANGLES
, count
,
832 (void *)(start
*sizeof(u32
))
838 for( int i
=0; i
<pscene
->shadower_count
; i
++ )
840 struct shadower
*shadower
= &pscene
->shadowers
[i
];
843 v3_copy( shadower
->sdf
.origin
, base
);
844 base
[1] -= shadower
->sdf
.info
[1];
845 v3_copy( base
, side
);
846 side
[0] += shadower
->sdf
.info
[0];
848 vg_line2( shadower
->sdf
.origin
, base
, 0xff00ff00, 0xff0000ff );
849 vg_line2( side
, base
, 0xff00ff00, 0xff0000ff );
850 vg_line( side
, shadower
->sdf
.origin
, 0xff00ff00 );
853 v3f p0
= { pscene
->bbx
[0][0], pscene
->bbx
[0][1], pscene
->bbx
[0][2] },
854 p1
= { pscene
->bbx
[0][0], pscene
->bbx
[1][1], pscene
->bbx
[0][2] },
855 p2
= { pscene
->bbx
[1][0], pscene
->bbx
[1][1], pscene
->bbx
[0][2] },
856 p3
= { pscene
->bbx
[1][0], pscene
->bbx
[0][1], pscene
->bbx
[0][2] },
858 p4
= { pscene
->bbx
[0][0], pscene
->bbx
[0][1], pscene
->bbx
[1][2] },
859 p5
= { pscene
->bbx
[0][0], pscene
->bbx
[1][1], pscene
->bbx
[1][2] },
860 p6
= { pscene
->bbx
[1][0], pscene
->bbx
[1][1], pscene
->bbx
[1][2] },
861 p7
= { pscene
->bbx
[1][0], pscene
->bbx
[0][1], pscene
->bbx
[1][2] };
863 u32 col
= 0xffff00c8;
864 vg_line( p0
, p1
, col
);
865 vg_line( p1
, p2
, col
);
866 vg_line( p2
, p3
, col
);
867 vg_line( p3
, p0
, col
);
869 vg_line( p4
, p5
, col
);
870 vg_line( p5
, p6
, col
);
871 vg_line( p6
, p7
, col
);
872 vg_line( p7
, p4
, col
);
874 vg_line( p0
, p4
, col
);
875 vg_line( p1
, p5
, col
);
876 vg_line( p2
, p6
, col
);
877 vg_line( p3
, p7
, col
);
881 static void scene_register(void)
883 SHADER_INIT( shader_debug_vcol
);