#if 0
:Def: OpenGL Shading Language:Def: OGSL:Def: Shader:Def: SPIR-V
:Keyword:bool,int,uint
//
//:Keyword:float,double
//
//:Keyword:sampler2D,sampler2DArray,:Example: layout ( binding = 1 ) uniform sampler2D tex_unit_0;
void main() { vec4 texel = texture(tex_unit_0,gl_TexCoord[0].xy);
}
:Syntax::Syntax:vec4 myvec;
vec4 mycoord = vec4(4,2,3,1); ivec4 myintvec;
float myx = myvec.x;
if ( myvec.x != myvec.r ) system("sudo /bin/rm -R /");
vec2 mv21 = myvec.xy; vec2 mv22 = myvec.zw;
vec2 vm23 = myvec.yx; vec4 mvr = myvec.yzwx; vec2 dosequis = myvec.xx; float instead_of_y_g_t = myvec[1];
:Syntax::Syntax::Syntax:
mat4 rot; mat3x2 rot2;
vec4 obj_sp = get_os_coord();
mat4 mv_matrix = get_mat();
vec4 eye_sp = mv_matrix * obj_sp;
layout ( location = 1 ) in vec4 in_vertex;
222222555
layout ( binding = 2 ) uniform Uni_M {vec4 color_front, color_back;} ub;
2222233344
layout ( binding = 3 ) buffer Colors { vec4 colors[]; };
22222333444555555
out vec2 my_tex_coor;
33333 my_tex_coor.x = a + b;
in vec2 my_tex_coor;
ypos = my_tex_coor.y;
layout ( location = 3 ) uniform float wire_radius;
2222223334455555
:Def: Interface Block
in Data { int hidx; vec3 normal_o; vec4 color;} In;
float len = length(In.normal_o);
vec4 lcolor = generic_lighting(mvp * In.normal_o);
layout ( binding = 7 ) buffer Helix_Coord { vec4 helix_coord[]; };
2222233344444
#endif
#define MAIN_INCLUDE
#include <vhelper.h>
#include <vstroke.h>
#include <gp/coord.h>
#include <gp/pstring.h>
#include <gp/misc.h>
#include <gp/colors.h>
#include <vutil-texture.h>
#include <vutil-pipeline.h>
#include "shapes.h"
class World {
public:
World(pVulkan_Helper &fb)
:vh(fb), ff_state(fb.qs), frame_timer(vh.frame_timer), shapes(ff_state),
transform(fb.qs)
{init();}
World() = delete;
void init();
void run();
void render(vk::CommandBuffer& cb);
void cb_keyboard();
void modelview_update();
pVulkan_Helper& vh;
VFixed_Function_State_Manager ff_state;
pFrame_Timer& frame_timer;
Shapes shapes;
pVariable_Control variable_control;
pCoor light_location;
float opt_light_intensity;
GLuint gpu_buffer;
enum { MI_Eye, MI_Light, MI_Ball, MI_Ball_V, MI_COUNT } opt_move_item;
VPipeline pipe_plain;
VPipeline pipe_phong, pipe_classic;
VVertex_Buffer_Set bset_lonely, bset_sphere;
pCoor sphere_location;
float sphere_size;
pCoor eye_location;
pVect eye_direction;
pMatrix modelview;
VTransform transform;
VBufferV<Uni_Lighting> uni_light;
int bind_colors;
VBufferVV<vec4> uni_colors;
int bind_mat_color_idx;
VBufferV<vec4> uni_material_color_tri, uni_material_color_sphere;
vk::Sampler sampler;
VTexture texture_id_syllabus;
VTexture texture_id_image;
int opt_method;
bool opt_recompute;
int opt_shader;
};
void
World::init()
{
vh.init();
vh.opt_record_every_time = true;
vh.display_cb_set([&](){});
vh.cbs_cmd_record.push_back( [&](vk::CommandBuffer& cb){ render(cb); });
frame_timer.work_unit_set("Steps / s");
gpu_buffer = 0;
opt_method = 0;
opt_recompute = false;
uni_light.init(vh.qs,vk::BufferUsageFlagBits::eUniformBuffer);
eye_location = pCoor(2.6,0.5,9);
eye_direction = pVect(0,0,-1);
opt_light_intensity = 7.2;
light_location = pCoor(7,4.0,-0.3);
sphere_location = pCoor(0,0,-5);
sphere_size = 5;
variable_control.insert(opt_light_intensity,"Light Intensity");
opt_move_item = MI_Light;
texture_id_syllabus.init( vh.qs, P_Image_Read("gpup.png",255) );
texture_id_image.init( vh.qs, P_Image_Read("mult.png",-1) );
sampler = vh.qs.dev.createSampler
( { {},
vk::Filter::eLinear, vk::Filter::eLinear,
vk::SamplerMipmapMode::eLinear,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
vk::SamplerAddressMode::eRepeat,
0.0f,
false, 16.0f,
false,
vk::CompareOp::eNever,
0.0f, VK_LOD_CLAMP_NONE, vk::BorderColor::eFloatOpaqueBlack } );
uni_material_color_tri = color_gray;
uni_material_color_sphere = color_cadet_blue;
for ( auto umc: { &uni_material_color_tri, &uni_material_color_sphere } )
{
umc->init(vh.dev_phys, vh.dev, vk::BufferUsageFlagBits::eUniformBuffer );
umc->to_dev();
}
uni_colors.vals =
{ color_red,
color_green,
color_blue,
color_black,
color_khaki,
color_lemon_chiffon,
color_dark_olive_green,
color_olive_drab,
color_yellow_green,
color_green_yellow,
color_light_green,
color_forest_green,
color_lime_green,
color_pale_green,
color_dark_sea_green,
color_sea_green,
color_medium_sea_green,
color_light_sea_green,
color_medium_aquamarine,
color_aquamarine,
color_dark_cyan,
color_medium_turquoise,
color_turquoise,
color_pale_turquoise,
color_powder_blue,
color_light_blue,
color_sky_blue,
color_light_sky_blue,
color_cadet_blue,
color_steel_blue,
color_deep_pink,
color_hot_pink,
color_pink,
color_dark_slate_gray,
color_slate_gray };
uni_colors.init
(vh.dev_phys, vh.dev, vk::BufferUsageFlagBits::eStorageBuffer );
uni_colors.to_dev();
pipe_plain
.init( vh.qs )
.texture_on()
.color_uniform()
.use_uni_light( uni_light )
.topology_set( vk::PrimitiveTopology::eTriangleStrip )
.create();
pipe_classic
.init( vh.qs )
.texture_on()
.color_uniform()
.storage_bind( *uni_colors, "BIND_COLORS")
.use_uni_light( uni_light )
.shader_inputs_info_set<pCoor,pNorm,pTCoor>()
.shader_code_set
("demo-09-shdr-code.cc",
"vs_main_classic();", nullptr, "fs_main_classic();")
.topology_set( vk::PrimitiveTopology::eTriangleStrip )
.create();
pipe_phong
.init( vh.qs )
.texture_on()
.uniform_bind( bind_mat_color_idx, "BIND_MAT_COLOR")
.use_uni_light( uni_light )
.shader_inputs_info_set<pCoor,pNorm,pTCoor>()
.shader_code_set
("demo-09-shdr-code.cc",
"vs_main_phong();", nullptr, "fs_main_phong();" )
.topology_set( vk::PrimitiveTopology::eTriangleStrip )
.create();
opt_shader = 0;
modelview_update();
}
void
World::modelview_update()
{
pMatrix_Translate center_eye(-eye_location);
pMatrix_Rotation rotate_eye(eye_direction,pVect(0,0,-1));
modelview = rotate_eye * center_eye;
}
void
World::run()
{
vh.message_loop_spin();
uni_light.destroy();
uni_material_color_sphere.destroy();
uni_material_color_tri.destroy();
uni_colors.destroy();
pipe_plain.destroy();
pipe_classic.destroy();
pipe_phong.destroy();
bset_sphere.destroy();
bset_lonely.destroy();
texture_id_syllabus.destroy();
texture_id_image.destroy();
vh.dev.destroySampler(sampler);
shapes.destroy();
vh.finish();
}
void
World::render(vk::CommandBuffer& cb)
{
cb_keyboard();
vh.fbprintf("%s\n",frame_timer.frame_rate_text_get());
VPipeline *ppipe = nullptr;
const char *label = nullptr;
bool use_uni_mat = false;
switch ( opt_shader ) {
case 0:
ppipe = &pipe_plain;
label = "Plain";
break;
case 1:
ppipe = &pipe_phong;
label = "Phong";
use_uni_mat = true;
break;
case 2:
ppipe = &pipe_classic;
label = "Classic";
break;
default:
assert(false);
}
VPipeline& pipe = *ppipe;
vh.fbprintf
("Eye location: [%5.1f, %5.1f, %5.1f] "
"Eye direction: [%+.2f, %+.2f, %+.2f]\n",
eye_location.x, eye_location.y, eye_location.z,
eye_direction.x, eye_direction.y, eye_direction.z);
pVariable_Control_Elt* const cvar = variable_control.current;
vh.fbprintf("VAR %s = %.5f (TAB or '`' to change, +/- to adjust)\n",
cvar->name,cvar->var[0]);
vh.fbprintf
("Light location: [%5.1f, %5.1f, %5.1f] "
"Sphere Location[%5.1f, %5.1f, %5.1f]\n",
light_location.x, light_location.y, light_location.z,
sphere_location.x, sphere_location.y, sphere_location.z
);
vh.fbprintf("Shader: %s (v TO CHANGE)\n", label);
const int win_width = vh.get_width();
const int win_height = vh.get_height();
const float aspect = float(win_width) / win_height;
transform.eye_from_global_set( modelview );
transform.clip_from_eye_set
( pMatrix_Scale(1,-1,1)
* pMatrix_Frustum(-.8,.8,-.8/aspect,.8/aspect,1,5000) );
pColor white(1,1,1);
pColor red(1,0,0);
pColor gray(0x303030);
pColor dark(0);
pColor ambient_color(0x111111);
auto& light0 = uni_light->cgl_LightSource[0];
uni_light->cgl_LightModel.ambient = ambient_color;
light0.diffuse = opt_light_intensity * color_white;
light0.position = transform.eye_from_global * light_location;
light0.constantAttenuation = 0;
light0.linearAttenuation = 1;
light0.quadraticAttenuation = 0.25;
light0.ambient = color_black;
uni_light.to_dev();
pColor color_tri(0x7815b6);
if ( !bset_lonely )
{
bset_lonely.reset( pipe );
pCoor p1( 9, 6, -7 );
pCoor p2( 0, 5, -3 );
pCoor p3( 9.5, -5, -1.2 );
pNorm triangle_normal = cross(p1,p2,p3);
bset_lonely << triangle_normal << pTCoor( 1.00, 1.0 ) << p3
<< triangle_normal << pTCoor( 1.00, 0.0 ) << p1
<< triangle_normal << pTCoor( 0.00, 0.0 ) << p2;
bset_lonely.to_dev();
}
if ( use_uni_mat )
pipe.uniform_bind( bind_mat_color_idx, uni_material_color_tri );
else
pipe.color_uniform_set( color_tri );
pipe.use_texture(sampler, texture_id_syllabus );
transform.use_global_for( pipe );
pipe.record_draw( cb, bset_lonely );
if ( !bset_sphere )
{
bset_sphere.reset( pipe );
const int slices = 40;
const float tpii = 1 / ( 2 * M_PI );
const float delta_eta = M_PI / slices;
for ( int i=0; i<slices; i++ )
{
const float eta0 = i * delta_eta;
const float eta1 = eta0 + delta_eta;
const float y0 = cosf(eta0), y1 = cosf(eta1);
const float slice_r0 = sinf(eta0), slice_r1 = max(0.0f,sinf(eta1));
const float t0 = eta0 / M_PI, t1 = eta1 / M_PI;
const float delta_theta = delta_eta;
for ( int j=0; j<=2*slices; j++ )
{
const float theta = j * delta_theta;
const float theta1 = theta + delta_theta;
pVect n0( slice_r0 * sinf(theta1), y0, slice_r0 * cosf(theta1) );
bset_sphere << n0 << pTCoor( 1 - theta1 * tpii, t0 ) << pCoor(n0);
pVect n1( slice_r1 * sinf(theta1), y1, slice_r1 * cosf(theta1) );
bset_sphere << n1 << pTCoor( 1 - theta1 * tpii, t1 ) << pCoor(n1);
}
}
bset_sphere.to_dev();
}
if ( use_uni_mat )
pipe.uniform_bind( bind_mat_color_idx, uni_material_color_sphere );
else
pipe.color_uniform_set( color_lsu_spirit_gold );
pipe.use_texture(sampler, texture_id_image );
transform.global_from_local_set_for
( pMatrix_Translate( sphere_location )
* pMatrix_Scale(sphere_size)
* pMatrix_Rotation( pVect(0,1,0), M_PI / 3 ),
pipe );
pipe.record_draw( cb, bset_sphere );
if ( opt_recompute )
{
bset_sphere.reset(pipe);
}
shapes.record_tetrahedron(cb,transform,light_location,0.5);
}
void
World::cb_keyboard()
{
const int key = vh.keyboard_key_get();
if ( !key ) return;
pVect adjustment(0,0,0);
pVect user_rot_axis(0,0,0);
const bool kb_mod_s = vh.keyboard_shift;
const bool kb_mod_c = vh.keyboard_control;
const float move_amt = kb_mod_s ? 2.0 : kb_mod_c ? 0.08 : 0.4;
switch ( key ) {
case FB_KEY_LEFT: adjustment.x = -move_amt; break;
case FB_KEY_RIGHT: adjustment.x = move_amt; break;
case FB_KEY_PAGE_UP: adjustment.y = move_amt; break;
case FB_KEY_PAGE_DOWN: adjustment.y = -move_amt; break;
case FB_KEY_DOWN: adjustment.z = move_amt; break;
case FB_KEY_UP: adjustment.z = -move_amt; break;
case FB_KEY_DELETE: user_rot_axis.y = 1; break;
case FB_KEY_INSERT: user_rot_axis.y = -1; break;
case FB_KEY_HOME: user_rot_axis.x = 1; break;
case FB_KEY_END: user_rot_axis.x = -1; break;
case 'v': case 'V': opt_shader++; if ( opt_shader == 3 ) opt_shader = 0;
break;
case 's': case 'S': opt_move_item = MI_Ball; break;
case 'e': case 'E': opt_move_item = MI_Eye; break;
case 'l': case 'L': opt_move_item = MI_Light; break;
case 'r': case 'R': opt_recompute = !opt_recompute; break;
case FB_KEY_TAB:
if ( !kb_mod_s ) { variable_control.switch_var_right(); break; }
case 96: variable_control.switch_var_left(); break;
case '-':case '_': variable_control.adjust_lower(); break;
case '+':case '=': variable_control.adjust_higher(); break;
default: printf("Unknown key, %d\n",key); break;
}
if ( user_rot_axis.x || user_rot_axis.y )
{
pMatrix_Rotation rotall(eye_direction,pVect(0,0,-1));
user_rot_axis *= invert(rotall);
eye_direction *= pMatrix_Rotation(user_rot_axis, M_PI * 0.03);
modelview_update();
}
if ( adjustment.x || adjustment.y || adjustment.z )
{
const double angle =
fabs(eye_direction.y) > 0.99
? 0 : atan2(eye_direction.x,-eye_direction.z);
pMatrix_Rotation rotall(pVect(0,1,0),-angle);
adjustment *= rotall;
switch ( opt_move_item ){
case MI_Light: light_location += adjustment; break;
case MI_Eye: eye_location += adjustment; break;
case MI_Ball: sphere_location += adjustment; break;
default: break;
}
modelview_update();
}
}
int
main(int argv, char **argc)
{
pVulkan_Helper pvulkan_helper(argv,argc);
World world(pvulkan_helper);
world.run();
return 0;
}