Files
Fable3D/my3dengine/shader.py
2026-02-04 21:31:57 +01:00

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)