-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Issue description
When drawing textured triangles with rlTexCoord2f
and rlVertex2f
functions from rlgl
as in textured polygon example, after setting the second texture, every following drawing in the frame has texcoords and vertices corrupted, including those made with rshapes
and rtextures
rlDraw* functions.
Environment
Desktop, Win10 22H2, OpenGL 4.6, tested on two devices
Issue Screenshots
When drawing in TRIANGLES mode (broken)
When drawing in QUADS mode (as expected)
The fox and background are drawn before the tiles. When rendered after the tiles, the fox sprite gets corrupted too. Black tiles are drawn before the red ones, and only the red ones are broken
Minimal example; triangles vs quads, blue tile is drawn after the red one:
Code Example
I prepared a minimal example in Odin (repo), can port to C if needed
package main
import rl "vendor:raylib"
import rlgl "vendor:raylib/rlgl"
SIZE := [2]f32 { 50, 50 }
ORIGIN_A := [2]f32 { 50, 75 }
ORIGIN_B := [2]f32 { 100, 75 }
main :: proc() {
rl.SetTraceLogLevel(.WARNING)
rl.InitWindow(200, 200, "fops")
defer rl.CloseWindow()
rl.SetTargetFPS(60)
texA := rl.LoadTexture("./a.png")
texB := rl.LoadTexture("./b.png")
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.ClearBackground(rl.WHITE)
// the goal is to draw two textures by specifying their vertices
buggyTriangles(texA, texB)
// niceQuads(texA, texB)
rl.EndDrawing()
}
}
buggyTriangles :: proc(texA: rl.Texture2D, texB: rl.Texture2D) {
rlgl.Begin(rlgl.TRIANGLES)
rlgl.Color4ub(255, 255, 255, 255)
draw(texA, ORIGIN_A, SIZE, true) // first call always works fine
draw(texB, ORIGIN_B, SIZE, true) // the second one is always bad
rlgl.End()
rlgl.SetTexture(0)
// doesn't matter how batch is managed, drawing stuff in separate begin/end pairs doesn't help
// textures must be different to fail, but the order doesn't matter
}
niceQuads :: proc(texA: rl.Texture2D, texB: rl.Texture2D) {
rlgl.Begin(rlgl.QUADS)
rlgl.Color4ub(255, 255, 255, 255)
draw(texA, ORIGIN_A, SIZE, false)
draw(texB, ORIGIN_B, SIZE, false)
rlgl.End()
rlgl.SetTexture(0)
}
draw :: proc(tex: rl.Texture2D, origin: [2]f32, size: [2]f32, useTriangles: bool) {
vertesex := [4][2]f32 {
origin + { 0, 0 } * size,
origin + { 0, 1 } * size,
origin + { 1, 1 } * size,
origin + { 1, 0 } * size
}
uv := [4][2]f32 {
{ 0, 0 },
{ 0, 1 },
{ 1, 1 },
{ 1, 0 }
}
// indices are used to pick texcoords and vertices data
// when drawing with .TRIANGLES set, 3x2 vertices are used
trindesex := []int {
1, 2, 0,
2, 3, 0
}
// when drawing with .QUADS set, just 4 vertices are used
quindesex := []int {
0, 1, 2, 3
}
rlgl.SetTexture(tex.id)
for i in (useTriangles ? trindesex : quindesex) {
rlgl.TexCoord2f(uv[i].x, uv[i].y)
rlgl.Vertex2f(vertesex[i].x, vertesex[i].y)
}
}
Backstory
Basically, I just needed to draw a tilemap. The only reason I had to resort to drawing with rlgl was that I needed to draw tiles by specifying vertices instead of tile size in order to guarantee that adjacent corners have same vertices, otherwise there would be tearing visible in some camera positions due to rounding errors. There is no rectangle drawing function in rshapes
that can do that, and none of triangle drawing functions I tried align texture coordinates correctly when drawing a quad.
It would be nice to have a rectangle drawing function in rshapes
and a texture drawing function in rtextures
that accept vertex coordinates like rlDrawTriangle
, also an option to specify texcoords for each vertex when drawing triangles and, ideally, triangle fans would be really useful too