gen2brain/raylib-go

Misleading use of color type RGBA.

Closed this issue · 2 comments

Whether raylib's colors are alpha premultiplied or not is determined by functions like SetBlendMode.

But go's image/color package's color types embed information on whether if it's alpha premultiplied or not.

So I think using image/color's color.RGBA type is misleading since it implies that colors are alpha premultiplied.

I think more honest thing would be to declare and use custom color type with 4 uint8 instead of using go's image/color package's RGBA type.

But maybe it's too late to fix it now....

I wrote some code to demonstrate this problem

package main

import (
	rl "github.com/gen2brain/raylib-go/raylib"
	"image/color"
	"fmt"
)

func main(){
	// declare colors as interfaces
	var red color.Color
	var blue color.Color

	var alphaPremultiplay bool
	var useNRGBA bool

	// set color.NRGBA as their value
	red = color.NRGBA{255, 0, 0, 100} 
	blue = color.NRGBA{0, 0, 255, 100}

	rl.InitWindow(500, 500, "blend-issue")

	for !rl.WindowShouldClose(){
		// press 'a' to toggle blend mode between normal blend and alpha premutiply
		if rl.IsKeyPressed(rl.KeyA){ 
			alphaPremultiplay = !alphaPremultiplay
		}

		// press 'c' to toggle between color.RGBA and color.NRGBA 
		if rl.IsKeyPressed(rl.KeyC){
			useNRGBA = !useNRGBA
		}

		rl.BeginDrawing()

		rl.ClearBackground(color.RGBA{255, 255, 255, 255})

		if alphaPremultiplay{
			//also why doesn't this function accept Blend mode type?
			rl.SetBlendMode(int32(rl.BlendAlphaPremultiply)) 
		}else{
			rl.SetBlendMode(int32(rl.BlendAlpha))
		}
		
		// use image/color's conversion models to convert color interfaces' colors to desired color model
		redRGBA  := color.RGBAModel.Convert(red).(color.RGBA) 
		blueRGBA := color.RGBAModel.Convert(blue).(color.RGBA) 

		redNRGBA := color.NRGBAModel.Convert(red).(color.NRGBA)
		blueNRGBA := color.NRGBAModel.Convert(blue).(color.NRGBA)

		if useNRGBA{
			rl.DrawRectangle(
				10, 10,
				200, 200,
				color.RGBA(redNRGBA), //forcing it to apccept NRGBA
			)

			rl.DrawCircle(
				160, 150,
				100,
				color.RGBA(blueNRGBA),
			)
		}else{
			rl.DrawRectangle(
				10, 10,
				200, 200,
				redRGBA,
			)

			rl.DrawCircle(
				160, 150,
				100,
				blueRGBA,
			)
		}

		rl.DrawText(
			fmt.Sprintf("[key a] alpha premultiply : %v", alphaPremultiplay),
			10, 300,
			20,
			color.RGBA{0,0,0,255},
		)

		rl.DrawText(
			fmt.Sprintf("[key c] use nrgba color : %v", useNRGBA),
			10, 330,
			20,
			color.RGBA{0,0,0,255},
		)

		rl.EndDrawing()
	}
}

Sorry, I'm dumb and I didn't realize I could just declare something like
type RaylibColor = color.RGBA
to make it clear this type is intended for raylib.

But then again, if you don't mind, I think doing something like that in raylib-go itself would be a nice way to solve the problem I mentioned above without breaking a backward compatibility : )

Wait, I didn't realize it had it's own color type until 29ba3cc .....
Sorry, my bad.