Skip to content

[rlgl] Drawing triangles breaks rendering when using more than one texture #5142

@MilesVII

Description

@MilesVII

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)
Image

When drawing in QUADS mode (as expected)
Image
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:
Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions