v/vlib/gl/1shader.v

196 lines
4.6 KiB
V
Raw Normal View History

2019-06-23 04:21:30 +02:00
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
2019-06-22 21:24:49 +02:00
module gl
2019-09-23 12:42:20 +02:00
// import os
2019-06-22 21:24:49 +02:00
import gx
import glm
// import darwin
pub struct Shader {
2019-06-22 21:24:49 +02:00
program_id int
}
pub const (
2019-06-22 21:24:49 +02: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-22 23:00:31 +02:00
{
2019-06-22 21:24:49 +02: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-22 23:00:31 +02:00
layout (location = 2) in vec2 aTexCoord;
2019-06-22 21:24:49 +02:00
out vec3 ourColor;
2019-08-22 23:00:31 +02:00
out vec2 TexCoord;
2019-06-22 21:24:49 +02:00
uniform mat4 projection;
void main() {
gl_Position = projection * vec4(aPos, 1.0);
// gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
2019-08-22 23:00:31 +02:00
//TexCoord = vec2(aTexCoord.x, aTexCoord.y);
TexCoord = aTexCoord;
2019-06-22 21:24:49 +02:00
}
'
SIMPLE_FRAG = '#version 330 core
out vec4 FragColor;
uniform vec3 color;
2019-08-22 23:00:31 +02:00
uniform bool has_texture;
2019-06-22 21:24:49 +02:00
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
2019-08-22 23:00:31 +02:00
2019-06-22 21:24:49 +02: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-22 23:00:31 +02:00
if (has_texture) {
/*
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 21:24:49 +02:00
FragColor = texture(ourTexture, TexCoord);
2019-08-22 23:00:31 +02:00
} else {
2019-06-22 21:24:49 +02:00
FragColor = vec4(color, 1.0f);
2019-08-22 23:00:31 +02:00
}
2019-06-22 21:24:49 +02:00
}
'
)
pub fn new_shader(name string) Shader {
2019-08-22 23:00:31 +02:00
// TODO This is not used, remove
mut dir := ''
2019-06-22 21:24:49 +02:00
// Already have absolute path
if name.starts_with('/') {
dir = ''
}
//vertex_path := '${dir}${name}.vert'
//fragment_path := '${dir}${name}.frag'
//println('shader path=$vertex_path,\n fpath="$fragment_path"')
2019-06-22 21:24:49 +02:00
// vertex_src := os.read_file(vertex_path.trim_space())
2019-06-28 15:24:46 +02:00
mut vertex_src := ''
mut fragment_src := ''
2019-06-22 21:24:49 +02: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-22 23:00:31 +02:00
vertex_shader := gl.create_shader(C.GL_VERTEX_SHADER)
2019-06-22 21:24:49 +02:00
gl.shader_source(vertex_shader, 1, vertex_src, 0)
gl.compile_shader(vertex_shader)
if gl.shader_compile_status(vertex_shader) == 0 {
log := gl.shader_info_log(vertex_shader)
println('shader $vertex_shader compilation failed')
println('shader source = $vertex_src')
2019-06-23 10:41:42 +02:00
println('shader failed to compile')
exit(1)
2019-06-22 21:24:49 +02:00
}
// fragment shader
// fragment_src := os.read_file(fragment_path.trim_space())
2019-08-22 23:00:31 +02:00
fragment_shader := gl.create_shader(C.GL_FRAGMENT_SHADER)
2019-06-22 21:24:49 +02:00
gl.shader_source(fragment_shader, 1, fragment_src, 0)
gl.compile_shader(fragment_shader)
if gl.shader_compile_status(fragment_shader) == 0 {
println('fragment $fragment_shader shader compilation failed')
2019-06-23 10:41:42 +02:00
println('shader failed to compile')
exit(1)
2019-06-22 21:24:49 +02: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 {
println('shader compilation failed')
println('vertex source = $vertex_src')
println('fragment source = $fragment_src')
2019-06-23 10:41:42 +02:00
println('shader failed to compile')
exit(1)
2019-06-22 21:24:49 +02:00
}
shader := Shader {
program_id: shader_program,
}
return shader
}
pub fn (s Shader) use() {
gl.use_program(s.program_id)
}
2019-11-24 04:27:02 +01:00
fn C.glGetUniformLocation() int
fn C.glUniformMatrix4fv()
fn C.glUniform1i()
fn C.glUniform3f()
2019-06-22 21:24:49 +02:00
pub fn (s Shader) uni_location(key string) int {
return C.glGetUniformLocation(s.program_id, key.str)
}
2019-06-25 21:36:44 +02:00
// fn (s Shader) set_mat4(str string, f *f32) {
2019-06-22 21:24:49 +02: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 21:36:44 +02: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 21:24:49 +02:00
}