#![cfg(feature = "software_renderer")]
use raylib::prelude::*;
#[test]
fn rlgl_immediate_triangle_renders() {
raylib::test_harness::with_headless(100, 100, |rl, thread| {
let img_raw = raylib::test_harness::render_frame(rl, thread, |d| {
let _ = d;
d.clear_background(Color::BLACK);
unsafe {
let tex = raylib::ffi::GetShapesTexture();
let tw = tex.width as f32;
let th = tex.height as f32;
let rect = raylib::ffi::GetShapesTextureRectangle();
raylib::ffi::rlSetTexture(tex.id);
raylib::ffi::rlBegin(raylib::ffi::RL_QUADS as i32);
raylib::ffi::rlNormal3f(0.0, 0.0, 1.0);
raylib::ffi::rlColor4ub(255, 0, 0, 255);
raylib::ffi::rlTexCoord2f(rect.x / tw, rect.y / th);
raylib::ffi::rlVertex2f(20.0, 20.0);
raylib::ffi::rlTexCoord2f(rect.x / tw, (rect.y + rect.height) / th);
raylib::ffi::rlVertex2f(20.0, 80.0);
raylib::ffi::rlTexCoord2f((rect.x + rect.width) / tw, (rect.y + rect.height) / th);
raylib::ffi::rlVertex2f(80.0, 80.0);
raylib::ffi::rlTexCoord2f((rect.x + rect.width) / tw, rect.y / th);
raylib::ffi::rlVertex2f(80.0, 20.0);
raylib::ffi::rlEnd();
raylib::ffi::rlSetTexture(0);
}
});
let red_raw = count_red(&img_raw, 0, 100, 0, 100);
println!("baseline raw FFI quads: {red_raw} red px");
assert!(red_raw > 100, "baseline raw FFI failed: {red_raw}");
let img_safe_nodraw = raylib::test_harness::render_frame(rl, thread, |d| {
d.clear_background(Color::BLACK);
unsafe {
let tex = raylib::ffi::GetShapesTexture();
let tw = tex.width as f32;
let th = tex.height as f32;
let rect = raylib::ffi::GetShapesTextureRectangle();
raylib::ffi::rlSetTexture(tex.id);
let mut v = d.rl_begin(DrawMode::Quads);
v.normal3f(0.0, 0.0, 1.0);
v.color4ub(Color::RED);
v.texcoord2f(rect.x / tw, rect.y / th);
v.vertex2f(20.0, 20.0);
v.texcoord2f(rect.x / tw, (rect.y + rect.height) / th);
v.vertex2f(20.0, 80.0);
v.texcoord2f((rect.x + rect.width) / tw, (rect.y + rect.height) / th);
v.vertex2f(80.0, 80.0);
v.texcoord2f((rect.x + rect.width) / tw, rect.y / th);
v.vertex2f(80.0, 20.0);
drop(v); raylib::ffi::rlSetTexture(0);
}
});
let red_safe_nodraw = count_red(&img_safe_nodraw, 0, 100, 0, 100);
println!("safe rl_begin (no matrix): {red_safe_nodraw} red px");
assert!(
red_safe_nodraw > 100,
"safe rl_begin (no matrix) failed: {red_safe_nodraw}"
);
let img_push = raylib::test_harness::render_frame(rl, thread, |d| {
d.clear_background(Color::BLACK);
unsafe {
let tex = raylib::ffi::GetShapesTexture();
let tw = tex.width as f32;
let th = tex.height as f32;
let rect = raylib::ffi::GetShapesTextureRectangle();
raylib::ffi::rlSetTexture(tex.id);
{
let mut m = d.rl_push_matrix();
m.rl_translatef(30.0, 0.0, 0.0);
m.rl_draw(DrawMode::Quads, |v| {
v.normal3f(0.0, 0.0, 1.0);
v.color4ub(Color::RED);
v.texcoord2f(rect.x / tw, rect.y / th);
v.vertex2f(20.0, 20.0);
v.texcoord2f(rect.x / tw, (rect.y + rect.height) / th);
v.vertex2f(20.0, 50.0);
v.texcoord2f((rect.x + rect.width) / tw, (rect.y + rect.height) / th);
v.vertex2f(50.0, 50.0);
v.texcoord2f((rect.x + rect.width) / tw, rect.y / th);
v.vertex2f(50.0, 20.0);
});
}
raylib::ffi::rlSetTexture(0);
}
});
let red_push_total = count_red(&img_push, 0, 100, 0, 100);
let red_push_box = count_red(&img_push, 50, 80, 20, 50);
println!(
"safe rl_push+translate+rl_draw: total={red_push_total} in_box=[50..80,20..50]={red_push_box}"
);
assert!(
red_push_total > 100,
"safe rl_push+rl_draw produced no pixels: {red_push_total}"
);
assert!(
red_push_box > 100,
"safe rl_push+rl_draw pixels not in expected translated region: \
total={red_push_total}, in_box={red_push_box}"
);
let img_blue = raylib::test_harness::render_frame(rl, thread, |d| {
d.clear_background(Color::BLACK);
unsafe {
let tex = raylib::ffi::GetShapesTexture();
let tw = tex.width as f32;
let th = tex.height as f32;
let rect = raylib::ffi::GetShapesTextureRectangle();
raylib::ffi::rlSetTexture(tex.id);
let mut v = d.rl_begin(DrawMode::Quads);
v.normal3f(0.0, 0.0, 1.0);
v.color4ub(Color::BLUE);
v.texcoord2f(rect.x / tw, rect.y / th);
v.vertex2f(20.0, 20.0);
v.texcoord2f(rect.x / tw, (rect.y + rect.height) / th);
v.vertex2f(20.0, 80.0);
v.texcoord2f((rect.x + rect.width) / tw, (rect.y + rect.height) / th);
v.vertex2f(80.0, 80.0);
v.texcoord2f((rect.x + rect.width) / tw, rect.y / th);
v.vertex2f(80.0, 20.0);
drop(v);
raylib::ffi::rlSetTexture(0);
}
});
let red_blue_frame = count_red(&img_blue, 0, 100, 0, 100);
let blue_px = count_blue(&img_blue, 0, 100, 0, 100);
println!("blue quad: {blue_px} blue px, {red_blue_frame} red px (should be 0)");
assert!(
blue_px > 100,
"blue quad produced no blue pixels: {blue_px}"
);
assert!(
red_blue_frame == 0,
"blue quad leaked into red counter: {red_blue_frame}"
);
});
}
fn count_red(img: &Image, x0: i32, x1: i32, y0: i32, y1: i32) -> u32 {
let mut count = 0u32;
for y in y0..y1 {
for x in x0..x1 {
let p = raylib::test_harness::pixel_at(img, x, y);
if p.r > 150 && p.g < 90 && p.b < 90 {
count += 1;
}
}
}
count
}
fn count_blue(img: &Image, x0: i32, x1: i32, y0: i32, y1: i32) -> u32 {
let mut count = 0u32;
for y in y0..y1 {
for x in x0..x1 {
let p = raylib::test_harness::pixel_at(img, x, y);
if p.b > 150 && p.r < 90 && p.g < 90 {
count += 1;
}
}
}
count
}