This commit is contained in:
agra
2026-02-22 13:22:29 +02:00
commit eba94d3c53
11 changed files with 1320 additions and 0 deletions

244
main.sx Normal file
View File

@@ -0,0 +1,244 @@
#import "modules/std.sx";
#import "modules/sdl3.sx";
#import "modules/opengl.sx";
#import "modules/math";
WIDTH :f32: 800;
HEIGHT :f32: 600;
main :: () {
print("init video: \n");
SDL_Init(SDL_INIT_VIDEO);
print("init opengl: \n");
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
print("init opengl profile: \n");
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
print("create window: \n");
window := SDL_CreateWindow("SX Game", xx WIDTH, xx HEIGHT, SDL_WINDOW_OPENGL);
gl_ctx := SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_ctx);
SDL_GL_SetSwapInterval(1);
print("load gl: \n");
load_gl(SDL_GL_GetProcAddress);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
print("create program: {}\n{}\n", VERT_SHADER_SRC, FRAG_SHADER_SRC);
program := create_program(VERT_SHADER_SRC, FRAG_SHADER_SRC);
glUseProgram(program);
print("uniform locations: \n");
mvp_loc := glGetUniformLocation(program, "uMVP");
light_loc := glGetUniformLocation(program, "uLightDir");
wire_loc := glGetUniformLocation(program, "uWire");
print("vertices\n");
// Cube vertices: pos(vec4 w=1) + normal(vec4 w=0), 36 vertices × 2 vec4s = 72
vertices : []Vector(4, f32) = .[
// Front face (z = +0.5)
.[-0.5, -0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
.[ 0.5, -0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
.[ 0.5, 0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
.[-0.5, -0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
.[ 0.5, 0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
.[-0.5, 0.5, 0.5, 1.0], .[ 0.0, 0.0, 1.0, 0.0],
// Back face (z = -0.5)
.[ 0.5, -0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
.[-0.5, -0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
.[-0.5, 0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
.[ 0.5, -0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
.[-0.5, 0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
.[ 0.5, 0.5, -0.5, 1.0], .[ 0.0, 0.0, -1.0, 0.0],
// Top face (y = +0.5)
.[-0.5, 0.5, 0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
.[ 0.5, 0.5, 0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
.[ 0.5, 0.5, -0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
.[-0.5, 0.5, 0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
.[ 0.5, 0.5, -0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
.[-0.5, 0.5, -0.5, 1.0], .[ 0.0, 1.0, 0.0, 0.0],
// Bottom face (y = -0.5)
.[-0.5, -0.5, -0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
.[ 0.5, -0.5, -0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
.[ 0.5, -0.5, 0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
.[-0.5, -0.5, -0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
.[ 0.5, -0.5, 0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
.[-0.5, -0.5, 0.5, 1.0], .[0.0, -1.0, 0.0, 0.0],
// Right face (x = +0.5)
.[ 0.5, -0.5, 0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
.[ 0.5, -0.5, -0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
.[ 0.5, 0.5, -0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
.[ 0.5, -0.5, 0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
.[ 0.5, 0.5, -0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
.[ 0.5, 0.5, 0.5, 1.0], .[1.0, 0.0, 0.0, 0.0],
// Left face (x = -0.5)
.[-0.5, -0.5, -0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0],
.[-0.5, -0.5, 0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0],
.[-0.5, 0.5, 0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0],
.[-0.5, -0.5, -0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0],
.[-0.5, 0.5, 0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0],
.[-0.5, 0.5, -0.5, 1.0], .[-1.0, 0.0, 0.0, 0.0]
];
print("cube buffer: \n");
vao : u32 = 0;
vbo : u32 = 0;
glGenVertexArrays(1, @vao);
glGenBuffers(1, @vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 1152, @vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, 0, 32, xx 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, 0, 32, xx 16);
glEnableVertexAttribArray(1);
glUniform3f(light_loc, 0.5, 0.7, 1.0);
glUniform1f(wire_loc, 0.0);
running := true;
event : SDL_Event = .none;
print("loop: \n");
while running {
while SDL_PollEvent(event) {
if event == {
case .quit: running = false;
case .key_up: (e) {
if e.key == {
case .escape: running = false;
}
}
}
}
ticks := SDL_GetTicks();
ms : f32 = xx ticks;
angle := ms * 0.001;
proj := mat4_perspective(PI/ 4.0, WIDTH / HEIGHT, 0.1, 100.0);
view := mat4_translate(0.0, 0.0, -3.0);
rot_y := mat4_rotate_y(angle);
rot_x := mat4_rotate_x(angle * 0.7);
model := mat4_multiply(rot_y, rot_x);
vm := mat4_multiply(view, model);
mvp := mat4_multiply(proj, vm);
glUniformMatrix4fv(mvp_loc, 1, 0, mvp.data);
glClearColor(0.1, 0.1, 0.15, 1.0);
glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT);
glUniform1f(wire_loc, 0.0);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(2.0);
glUniform1f(wire_loc, 1.0);
glDrawArrays(GL_TRIANGLES, 0, 36);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDepthFunc(GL_LESS);
glUniform1f(wire_loc, 0.0);
print("{}\n", ms);
SDL_GL_SwapWindow(window);
}
SDL_GL_DestroyContext(gl_ctx);
SDL_DestroyWindow(window);
SDL_Quit();
}
create_program :: (vert_src: [:0]u8, frag_src: [:0]u8) -> u32 {
vs := compile_shader(GL_VERTEX_SHADER, vert_src);
fs := compile_shader(GL_FRAGMENT_SHADER, frag_src);
prog := glCreateProgram();
glAttachShader(prog, vs);
glAttachShader(prog, fs);
glLinkProgram(prog);
status : s32 = 0;
glGetProgramiv(prog, GL_LINK_STATUS, @status);
if status == GL_FALSE {
log_buf: [512]u8 = ---;
glGetProgramInfoLog(prog, 512, null, log_buf);
print("error program link\n");
}
glDeleteShader(vs);
glDeleteShader(fs);
return prog;
}
compile_shader :: (shader_type : u32, source: [:0]u8) -> u32 {
shader : u32 = glCreateShader(shader_type);
glShaderSource(shader, 1, source, null);
glCompileShader(shader);
status : s32 = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, @status);
if status == GL_FALSE {
log_buf : [512]u8 = ---;
glGetShaderInfoLog(shader, 512, null, log_buf);
print("error compile shader\n");
}
return shader;
}
VERT_SHADER_SRC : string = #string GLSL
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 uMVP;
out vec3 vNormal;
out vec3 vPos;
void main() {
gl_Position = uMVP * vec4(aPos, 1.0);
vNormal = aNormal;
vPos = aPos;
}
GLSL;
FRAG_SHADER_SRC : string = #string GLSL
#version 330 core
in vec3 vNormal;
in vec3 vPos;
out vec4 FragColor;
uniform vec3 uLightDir;
uniform float uWire;
void main() {
if (uWire > 0.5) {
FragColor = vec4(0.05, 0.05, 0.05, 1.0);
return;
}
vec3 n = normalize(vNormal);
vec3 l = normalize(uLightDir);
float diff = max(dot(n, l), 0.15);
float cx = floor(vPos.x * 2.0 + 0.001);
float cy = floor(vPos.y * 2.0 + 0.001);
float cz = floor(vPos.z * 2.0 + 0.001);
float check = mod(cx + cy + cz, 2.0);
vec3 col1 = vec3(0.9, 0.5, 0.2);
vec3 col2 = vec3(0.2, 0.6, 0.9);
vec3 base = mix(col1, col2, check);
FragColor = vec4(base * diff, 1.0);
}
GLSL;