glgl

package
v0.0.0-...-370dd11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2023 License: MIT Imports: 11 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrStringNotNullTerminated = errors.New("string not null terminated")
)

Functions

func ClearErrors

func ClearErrors()

ClearErrors clears all of OpenGL's errors in it's log.

func EnableDebugOutput

func EnableDebugOutput(log *slog.Logger)

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 GetImage

func GetImage[T any](dst []T, tex Texture, cfg TextureImgConfig) 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.

func Version

func Version() string

Version returns the running OpenGL version as a string.

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) Bind

func (p Program) Bind()

func (Program) BindFrag

func (p Program) BindFrag(name string) error

func (Program) Delete

func (p Program) Delete()

Delete deletes p. Make sure program is binded before deletion.

func (Program) RunCompute

func (p Program) RunCompute(workSizeX, workSizeY, workSizeZ int) error

RunCompute runs a the program's compute shader with defined work sizes and waits for it to finish.

func (Program) SetUniform1f

func (p Program) SetUniform1f(name string, v float32) error

func (Program) SetUniformName4f

func (p Program) SetUniformName4f(name string, v0, v1, v2, v3 float32) error

func (Program) Unbind

func (p Program) Unbind()

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.

func (Texture) Bind

func (t Texture) Bind(activeSlot int)

Bind receives a slot onto which to bind from 0 to 32.

func (Texture) Delete

func (t Texture) Delete()
func (t Texture) Unbind() {
	if err := Err(); err != nil {
		panic(err)
	}
	gl.ActiveTexture(0)
	gl.BindTexture(t.target, 0)
	if err := Err(); err != nil {
		panic(err)
	}
}

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 TextureType

type TextureType uint32
const Texture2D TextureType = gl.TEXTURE_2D

type Type

type Type uint32
const (
	Int8    Type = gl.BYTE
	Uint8   Type = gl.UNSIGNED_BYTE
	Int16   Type = gl.SHORT
	Uint16  Type = gl.UNSIGNED_SHORT
	Int32   Type = gl.INT
	Uint32  Type = gl.UNSIGNED_INT
	Float32 Type = gl.FLOAT
)

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()

type WindowConfig

type WindowConfig struct {
	Title        string
	NotResizable bool
	Version      [2]int
	// glfw.OpenGLCoreProfile
	OpenGLProfile int
	ForwardCompat bool
	Width, Height int
	DebugLog      *slog.Logger
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL