Documentation ¶
Overview ¶
Example (ColoredSquare) ¶
package main import ( "fmt" "runtime" "strings" "time" "unsafe" "github.com/go-gl/gl/v4.6-core/gl" "github.com/go-gl/glfw/v3.3/glfw" "github.com/soypat/glgl/v4.6-core/glgl" "golang.org/x/exp/slog" ) func init() { // GLFW event handling must run on the main OS thread runtime.LockOSThread() } func main() { // Very basic index buffer example. const shader = ` #shader vertex #version 330 in vec3 vert; void main() { gl_Position = vec4(vert.xyz, 1.0); } #shader fragment #version 330 out vec4 outputColor; uniform vec4 u_color; void main() { outputColor = u_color; }` // Square with indices: // 3----2 // | | // 0----1 var positions = []float32{ -0.5, -0.5, // 0 0.5, -0.5, // 1 0.5, 0.5, // 2 -0.5, 0.5, //3 } var indices = []uint32{ 0, 1, 2, // Lower right triangle. 0, 2, 3, // Upper left triangle. } window, terminate, err := glgl.InitWithCurrentWindow33(glgl.WindowConfig{ Title: "Index Buffers", Width: 800, Height: 800, NotResizable: true, Version: [2]int{4, 6}, OpenGLProfile: glfw.OpenGLCoreProfile, ForwardCompat: true, }) defer terminate() fmt.Println("OpenGL version", glgl.Version()) // Separate vertex and fragment shaders from source code. source, err := glgl.ParseCombined(strings.NewReader(shader)) if err != nil { slog.Error("parse combined source fail", err) return } // Configure the vertex and fragment shaders program, err := glgl.CompileProgram(source) if err != nil { slog.Error("compile fail", err) return } defer program.Delete() program.Bind() err = program.BindFrag("outputColor\x00") if err != nil { slog.Error("program bind frag fail", err) return } // Configure the Vertex Array Object. vao := glgl.NewVAO() // Create the Position Buffer Object. vbo, err := glgl.NewVertexBuffer(glgl.StaticDraw, positions) if err != nil { slog.Error("creating positions vertex buffer", err) return } err = vao.AddAttribute(vbo, glgl.AttribLayout{ Program: program, Type: gl.FLOAT, Name: "vert\x00", Packing: 2, Stride: 2 * 4, // 2 floats, each 4 bytes wide. }) if err != nil { slog.Error("adding attribute vert", err) return } // Create Index Buffer Object. _, err = glgl.NewIndexBuffer(indices) if err != nil { slog.Error("creating index buffer", err) return } // Set uniform variable `u_color` in source code. err = program.SetUniformName4f("u_color\x00", 0.2, 0.3, 0.8, 1) if err != nil { slog.Error("creating index buffer", err) return } for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT) gl.DrawElements(gl.TRIANGLES, int32(len(indices)), gl.UNSIGNED_INT, unsafe.Pointer(nil)) program.SetUniformName4f("u_color\x00", float32(time.Now().UnixMilli()%1000)/1000, .5, .3, 1) // Maintenance glfw.SwapInterval(1) // Can prevent epilepsy for high frequency window.SwapBuffers() glfw.PollEvents() if window.GetKey(glfw.KeyEscape) == glfw.Press { window.SetShouldClose(true) } } }
Output: None.
Index ¶
- Variables
- func ClearErrors()
- func EnableDebugOutput(log *slog.Logger)
- func Err() error
- func GetBufferData[T any](dst []T, vbo VertexBuffer) error
- func GetImage[T any](dst []T, tex Texture, cfg TextureImgConfig) error
- func InitWithCurrentWindow33(cfg WindowConfig) (*glfw.Window, func(), error)
- func MapBufferData[T any](vbo VertexBuffer, length int, access AccessUsage) ([]T, error)
- func MaxTextureBinded() (textureBounds int)
- func MaxTextureSlots() (textureUnits int)
- func SetImage2D[T any](tex Texture, cfg TextureImgConfig, data []T) error
- func Version() string
- type AccessUsage
- type AttribLayout
- type BufferUsage
- type IndexBuffer
- type Program
- func (p Program) Bind()
- func (p Program) BindFrag(name string) error
- func (p Program) Delete()
- func (p Program) RunCompute(workSizeX, workSizeY, workSizeZ int) error
- func (p Program) SetUniform1f(name string, v float32) error
- func (p Program) SetUniformName4f(name string, v0, v1, v2, v3 float32) error
- func (p Program) Unbind()
- type ShaderSource
- type Texture
- type TextureImgConfig
- type TextureType
- type Type
- type VertexArray
- type VertexBuffer
- type WindowConfig
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var (
ErrStringNotNullTerminated = errors.New("string not null terminated")
)
Functions ¶
func EnableDebugOutput ¶
EnableDebugOutput writes debug output to log via glDebugMessageCallback. If log is nil then the default slog package logger is used.
func Err ¶
func Err() error
Err returns a non-nil glErrors if errors are foudn in OpenGL's GetError buffer. After a call to Err no more errors should be returned until the next GL call.
func GetBufferData ¶
func GetBufferData[T any](dst []T, vbo VertexBuffer) error
func InitWithCurrentWindow33 ¶
func InitWithCurrentWindow33(cfg WindowConfig) (*glfw.Window, func(), error)
func MapBufferData ¶
func MapBufferData[T any](vbo VertexBuffer, length int, access AccessUsage) ([]T, error)
MapBufferData maps vertex buffer memory on the GPU to client space in the form of a slice.
func MaxTextureBinded ¶
func MaxTextureBinded() (textureBounds int)
func MaxTextureSlots ¶
func MaxTextureSlots() (textureUnits int)
func SetImage2D ¶
func SetImage2D[T any](tex Texture, cfg TextureImgConfig, data []T) error
SetImage2D sets an existing texture's values on the GPU.
Types ¶
type AccessUsage ¶
type AccessUsage uint32
const WriteOnly, ReadOnly, ReadOrWrite AccessUsage = gl.WRITE_ONLY, gl.READ_ONLY, gl.READ_WRITE
type AttribLayout ¶
type AttribLayout struct { // The OpenGL program identifier. Program Program // Type is a OpenGL enum representing the underlying type. Valid types include // gl.FLOAT, gl.UNSIGNED_INT, gl.UNSIGNED_BYTE, gl.BYTE etc. Type Type // Name is the identifier of the attribute in the // vertex shader source code finished with a null terminator. Name string // Packing is a value between 1 and 4 and represents how many // of the type are present at the attribute location. // // Example: // When w orking with a vec3 attribute in the shader source code // with a gl.Float type, then the Packing is 3 since there are // 3 floats packed at each attribute location. Packing int // Stride is the distance in bytes between attributes in the buffer. Stride int // Offset is the starting offset with which to start // traversing the vertex buffer. Offset int // specifies whether fixed-point data values should be normalized (when true) // or converted directly as fixed-point values (when false) when they are accessed. // Usually left as false? Normalize bool }
AttribLayout is a low level configuration struct for adding vertex buffers attribute layouts to a vertex array object.
type BufferUsage ¶
type BufferUsage uint32
BufferUsage is a required hint given to the GPU that provide a general description of how exactly the user will be using the buffer object so as to better optimize performance.
There are two independent parts to the usage pattern: how the user will be reading/writing from/to the buffer, and how often the user will be changing it relative to the use of the data.
- DRAW: The user will be writing data to the buffer, but the user will not read it.
- READ: The user will not be writing data, but the user will be reading it back.
- COPY: The user will be neither writing nor reading the data.
There are three hints for how frequently the user will be changing the buffer's data.
- STATIC: The user will set the data once.
- DYNAMIC: The user will set the data occasionally.
- STREAM: The user will be changing the data after every use. Or almost every use.
DRAW is useful for, as the name suggests, drawing. The user is uploading data, but only the GL is reading it.
READ is used when a buffer object is used as the destination for OpenGL commands. This could be rendering to a Buffer Texture, using arbitrary writes to buffer textures, doing a pixel transfer into a buffer object, using Transform Feedback, or any other OpenGL operation that writes to buffer objects.
COPY is used when a buffer object is used to pass data from one place in OpenGL to another.
const ( StaticDraw BufferUsage = gl.STATIC_DRAW StaticRead BufferUsage = gl.STATIC_READ StaticCopy BufferUsage = gl.STATIC_COPY DynamicDraw BufferUsage = gl.DYNAMIC_DRAW DynamicRead BufferUsage = gl.DYNAMIC_READ DynamicCopy BufferUsage = gl.DYNAMIC_COPY StreamDraw BufferUsage = gl.STREAM_DRAW StreamRead BufferUsage = gl.STREAM_READ StreamCopy BufferUsage = gl.STREAM_COPY )
Buffer Usages. See BufferUsage documentation for detailed information.
type IndexBuffer ¶
type IndexBuffer struct {
// contains filtered or unexported fields
}
func NewIndexBuffer ¶
func NewIndexBuffer(data []uint32) (IndexBuffer, error)
func (IndexBuffer) Bind ¶
func (vbo IndexBuffer) Bind()
func (IndexBuffer) Delete ¶
func (vbo IndexBuffer) Delete()
func (IndexBuffer) Unbind ¶
func (vbo IndexBuffer) Unbind()
type Program ¶
type Program struct {
// contains filtered or unexported fields
}
func CompileProgram ¶
func CompileProgram(ss ShaderSource) (prog Program, err error)
func (Program) Delete ¶
func (p Program) Delete()
Delete deletes p. Make sure program is binded before deletion.
func (Program) RunCompute ¶
RunCompute runs a the program's compute shader with defined work sizes and waits for it to finish.
func (Program) SetUniformName4f ¶
type ShaderSource ¶
type ShaderSource struct { // Vertex and Fragment are null terminated strings with source code. Vertex string Fragment string Compute string Include string }
Vertex and Fragment are null terminated strings with source code.
func ParseCombined ¶
func ParseCombined(r io.Reader) (ss ShaderSource, err error)
ParseCombinedBasic parses a file with vertex and fragment #shader pragmas inspired by The Cherno's take on shader file segmenting. This method of writing shaders lets one keep vertex and fragment shader source code in the same file:
// Anything above first #shader pragma is ignored. #shader vertex void main() { gl_Position = vec4(1.0,0.0,0.0, 1.0); } #shader fragment void main() { gl_Frag = gl_Position/2; }
`compute` and `includeashead` are also valid #shader pragmas. ParseCombined performs no calls to the GL.
type Texture ¶
type Texture struct {
// contains filtered or unexported fields
}
func NewTextureFromImage ¶
func NewTextureFromImage[T any](cfg TextureImgConfig, data []T) (Texture, error)
NewTextureFromImage creates a new Texture from an image and binds it to the current context.
type TextureImgConfig ¶
type TextureImgConfig struct { // Specifies the target texture. Must be one of: // GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D, GL_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_1D_ARRAY, GL_TEXTURE_RECTANGLE, GL_PROXY_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, or GL_PROXY_TEXTURE_CUBE_MAP. Type TextureType Width int Height int Border int32 // Specifies the number of color components in the texture. // Can use base, sized or compressed internal formats: See [TextureImgConfig] for more. // If not set uses Format. InternalFormat int32 // Specifies format of the pixel data. Accepts: // GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL. Format uint32 // Specifies the data type of the pixel data. Accepts // GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, and GL_UNSIGNED_INT_2_10_10_10_REV. Xtype uint32 // Magnification filtering. gl.NEAREST or gl.LINEAR. MagFilter int32 // Minification filtering. gl.NEAREST or gl.LINEAR. MinFilter int32 // Textures coordinates usually range from (0,0) to (1,1). Wrap indicates // how OpenGL is to repeat the texture outside this range. // gl.REPEAT, gl.MIRRORED_REPEAT, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_BORDER. Wrap int32 // Specifies a token indicating the type of access that will be performed on the image. Access AccessUsage Layered bool Layer int32 // Specifies the level-of-detail number. Level 0 is the base image level. If target is GL_TEXTURE_RECTANGLE or GL_PROXY_TEXTURE_RECTANGLE, level must be 0. Level int32 // Specifies the unit on which to bind the image onto the texture. // ImageUnit uint32 // TextureUnit is the texture unit onto which the texture is loaded (glActiveTexture). // TextureUnit starts at 0 and goes all the way up to MaxTextureSlots(). TextureUnit int }
TextureImgConfig builds an image based texture. Below are common formats: - Base internal. i.e: gl.RED, gl.RG, gl.RGBA, gl.DEPTH_COMPONENT - Sized internal: gl.R8, gl.R16, gl.RGB4, gl.R32F, gl.RGBA32F.
func (TextureImgConfig) PixelSize ¶
func (cfg TextureImgConfig) PixelSize() int
type VertexArray ¶
type VertexArray struct {
// contains filtered or unexported fields
}
VertexArray ties data layout with vertex buffer(s). Is aware of data layout via VertexAttribPointer* calls. Vertex array parameters are client state, that is to say the GPU is unaware of it. Loosely speaking, a vertex array
func NewVAO ¶
func NewVAO() VertexArray
NewVAO creates a vertex array object and binds it to current context.
func (VertexArray) AddAttribute ¶
func (vao VertexArray) AddAttribute(vbo VertexBuffer, layout AttribLayout) error
func (VertexArray) Bind ¶
func (vao VertexArray) Bind()
func (VertexArray) Unbind ¶
func (vao VertexArray) Unbind()
type VertexBuffer ¶
type VertexBuffer struct {
// contains filtered or unexported fields
}
VertexBuffer contains bytes, no information on the layout or type. Buffer objects are said to be "server state", compared to vertex array parameters as "client state".
func NewVertexBuffer ¶
func NewVertexBuffer[T any](usage BufferUsage, data []T) (VertexBuffer, error)
NewVertexBuffer creates a new vertex buffer and binds it.
func (VertexBuffer) Bind ¶
func (vbo VertexBuffer) Bind()
func (VertexBuffer) Delete ¶
func (vbo VertexBuffer) Delete()
func (VertexBuffer) Unbind ¶
func (vbo VertexBuffer) Unbind()