sample mouse position from position geometry buffer

This commit is contained in:
Zack Buhman 2026-03-10 15:11:14 -05:00
parent 91d86a4f85
commit 43134dcdab
4 changed files with 145 additions and 29 deletions

View File

@ -6,11 +6,15 @@ extern "C" {
void load(const char * source_path);
void draw();
void kb_update(int up, int down, int left, int right);
void update(float lx, float ly, float rx, float ry, float tl, float tr,
void update_keyboard(int up, int down, int left, int right);
void update_mouse(int x, int y);
void update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder);
int leftshoulder, int rightshoulder,
int start);
void update(float time);
#ifdef __cplusplus
}

View File

@ -3,25 +3,36 @@ local joysticks
function init()
joysticks = love.joystick.getJoysticks()
for i, joystick in ipairs(joysticks) do
print(i, joystick:getName())
end
ffi.cdef[[
void load(const char * source_path);
void update_window(int width, int height);
void draw();
void kb_update(int kbup, int kbdown, int kbleft, int kbright);
void update(float lx, float ly, float rx, float ry, float tl, float tr,
void update_keyboard(int kbup, int kbdown, int kbleft, int kbright);
void update_mouse(int x, int y);
void update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder);
int leftshoulder, int rightshoulder,
int start);
void update(float time);
]]
local source_path = love.filesystem.getSource()
test = ffi.load(source_path .. "/test.so")
test.load(source_path)
print(love.filesystem.getWorkingDirectory())
end
local update = function(dt)
for _, joystick in ipairs(joysticks) do
local update = function(time)
test.update(time)
for joystick_index, joystick in ipairs(joysticks) do
if joystick_index >= 8 then
break
end
local lx = joystick:getGamepadAxis("leftx")
local ly = joystick:getGamepadAxis("lefty")
local rx = joystick:getGamepadAxis("rightx")
@ -38,18 +49,21 @@ local update = function(dt)
local y = joystick:isGamepadDown("y")
local leftshoulder = joystick:isGamepadDown("leftshoulder")
local rightshoulder = joystick:isGamepadDown("rightshoulder")
test.update(lx, ly, rx, ry, tl, tr,
local start = joystick:isGamepadDown("start")
--print("start", i, start)
test.update_joystick(joystick_index,
lx, ly, rx, ry, tl, tr,
up, down, left, right,
a, b, x, y,
leftshoulder, rightshoulder)
leftshoulder, rightshoulder,
start)
end
local up = love.keyboard.isDown("up")
local down = love.keyboard.isDown("down")
local left = love.keyboard.isDown("left")
local right = love.keyboard.isDown("right")
test.kb_update(up, down, left, right);
test.update_keyboard(up, down, left, right);
end
local draw = function()
@ -59,7 +73,7 @@ end
function love.run()
init()
love.timer.step()
--love.timer.step()
return function()
love.event.pump()
@ -77,14 +91,18 @@ function love.run()
width, height, flags = love.window.getMode()
test.update_window(width, height)
local dt = love.timer.step()
update(dt)
--local dt = love.timer.step()
local time = love.timer.getTime()
update(time)
draw()
local x, y = love.mouse.getPosition()
test.update_mouse(x, y)
love.graphics.present()
love.timer.sleep(0.001)
local fps = love.timer.getFPS( )
--local fps = love.timer.getFPS( )
--print(fps)
end
end

View File

@ -7,6 +7,7 @@ uniform sampler2D ColorSampler;
uniform float Linear;
uniform float Quadratic;
uniform vec3 Eye;
uniform vec3 MousePosition;
layout (location = 0) out vec4 Color;
@ -37,7 +38,8 @@ void main()
}
vec3 light_direction = normalize(Eye.xyz - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (floor(MousePosition + 0.5) == floor(position.xyz + 0.5))
diffuse = 1.5;
out_color = color.xyz * diffuse;
Color = vec4(out_color, 1.0);
}

View File

@ -66,6 +66,7 @@ struct lighting_location {
unsigned int quadratic;
unsigned int linear;
unsigned int eye;
unsigned int mouse_position;
unsigned int lights;
} uniform;
@ -113,6 +114,12 @@ static instance_cfg instance_cfg[region_count];
static unsigned int empty_vertex_array_object = -1;
static unsigned int quad_index_buffer = -1;
static XMFLOAT3 mouse_position;
static bool mouse_position_sample = true;
static float current_time;
static float last_frame_time;
void load_quad_index_buffer()
{
uint8_t const data[] = {
@ -191,6 +198,7 @@ void load_lighting_program()
lighting_location.uniform.quadratic = glGetUniformLocation(program, "Quadratic");
lighting_location.uniform.linear = glGetUniformLocation(program, "Linear");
lighting_location.uniform.eye = glGetUniformLocation(program, "Eye");
lighting_location.uniform.mouse_position = glGetUniformLocation(program, "MousePosition");
lighting_location.uniform.lights = glGetUniformBlockIndex(program, "Lights");
fprintf(stderr, "lighting program:\n");
@ -641,17 +649,22 @@ light_parameters lighting = {
.linear = 1.0
};
void kb_update(int up, int down, int left, int right)
void update_keyboard(int up, int down, int left, int right)
{
XMVECTOR normal = XMVector3NormalizeEst(XMVector3Cross(view_state.forward, view_state.up));
view_state.eye += view_state.forward * (0.1f * up + -0.1f * down);
view_state.eye += normal * (-0.1f * left + 0.1f * right);
}
void update(float lx, float ly, float rx, float ry, float tl, float tr,
const int max_joysticks = 8;
static int last_frame_start[max_joysticks] = {};
void update_joystick(int joystick_index,
float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right,
int a, int b, int x, int y,
int leftshoulder, int rightshoulder)
int leftshoulder, int rightshoulder,
int start)
{
//view_state.yaw += rx;
XMMATRIX mrz = XMMatrixRotationZ(rx * -0.035);
@ -685,6 +698,16 @@ void update(float lx, float ly, float rx, float ry, float tl, float tr,
if (rightshoulder) {
load_line_point_from_eye(1);
}
if (start && (start != last_frame_start[joystick_index])) {
mouse_position_sample = !mouse_position_sample;
printf("mouse_position_sample: %d\n", mouse_position_sample);
}
last_frame_start[joystick_index] = start;
}
void update(float time)
{
current_time = time;
}
static inline int popcount(int x)
@ -715,6 +738,37 @@ inline static float draw_vector(font::font const& ter_best, char * const buf, fl
return y;
}
static int average_init = 0;
static int average_ix = 0;
static float rolling_sum = 0;
static float averages[16] = {};
const int frame_warmup = 10;
float update_average(float value)
{
if (average_init < frame_warmup) {
average_init += 1;
return 0.0f;
}
if (average_init == frame_warmup) {
assert(average_ix == 0);
rolling_sum = value * 16.0f;
for (int i = 0; i < 16; i++) {
averages[i] = value;
}
average_init += 1;
} else {
rolling_sum -= averages[average_ix];
rolling_sum += value;
averages[average_ix] = value;
average_ix = (average_ix + 1) % 16;
}
return rolling_sum * (1.0f / 16.0f);
}
void draw_hud()
{
char buf[512];
@ -748,6 +802,13 @@ void draw_hud()
labeled_value<float>(buf, "pitch: ", "%.9f", view_state.pitch);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
XMVECTOR position = XMLoadFloat3(&mouse_position);
y = draw_vector(ter_best, buf, y, "mouse_position", position);
labeled_value<float>(buf, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
}
XMMATRIX current_view_projection()
@ -872,6 +933,7 @@ void draw_lighting()
XMFLOAT3 eye;
XMStoreFloat3(&eye, view_state.eye);
glUniform3fv(lighting_location.uniform.eye, 1, (float*)&eye);
glUniform3fv(lighting_location.uniform.mouse_position, 1, (float*)&mouse_position);
glBindBufferBase(GL_UNIFORM_BUFFER, lighting_location.binding.lights, light_uniform_buffer);
@ -912,6 +974,34 @@ void draw_line()
glDrawElementsInstanced(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count);
}
int clamp(int n, int high)
{
if (n < 0)
return 0;
if (n >= high)
return high;
return n;
}
void update_mouse(int x, int y)
{
if (!mouse_position_sample)
return;
glBindFramebuffer(GL_READ_FRAMEBUFFER, geometry_buffer_pnc.framebuffer);
glReadBuffer(geometry_buffer_pnc_types[target_name::POSITION].attachment);
x = clamp(x, geometry_buffer_pnc.width);
y = clamp(y, geometry_buffer_pnc.height);
glReadPixels(x,
geometry_buffer_pnc.height - y,
1, // width
1, // height
GL_RGB,
GL_FLOAT,
(void*)&mouse_position);
}
void draw()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@ -929,4 +1019,6 @@ void draw()
draw_lighting();
//draw_quad();
draw_hud();
last_frame_time = current_time;
}