gl01/internal/render/screenquad.go

123 lines
3.2 KiB
Go
Raw Normal View History

package render
import (
_ "embed"
"unsafe"
"edgaru089.ml/go/gl01/internal/util/itype"
"github.com/go-gl/gl/all-core/gl"
)
var (
screenQuadVerts = []float32{
-1, -1,
0, 0,
1, -1,
1, 0,
1, 1,
1, 1,
-1, -1,
0, 0,
1, 1,
1, 1,
-1, 1,
0, 1,
}
screenQuadVAO uint32
screenQuadVBO uint32
drawTextureShader *Shader // Shader for dumping textures to screen
)
func initScreenQuad() {
gl.GenBuffers(1, &screenQuadVBO)
gl.BindBuffer(gl.ARRAY_BUFFER, screenQuadVBO)
gl.BufferData(gl.ARRAY_BUFFER, int(unsafe.Sizeof(float32(0)))*len(screenQuadVerts), gl.Ptr(screenQuadVerts), gl.STATIC_DRAW)
gl.GenVertexArrays(1, &screenQuadVAO)
gl.BindVertexArray(screenQuadVAO)
gl.VertexAttribPointer(0, 2, gl.FLOAT, false, int32(4*unsafe.Sizeof(float32(0))), gl.PtrOffset(0))
gl.VertexAttribPointer(1, 2, gl.FLOAT, false, int32(4*unsafe.Sizeof(float32(0))), gl.PtrOffset(int(2*unsafe.Sizeof(float32(0)))))
gl.EnableVertexAttribArray(0)
gl.EnableVertexAttribArray(1)
}
// DrawScreenQuad draws a Quad covering the entire screen with the current binding shader.
//
// Attribute: (location=0) vert: [ -1.0 --> 1.0]
// (location=1) texCoord: [ 0 --> 1]
func DrawScreenQuad() {
if screenQuadVAO == 0 {
initScreenQuad()
}
gl.Disable(gl.DEPTH_TEST)
gl.Disable(gl.CULL_FACE)
gl.BindVertexArray(screenQuadVAO)
gl.DrawArrays(gl.TRIANGLES, 0, 6)
}
// DrawTextureChannels specifies the channels in RGBA to be drawn.
type DrawTextureChannels int
const (
DrawTextureChannels_R DrawTextureChannels = 1 << iota
DrawTextureChannels_G
DrawTextureChannels_B
DrawTextureChannels_A
)
var (
//go:embed drawtexture.vert
drawTextureShaderVert string
//go:embed drawtexture.frag
drawTextureShaderFrag string
)
func initDrawTexture() {
var err error
drawTextureShader, err = NewShader(drawTextureShaderVert, drawTextureShaderFrag)
if err != nil {
panic(err)
}
gl.BindFragDataLocation(drawTextureShader.Handle(), 0, gl.Str("outputColor\x00"))
}
// DrawTexture dumps the contents of a Texture onto the portion of the screen.
// It disables depth test and cull face.
//
// onScreen is specified in [-1, 1] size.
//
// If only one channel is specified, that channel is drawn in black and white.
// Otherwise, R/G/B are drawn in their specified channels and A is ignored.
//
// The texture values from vauleRange is mapped to [0, 1] linearly.
//
// TODO: This does not work. Maybe something wrong with the shaders or blending
func DrawTexture(texture uint32, onScreen itype.Rectf, channels DrawTextureChannels, valueMin, valueMax float32) {
if screenQuadVAO == 0 {
initScreenQuad()
}
if drawTextureShader == nil {
initDrawTexture()
}
drawTextureShader.UseProgram()
drawTextureShader.SetUniformVec2f("onScreenPos", onScreen.MinPoint())
drawTextureShader.SetUniformVec2f("onScreenSize", onScreen.Size())
drawTextureShader.SetUniformFloat("valueMin", valueMin)
drawTextureShader.SetUniformFloat("valueMax", valueMax)
drawTextureShader.SetUniformInt("channels", int32(channels))
drawTextureShader.SetUniformTextureHandle("tex", texture)
drawTextureShader.BindTextures()
gl.Disable(gl.DEPTH_TEST)
gl.Disable(gl.CULL_FACE)
gl.BindVertexArray(screenQuadVAO)
gl.DrawArrays(gl.TRIANGLES, 0, 6)
}