package render import ( _ "embed" "unsafe" "edgaru089.ink/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) }