132 lines
3.2 KiB
Python
132 lines
3.2 KiB
Python
from OpenGL.GL import *
|
|
|
|
ui_vertex_src = """
|
|
#version 330 core
|
|
layout(location = 0) in vec2 aPos;
|
|
layout(location = 1) in vec2 aUV;
|
|
|
|
out vec2 vUV;
|
|
|
|
void main() {
|
|
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
vUV = aUV;
|
|
}
|
|
"""
|
|
|
|
ui_fragment_src = """
|
|
#version 330 core
|
|
in vec2 vUV;
|
|
uniform sampler2D uTexture;
|
|
uniform vec4 uColor;
|
|
uniform int useTexture;
|
|
out vec4 FragColor;
|
|
|
|
void main() {
|
|
if (useTexture == 1)
|
|
FragColor = texture(uTexture, vUV) * uColor;
|
|
else
|
|
FragColor = uColor;
|
|
}
|
|
"""
|
|
|
|
basic_vertex_src = """
|
|
#version 330 core
|
|
layout(location = 0) in vec3 aPos;
|
|
layout(location = 1) in vec3 aColor;
|
|
layout(location = 2) in vec2 aUV;
|
|
|
|
uniform mat4 uModel;
|
|
uniform mat4 uView;
|
|
uniform mat4 uProjection;
|
|
|
|
uniform vec2 uUVTiling;
|
|
uniform vec2 uUVOffset;
|
|
|
|
out vec3 vColor;
|
|
out vec2 vUV;
|
|
|
|
void main() {
|
|
gl_Position = uProjection * uView * uModel * vec4(aPos, 1.0);
|
|
vColor = aColor;
|
|
vUV = aUV * uUVTiling + uUVOffset;
|
|
}
|
|
"""
|
|
|
|
basic_fragment_src = """
|
|
#version 330 core
|
|
in vec3 vColor;
|
|
in vec2 vUV;
|
|
uniform sampler2D uTexture;
|
|
uniform int useTexture;
|
|
out vec4 FragColor;
|
|
|
|
void main() {
|
|
if (useTexture == 1)
|
|
FragColor = texture(uTexture, vUV);
|
|
else
|
|
FragColor = vec4(vColor, 1.0);
|
|
}
|
|
"""
|
|
|
|
def compile_shader(src, shader_type):
|
|
shader = glCreateShader(shader_type)
|
|
glShaderSource(shader, src)
|
|
glCompileShader(shader)
|
|
|
|
if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
|
|
error = glGetShaderInfoLog(shader).decode()
|
|
raise RuntimeError(f"Shader compile error: {error}")
|
|
return shader
|
|
|
|
def create_shader(vertex_src, fragment_src):
|
|
vert = compile_shader(vertex_src, GL_VERTEX_SHADER)
|
|
frag = compile_shader(fragment_src, GL_FRAGMENT_SHADER)
|
|
|
|
program = glCreateProgram()
|
|
glAttachShader(program, vert)
|
|
glAttachShader(program, frag)
|
|
glLinkProgram(program)
|
|
|
|
if glGetProgramiv(program, GL_LINK_STATUS) != GL_TRUE:
|
|
error = glGetProgramInfoLog(program).decode()
|
|
raise RuntimeError(f"Program link error: {error}")
|
|
|
|
glDeleteShader(vert)
|
|
glDeleteShader(frag)
|
|
return program
|
|
|
|
|
|
class ShaderProgram:
|
|
def __init__(self, vertex_src, fragment_src):
|
|
self.program = create_shader(vertex_src, fragment_src)
|
|
self.uniform_locations = {}
|
|
|
|
def use(self):
|
|
glUseProgram(self.program)
|
|
|
|
def get_uniform_location(self, name):
|
|
if name not in self.uniform_locations:
|
|
self.uniform_locations[name] = glGetUniformLocation(self.program, name)
|
|
return self.uniform_locations[name]
|
|
|
|
def set_uniform_1i(self, name, value):
|
|
glUniform1i(self.get_uniform_location(name), value)
|
|
|
|
def set_uniform_1f(self, name, value):
|
|
glUniform1f(self.get_uniform_location(name), value)
|
|
|
|
def set_uniform_vec2(self, name, vec):
|
|
glUniform2fv(self.get_uniform_location(name), 1, vec)
|
|
|
|
def set_uniform_vec3(self, name, vec):
|
|
glUniform3fv(self.get_uniform_location(name), 1, vec)
|
|
|
|
def set_uniform_mat4(self, name, mat, transpose=False):
|
|
glUniformMatrix4fv(self.get_uniform_location(name), 1, transpose, mat)
|
|
|
|
def create_ui_shader():
|
|
return ShaderProgram(ui_vertex_src, ui_fragment_src)
|
|
|
|
def basic_shader():
|
|
return ShaderProgram(basic_vertex_src, basic_fragment_src)
|