2020-01-23 23:04:46 +03:00
|
|
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
2019-06-23 05:21:30 +03:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
|
2019-06-22 22:24:49 +03:00
|
|
|
module gl
|
|
|
|
|
2019-09-23 13:42:20 +03:00
|
|
|
// import os
|
2019-06-22 22:24:49 +03:00
|
|
|
import gx
|
|
|
|
import glm
|
|
|
|
|
|
|
|
// import darwin
|
|
|
|
|
2019-10-24 13:19:27 +03:00
|
|
|
pub struct Shader {
|
2019-06-22 22:24:49 +03:00
|
|
|
program_id int
|
|
|
|
}
|
2020-01-18 22:08:11 +03:00
|
|
|
pub fn (s Shader) str() string {
|
|
|
|
return 'Shader{ program_id: s.program_id }'
|
|
|
|
}
|
2019-06-22 22:24:49 +03:00
|
|
|
|
2019-10-24 14:35:11 +03:00
|
|
|
pub const (
|
2019-06-22 22:24:49 +03:00
|
|
|
TEXT_VERT = '#version 330 core
|
|
|
|
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
|
|
|
out vec2 TexCoords;
|
|
|
|
|
|
|
|
uniform mat4 projection;
|
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
|
|
|
TexCoords = vertex.zw;
|
|
|
|
} '
|
|
|
|
TEXT_FRAG = '#version 330 core
|
|
|
|
in vec2 TexCoords;
|
|
|
|
out vec4 color;
|
|
|
|
|
|
|
|
uniform sampler2D text;
|
|
|
|
uniform vec3 textColor;
|
|
|
|
|
|
|
|
void main()
|
2019-08-23 00:00:31 +03:00
|
|
|
{
|
2019-06-22 22:24:49 +03:00
|
|
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
|
|
|
color = vec4(textColor, 1.0) * sampled;
|
|
|
|
} '
|
|
|
|
SIMPLE_VERT = ' #version 330 core
|
|
|
|
|
|
|
|
layout (location = 0) in vec3 aPos;
|
|
|
|
layout (location = 1) in vec3 aColor;
|
2019-08-23 00:00:31 +03:00
|
|
|
layout (location = 2) in vec2 aTexCoord;
|
2019-06-22 22:24:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
out vec3 ourColor;
|
2019-08-23 00:00:31 +03:00
|
|
|
out vec2 TexCoord;
|
2019-06-22 22:24:49 +03:00
|
|
|
|
|
|
|
uniform mat4 projection;
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
gl_Position = projection * vec4(aPos, 1.0);
|
|
|
|
// gl_Position = vec4(aPos, 1.0);
|
|
|
|
|
|
|
|
ourColor = aColor;
|
2019-08-23 00:00:31 +03:00
|
|
|
//TexCoord = vec2(aTexCoord.x, aTexCoord.y);
|
|
|
|
TexCoord = aTexCoord;
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
'
|
|
|
|
SIMPLE_FRAG = '#version 330 core
|
|
|
|
|
|
|
|
out vec4 FragColor;
|
|
|
|
uniform vec3 color;
|
|
|
|
|
2019-08-23 00:00:31 +03:00
|
|
|
uniform bool has_texture;
|
2019-06-22 22:24:49 +03:00
|
|
|
|
|
|
|
in vec3 ourColor;
|
|
|
|
in vec2 TexCoord;
|
|
|
|
|
|
|
|
uniform sampler2D ourTexture;
|
2019-08-23 00:00:31 +03:00
|
|
|
|
2019-06-22 22:24:49 +03:00
|
|
|
|
|
|
|
void main() {
|
|
|
|
// FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
|
|
|
// FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
2019-08-23 00:00:31 +03:00
|
|
|
if (has_texture) {
|
2020-01-09 14:00:39 +03:00
|
|
|
/*
|
|
|
|
vec3 chromaKeyColor = texture(ourTexture,TexCoord.xy).xyz;
|
|
|
|
|
|
|
|
float alpha;
|
|
|
|
bool is_cyan = ((chromaKeyColor.x == 0)); // && chromaKeyColor.x <= 1) && (chromaKeyColor.y <= 255) &&
|
|
|
|
bool is_pink= ((chromaKeyColor.y == 0));
|
|
|
|
//bool is_pink= ((chromaKeyColor.x <= 255) && (chromaKeyColor.y == 0) &&(chromaKeyColor.z <= 255));
|
|
|
|
if (is_cyan || is_pink) {
|
|
|
|
alpha = 0.;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
alpha = 1.0;
|
|
|
|
}
|
|
|
|
FragColor= vec4(texture(ourTexture,TexCoord.xy).xyz,alpha);
|
|
|
|
*/
|
|
|
|
|
2019-06-22 22:24:49 +03:00
|
|
|
FragColor = texture(ourTexture, TexCoord);
|
2019-08-23 00:00:31 +03:00
|
|
|
|
|
|
|
} else {
|
2019-06-22 22:24:49 +03:00
|
|
|
FragColor = vec4(color, 1.0f);
|
2019-08-23 00:00:31 +03:00
|
|
|
}
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
'
|
|
|
|
)
|
|
|
|
|
|
|
|
pub fn new_shader(name string) Shader {
|
2019-08-23 00:00:31 +03:00
|
|
|
// TODO This is not used, remove
|
|
|
|
mut dir := ''
|
2019-06-22 22:24:49 +03:00
|
|
|
// Already have absolute path
|
|
|
|
if name.starts_with('/') {
|
|
|
|
dir = ''
|
|
|
|
}
|
2019-12-06 15:24:53 +03:00
|
|
|
//vertex_path := '${dir}${name}.vert'
|
|
|
|
//fragment_path := '${dir}${name}.frag'
|
2019-07-10 14:27:35 +03:00
|
|
|
//println('shader path=$vertex_path,\n fpath="$fragment_path"')
|
2019-06-22 22:24:49 +03:00
|
|
|
// vertex_src := os.read_file(vertex_path.trim_space())
|
2019-06-28 16:24:46 +03:00
|
|
|
mut vertex_src := ''
|
|
|
|
mut fragment_src := ''
|
2019-06-22 22:24:49 +03:00
|
|
|
if name == 'text' {
|
|
|
|
vertex_src = TEXT_VERT
|
|
|
|
fragment_src = TEXT_FRAG
|
|
|
|
}
|
|
|
|
else if name == 'simple' {
|
|
|
|
// println('new shader simple!!!')
|
|
|
|
// println(SIMPLE_VERT)
|
|
|
|
vertex_src = SIMPLE_VERT
|
|
|
|
fragment_src = SIMPLE_FRAG
|
|
|
|
}
|
|
|
|
// ////////////////////////////////////////
|
2019-08-23 00:00:31 +03:00
|
|
|
vertex_shader := gl.create_shader(C.GL_VERTEX_SHADER)
|
2019-06-22 22:24:49 +03:00
|
|
|
gl.shader_source(vertex_shader, 1, vertex_src, 0)
|
|
|
|
gl.compile_shader(vertex_shader)
|
|
|
|
if gl.shader_compile_status(vertex_shader) == 0 {
|
2020-04-25 09:48:58 +03:00
|
|
|
cerror := gl.shader_info_log(vertex_shader)
|
|
|
|
eprintln('vertex ${vertex_shader} shader compilation failed')
|
|
|
|
eprintln('shader source = ${vertex_src}')
|
|
|
|
eprintln('failed to compile, with error')
|
|
|
|
eprintln(cerror)
|
2019-06-23 11:41:42 +03:00
|
|
|
exit(1)
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
// fragment shader
|
|
|
|
// fragment_src := os.read_file(fragment_path.trim_space())
|
2019-08-23 00:00:31 +03:00
|
|
|
fragment_shader := gl.create_shader(C.GL_FRAGMENT_SHADER)
|
2019-06-22 22:24:49 +03:00
|
|
|
gl.shader_source(fragment_shader, 1, fragment_src, 0)
|
|
|
|
gl.compile_shader(fragment_shader)
|
|
|
|
if gl.shader_compile_status(fragment_shader) == 0 {
|
2020-04-25 09:48:58 +03:00
|
|
|
cerror := gl.shader_info_log(fragment_shader)
|
|
|
|
eprintln('fragment ${fragment_shader} shader compilation failed')
|
|
|
|
eprintln('shader source = ${fragment_src}')
|
|
|
|
eprintln('failed to compile, with error')
|
|
|
|
eprintln(cerror)
|
2019-06-23 11:41:42 +03:00
|
|
|
exit(1)
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
// link shaders
|
|
|
|
shader_program := gl.create_program()
|
|
|
|
gl.attach_shader(shader_program, vertex_shader)
|
|
|
|
gl.attach_shader(shader_program, fragment_shader)
|
|
|
|
gl.link_program(shader_program)
|
|
|
|
// check for linking errors
|
|
|
|
success := gl.get_program_link_status(shader_program)
|
|
|
|
if success == 0 {
|
2020-04-25 09:48:58 +03:00
|
|
|
cerror := gl.shader_info_log(shader_program)
|
|
|
|
eprintln('shader program linking failed')
|
|
|
|
eprintln('vertex source = ${vertex_src}')
|
|
|
|
eprintln('fragment source = ${fragment_src}')
|
|
|
|
eprintln('failed to compile, with error')
|
|
|
|
eprintln(cerror)
|
2019-06-23 11:41:42 +03:00
|
|
|
exit(1)
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
shader := Shader {
|
|
|
|
program_id: shader_program,
|
|
|
|
}
|
|
|
|
return shader
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (s Shader) use() {
|
|
|
|
gl.use_program(s.program_id)
|
|
|
|
}
|
|
|
|
|
2019-11-24 06:27:02 +03:00
|
|
|
fn C.glUniformMatrix4fv()
|
|
|
|
fn C.glUniform1i()
|
|
|
|
fn C.glUniform3f()
|
|
|
|
|
2019-06-22 22:24:49 +03:00
|
|
|
pub fn (s Shader) uni_location(key string) int {
|
|
|
|
return C.glGetUniformLocation(s.program_id, key.str)
|
|
|
|
}
|
|
|
|
|
2019-06-25 22:36:44 +03:00
|
|
|
// fn (s Shader) set_mat4(str string, f *f32) {
|
2019-06-22 22:24:49 +03:00
|
|
|
pub fn (s Shader) set_mat4(str string, m glm.Mat4) {
|
|
|
|
// TODO cache uniform location
|
|
|
|
C.glUniformMatrix4fv(s.uni_location(str), 1, false, m.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (s Shader) set_int(str string, n int) {
|
|
|
|
C.glUniform1i(s.uni_location(str), n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (s Shader) set_color(str string, c gx.Color) {
|
2019-06-25 22:36:44 +03:00
|
|
|
C.glUniform3f(s.uni_location(str), f32(c.r) / 255.0, f32(c.g) / 255.0, f32(c.b) / 255.0)
|
2019-06-22 22:24:49 +03:00
|
|
|
}
|
|
|
|
|