simplegl

package module
v0.0.0-...-337bf54 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2021 License: MIT Imports: 12 Imported by: 0

README

SimpleGL

SimpleGL is a simple Go wrapper for modern OpenGL.
It's a pure Go repo and is fully compatible with go-gl ecosystem.

SimpleGL uses the packages below:

SimpleGL provides Object, Group, Viewpoint, LightSource, some common shapes and some routine functions to make modern OpenGL development more easily and fast.
It could be seen as a lightweight wrapper just to simplify the OpenGL routines and organize the code, so developers can get rid of those verbose routines and focus on shaders, vertices and business logics.

Installation

go get github.com/burwei/simplegl

Quick Start

Let's get start with the hello cube program. It shows a rotating cube.
This program is the modified version of go-gl/example/gl41core-cube example.

package main

import (
	"math"

	sgl "github.com/burwei/simplegl"
	"github.com/go-gl/glfw/v3.3/glfw"
	"github.com/go-gl/mathgl/mgl32"
)

const (
	width  = 800
	height = 600
	title  = "SimpleGL"
)

func main() {
	window := sgl.Init(width, height, title)
	defer sgl.Terminate()

	vp := sgl.NewViewpoint(width, height)
	ls := sgl.NewLightSrc()
	mt := sgl.NewMaterial()

	cube := sgl.BasicObj{}
	cube.SetProgramVar(sgl.BasicObjProgVar{
		Red:   1,
		Green: 0.3,
		Blue:  0.3,
		Vp:    &vp,
		Ls:    &ls,
		Mt:    &mt,
	})
	cube.PrepareProgram(true)
	cube.SetVertices(sgl.NewCube(200))

	angle := 0.0
	previousTime := glfw.GetTime()
	rotateY := mgl32.Rotate3DY(-math.Pi / 6).Mat4()

	sgl.BeforeMainLoop(window, &vp)
	for !window.ShouldClose() {
		sgl.BeforeDrawing()

		// make the cube rotate
		time := glfw.GetTime()
		elapsed := time - previousTime
		previousTime = time
		angle += elapsed
		cube.SetModel(rotateY.Mul4(
			mgl32.Rotate3DX(float32(angle) / 5).Mat4(),
		))

		// Render
		cube.Render()

		sgl.AfterDrawing(window)
	}
}

result:

Usage

To use SimpleGL, developers should know how to develop modern OpenGL.
LeanOpenGL.com is a good place to get started if one is not so familiar with OpenGL.

The good news is, developers with Go programming skills and zero OpenGL knowledge might still able to learn some basic OpenGL directly from SimpleGL, since it organizes the code to make it easier to use and understand.

The usage introduction contains the contents below:

  • OpenGL program struture
  • Object
  • Shape
  • Viewpoint & Coordinate system
  • LightSource & Material
  • Group
OpenGL Program structure

Modern OpenGL program can be roughly divided into two parts, CPU program and GPU programs.

The CPU program contains two parts, setup and main loop.
In setup part we call sgl.Init(), which will lock the current thread and init OpenGL and GLFW. GLFW is the library that handles the graphics output and device input, such as window, keyboard, mouse, joystick and so on. Variable assignment, input callback settings and all things we should prepared before starting the main loop will be in the setup part.
The main loop is the for !window.ShouldClose() {} loop. We render the objects in main loop. Before and after the rendering, we call sgl.BeforeDrawing() and sgl.AfterDrawing() to clean, swap buffers and poll events.

The GPU programs contains also two parts, Program Object and shaders. Program Object is used in render operation and it's also the "Program" that SimpleGL refers to when calling APIs like sgl.Object.PrepareProgram() and slg.ObjectSetProgramVar() and so on. SimpleGL sees each Program Object as a final all-in-one program for each sgl.Object, so all varialbes of shaders attached to the Program Object are also seen as the variables of the "Program". Shaders are written in GLSL, and are used to determine how to draw the vertices.
One Program Object can combine multiple shaders to do the rendering job, but we only attach a vertex shader and a fragment shader on it in SimpleGL (so far). Vertex shader calculates the positions of vertices and fragment shader calculates the colors of fragments.

The above is just a simplified introduction. To know more about how OpenGL works, see OpenGL rendering pipeline overview.

Object

sgl.Object is an interface that represents a object with a specific Project Object that can be render on the window after it gets the program variables and vertex array it needs.

sgl.Object + program variables + vertex array = visuable object

sgl.BasicObj is the object with basic lighting, and it's able to draw any shape (any vertex array that contains 3*n float32 values). Developers can implement their own sgl.Object to create some cool objects. By implement sgl.Object, the object could be more easiy to use and be able to move together as a group.

// create a sgl.Object
cube := sgl.BasicObj{}

// set shader program variables
cube.SetProgramVar(sgl.BasicObjProgVar{
	Red:   1,
	Green: 0.3,
	Blue:  0.3,
	Vp:    &vp,
	Ls:    &ls,
	Mt:    &mt,
})

// produce the shader program and bind the program variables with it
cube.PrepareProgram(true)

// set the vetex array
cube.SetVertices(sgl.NewCube(200))

// render the object (in main loop)
cube.Render()
Shape

Shapes are described by vertex arrays, which are 1-D float32 arrays. The most basic vertex arrays are those who use 3 float32 values to represent a vertex's X,Y,Z position. Sometimes vertex array will contains some meta data such as the direction of the texture.

For instance, sgl.NewCube() is a vertex array that use 3 float32 to represent a vertex and form a cube with a user-defined side length.

cube.SetVertices(sgl.NewCube(200))
Viewpoint & Coordinate system

sgl.Viewpoint provides a default camera (eye) position on (X, Y, Z) = (0, 0, 1000) and default target position on (X, Y, Z) = (0, 0, 0). The default top direction of the camera is positive Y and the default projection is perspective projection.

Before we read the code, we should understand the position of the camera as well as the coordinate systems.

There are four coordinate systems here:

  1. local coordinate
  2. world-space coordinate
  3. view-space coordinate
  4. clip-space coordinate

The usage of sgl.Viewpoint is simple. Just new one with the width and height of the window. Although there's no strong restrictions, all sgl.Object should contain a sgl.Viewpoint to make the object appear in view-space and clip-space coordinate correctly.

vp := sgl.NewViewpoint(width, height)

cube := sgl.BasicObj{}
cube.SetProgramVar(sgl.BasicObjProgVar{
	Red:   1,
	Green: 0.3,
	Blue:  0.3,
	Vp:    &vp,
	Ls:    &ls,
	Mt:    &mt,
})
LightSource & Material

sgl.LightSource and agl.Material provides a default light source and default material. These two are essential for those sgl.Object that render the lighting effect.

sgl.LightSource contains 3 attributes: light position, light color and light intensity. All of them are easy to understand.

sgl.Material contains 4 attributes: ambient, diffuse, specular and shininess. Ambient determines what color does the material reflects under ambient lighting; diffuse determines what color does the material reflects under diffuse lighting; specular determines the color of the material's specular highligh; and shininess determines the scattering/radius of the specular highlight.

ls := sgl.NewLightSrc()
mt := sgl.Material{
	Ambient: mgl32.Vec3{0.1, 0.1, 0.1},
	Diffuse: mgl32.Vec3{0.6, 0.6, 0.6},
	Specular: mgl32.Vec3{1.5, 1.5, 1.5},
	Shininess: 24,
}

newCube := sgl.BasicObj{}
newCube.SetProgramVar(sgl.BasicObjProgVar{
	Red:   1,
	Green: 0.3,
	Blue:  0.3,
	Vp:    &vp,
	Ls:    &ls,
	Mt:    &mt,
})
Group

sgl.Group collects mutiple sgl.Object and make them move together like a bigger object. Besides making sgl.Object move together, sgl.Group can also move any collected sgl.Object individually.

// before main loop
group := sgl.NewGroup()
group.AddObject("cube1", &cube1)

// in main loop
group.SetObjectModel("cube1", rotateY.Mul4(
	mgl32.Rotate3DX(float32(angle)/5).Mat4(),
))
group.SetGroupModel(
	mgl32.Translate3D(0, float32(tr), 0).Mul4(
		mgl32.Rotate3DY(float32(angle)/5).Mat4(),
	),
)
group.Render()

Examples

For more examples, see the example folder.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AfterDrawing

func AfterDrawing(window *glfw.Window)

func BeforeDrawing

func BeforeDrawing()

func BeforeMainLoop

func BeforeMainLoop(window *glfw.Window, vp *Viewpoint)

func Init

func Init(windowWidth int, windowHeight int, windowTitle string) *glfw.Window

func InitGlfwAndOpenGL

func InitGlfwAndOpenGL(width int, height int, title string) *glfw.Window

func MakeProgram

func MakeProgram(vertexShaderSource, fragmentShaderSource string) uint32

func NewCube

func NewCube(l float32) *[]float32

NewSimpleCube will return vertices of a cube with side length l.

func NewUniTexCube

func NewUniTexCube(l float32) *[]float32

NewUniTexCube will return vertices of a cube with side length l. The vertices contains custom data (texture vector)

func ReadBinaryStlFile

func ReadBinaryStlFile(file string, min float64, max float64) []float32

func Terminate

func Terminate()

Types

type BasicNoLightObj

type BasicNoLightObj struct {
	// contains filtered or unexported fields
}

func (*BasicNoLightObj) BindProgramVar

func (obj *BasicNoLightObj) BindProgramVar(program uint32)

func (*BasicNoLightObj) GetModel

func (obj *BasicNoLightObj) GetModel() mgl32.Mat4

func (*BasicNoLightObj) GetProgram

func (obj *BasicNoLightObj) GetProgram() uint32

func (*BasicNoLightObj) PrepareProgram

func (obj *BasicNoLightObj) PrepareProgram(bindProgramVar bool)

func (*BasicNoLightObj) Render

func (obj *BasicNoLightObj) Render()

func (*BasicNoLightObj) SetModel

func (obj *BasicNoLightObj) SetModel(newModel mgl32.Mat4)

func (*BasicNoLightObj) SetProgram

func (obj *BasicNoLightObj) SetProgram(program uint32)

func (*BasicNoLightObj) SetProgramVar

func (obj *BasicNoLightObj) SetProgramVar(progVar interface{})

func (*BasicNoLightObj) SetVertices

func (obj *BasicNoLightObj) SetVertices(vertices *[]float32)

type BasicNoLightObjProgVar

type BasicNoLightObjProgVar struct {
	Red   float32
	Green float32
	Blue  float32
	Vp    *Viewpoint
}

type BasicObj

type BasicObj struct {
	// contains filtered or unexported fields
}

func (*BasicObj) BindProgramVar

func (obj *BasicObj) BindProgramVar(program uint32)

func (*BasicObj) GetModel

func (obj *BasicObj) GetModel() mgl32.Mat4

func (*BasicObj) GetProgram

func (obj *BasicObj) GetProgram() uint32

func (*BasicObj) PrepareProgram

func (obj *BasicObj) PrepareProgram(bindProgramVar bool)

func (*BasicObj) Render

func (obj *BasicObj) Render()

func (*BasicObj) SetModel

func (obj *BasicObj) SetModel(newModel mgl32.Mat4)

func (*BasicObj) SetProgram

func (obj *BasicObj) SetProgram(program uint32)

func (*BasicObj) SetProgramVar

func (obj *BasicObj) SetProgramVar(progVar interface{})

func (*BasicObj) SetVertices

func (obj *BasicObj) SetVertices(vertices *[]float32)

type BasicObjProgVar

type BasicObjProgVar struct {
	Red   float32
	Green float32
	Blue  float32
	Vp    *Viewpoint
	Ls    *LightSrc
	Mt    *Material
}

type BasicTexObj

type BasicTexObj struct {
	// contains filtered or unexported fields
}

func (*BasicTexObj) BindProgramVar

func (obj *BasicTexObj) BindProgramVar(program uint32)

func (*BasicTexObj) GetModel

func (obj *BasicTexObj) GetModel() mgl32.Mat4

func (*BasicTexObj) GetProgram

func (obj *BasicTexObj) GetProgram() uint32

func (*BasicTexObj) PrepareProgram

func (obj *BasicTexObj) PrepareProgram(bindProgramVar bool)

func (*BasicTexObj) Render

func (obj *BasicTexObj) Render()

func (*BasicTexObj) SetModel

func (obj *BasicTexObj) SetModel(newModel mgl32.Mat4)

func (*BasicTexObj) SetProgram

func (obj *BasicTexObj) SetProgram(program uint32)

func (*BasicTexObj) SetProgramVar

func (obj *BasicTexObj) SetProgramVar(progVar interface{})

func (*BasicTexObj) SetVertices

func (obj *BasicTexObj) SetVertices(vertices *[]float32)

type BasicTexObjProgVar

type BasicTexObjProgVar struct {
	TextureSrc string
	Vp         *Viewpoint
}

type Group

type Group struct {
	// contains filtered or unexported fields
}

func NewGroup

func NewGroup() Group

func (*Group) AddObject

func (g *Group) AddObject(name string, obj Object)

func (*Group) Render

func (g *Group) Render()

func (*Group) SetGroupModel

func (g *Group) SetGroupModel(newModel mgl32.Mat4)

func (*Group) SetObjectModel

func (g *Group) SetObjectModel(name string, newModel mgl32.Mat4)

type LightSrc

type LightSrc struct {
	Pos       mgl32.Vec3
	Color     mgl32.Vec3
	Intensity float32
}

func NewLightSrc

func NewLightSrc() LightSrc

type Material

type Material struct {
	Ambient   mgl32.Vec3
	Diffuse   mgl32.Vec3
	Specular  mgl32.Vec3
	Shininess float32
}

func NewMaterial

func NewMaterial() Material

type Object

type Object interface {
	// SetProgramVar sets the program's constant and uniform variables.
	SetProgramVar(interface{})

	// PrepareProgram prepares a shader program.
	// If the arg is true, bind uniform variables,
	// otherwise store the program only without binding uniform variables.
	PrepareProgram(bool)

	// BindProgramVar bind uniform variables to a shader program.
	BindProgramVar(uint32)

	// SetVertices sets vao and vbo.
	SetVertices(*[]float32)

	// GetModel gets the model of the object.
	GetProgram() uint32

	// SetModel sets the model of the object.
	SetProgram(uint32)

	// GetModel gets the model of the object.
	GetModel() mgl32.Mat4

	// SetModel sets the model of the object.
	SetModel(mgl32.Mat4)

	// Render refreshs uniform variables and draw the object.
	// All references of the variables that would change the
	// object's states in the main loop (i.e. uniform variables)
	// should have already been prepared when calling SetProgramVar(),
	// thus we won't do any extra work here to get the best performance.
	Render()
}

type Viewpoint

type Viewpoint struct {
	Projection mgl32.Mat4
	Fovy       float32
	Aspect     float32
	Near       float32
	Far        float32
	Camera     mgl32.Mat4
	Eye        mgl32.Vec3
	Target     mgl32.Vec3
	Top        mgl32.Vec3
}

func NewViewpoint

func NewViewpoint(width int, height int) Viewpoint

Directories

Path Synopsis
examples
stl

Jump to

Keyboard shortcuts

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