123 lines
3.2 KiB
Go
123 lines
3.2 KiB
Go
|
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)
|
||
|
}
|