Ep5: Obj file loading+indexed drawing+uniforms

This commit is contained in:
bloeys
2021-11-06 22:23:48 +04:00
parent 2b341132f8
commit 3167bffbd1
12 changed files with 264 additions and 39 deletions

View File

@ -2,39 +2,58 @@ package buffers
import (
"github.com/bloeys/go-sdl-engine/logging"
"github.com/go-gl/gl/v4.6-compatibility/gl"
"github.com/go-gl/gl/v4.6-core/gl"
)
type BufferType int
type BufGLType int
const (
BufTypeUnknown BufferType = iota
BufGLTypeUnknown BufGLType = 0
//Generic array of data. Should be used for most data like vertex positions, vertex colors etc.
BufGLTypeArray BufGLType = gl.ARRAY_BUFFER
BufGLTypeIndices BufGLType = gl.ELEMENT_ARRAY_BUFFER
)
type BufType int
const (
BufTypeUnknown BufType = iota
BufTypeVertPos
BufTypeColor
BufTypeIndex
)
type BufferGLType int
func (bt BufType) GetBufferGLType() BufGLType {
switch bt {
const (
//Generic array of data. Should be used for most data like vertex positions, vertex colors etc.
BufGLTypeArrayBuffer BufferGLType = gl.ARRAY_BUFFER
)
case BufTypeColor:
fallthrough
case BufTypeVertPos:
return BufGLTypeArray
type BufferUsage int
case BufTypeIndex:
return BufGLTypeIndices
default:
logging.WarnLog.Println("Unknown BufferType. BufferType: ", bt)
return BufGLTypeUnknown
}
}
type BufUsage int
const (
//Buffer is set only once and used many times
BufUsageStatic BufferUsage = gl.STATIC_DRAW
BufUsageStatic BufUsage = gl.STATIC_DRAW
//Buffer is changed a lot and used many times
BufUsageDynamic BufferUsage = gl.DYNAMIC_DRAW
BufUsageDynamic BufUsage = gl.DYNAMIC_DRAW
//Buffer is set only once and used by the GPU at most a few times
BufUsageStream BufferUsage = gl.STREAM_DRAW
BufUsageStream BufUsage = gl.STREAM_DRAW
)
type Buffer struct {
ID uint32
Type BufferType
GLType BufferGLType
Type BufType
GLType BufGLType
DataTypeInfo
}
@ -50,9 +69,10 @@ type BufferObject struct {
VAOID uint32
VertPosBuf *Buffer
ColorBuf *Buffer
IndexBuf *Buffer
}
func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufferUsage, bufType BufferType, bufDataType DataType) {
func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufUsage, bufType BufType, bufDataType DataType) {
gl.BindVertexArray(bo.VAOID)
@ -66,7 +86,35 @@ func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufferUsage, bufType
buf := &Buffer{
ID: vboID,
Type: bufType,
GLType: BufGLTypeArrayBuffer,
GLType: bufType.GetBufferGLType(),
DataTypeInfo: GetDataTypeInfo(bufDataType),
}
bo.SetBuffer(buf)
//Fill buffer with data
gl.BindBuffer(uint32(buf.GLType), buf.ID)
gl.BufferData(uint32(buf.GLType), int(buf.DataTypeInfo.ElementSize)*len(data), gl.Ptr(data), uint32(bufUsage))
//Unbind everything
gl.BindVertexArray(0)
gl.BindBuffer(uint32(buf.GLType), 0)
}
func (bo *BufferObject) GenBufferUint32(data []uint32, bufUsage BufUsage, bufType BufType, bufDataType DataType) {
gl.BindVertexArray(bo.VAOID)
//Create vertex buffer object
var vboID uint32
gl.CreateBuffers(1, &vboID)
if vboID == 0 {
logging.ErrLog.Println("Failed to create openGL buffer")
}
buf := &Buffer{
ID: vboID,
Type: bufType,
GLType: bufType.GetBufferGLType(),
DataTypeInfo: GetDataTypeInfo(bufDataType),
}
bo.SetBuffer(buf)
@ -87,6 +135,8 @@ func (bo *BufferObject) SetBuffer(buf *Buffer) {
bo.VertPosBuf = buf
case BufTypeColor:
bo.ColorBuf = buf
case BufTypeIndex:
bo.IndexBuf = buf
default:
logging.WarnLog.Println("Unknown buffer type in SetBuffer. Type:", buf.Type)
}

View File

@ -2,13 +2,14 @@ package buffers
import (
"github.com/bloeys/go-sdl-engine/logging"
"github.com/go-gl/gl/v4.6-compatibility/gl"
"github.com/go-gl/gl/v4.6-core/gl"
)
type DataType int
const (
DataTypeUnknown = iota
DataTypeUnknown DataType = iota
DataTypeUint32
DataTypeInt32
DataTypeFloat32
DataTypeFloat64
@ -37,6 +38,8 @@ func (dti *DataTypeInfo) GetSize() int32 {
func GetDataTypeInfo(dt DataType) DataTypeInfo {
switch dt {
case DataTypeUint32:
fallthrough
case DataTypeInt32:
return DataTypeInfo{
ElementSize: 4,

2
go.mod
View File

@ -5,3 +5,5 @@ go 1.17
require github.com/veandco/go-sdl2 v0.4.10
require github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259
require github.com/bloeys/gglm v0.1.1 // indirect

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/bloeys/gglm v0.1.1 h1:juLE2OqobKKamMq7IKkplOJcZaM45CAcmbS0rCND3Hc=
github.com/bloeys/gglm v0.1.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 h1:8q7+xl2D2qHPLTII1t4vSMNP2VKwDcn+Avf2WXvdB1A=
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=

47
main.go
View File

@ -1,11 +1,13 @@
package main
import (
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/go-sdl-engine/buffers"
"github.com/bloeys/go-sdl-engine/input"
"github.com/bloeys/go-sdl-engine/logging"
"github.com/bloeys/go-sdl-engine/res/models"
"github.com/bloeys/go-sdl-engine/shaders"
"github.com/go-gl/gl/v4.6-compatibility/gl"
"github.com/go-gl/gl/v4.6-core/gl"
"github.com/veandco/go-sdl2/sdl"
)
@ -48,8 +50,16 @@ func main() {
simpleShader.SetAttribute("vertPos", bo, bo.VertPosBuf)
simpleShader.EnableAttribute("vertPos")
simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf)
simpleShader.EnableAttribute("vertColor")
// simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf)
// simpleShader.EnableAttribute("vertColor")
modelMat := gglm.NewTrMatId()
translationMat := gglm.NewTranslationMat(gglm.NewVec3(-0.5, 0, 0))
scaleMat := gglm.NewScaleMat(gglm.NewVec3(0.25, 0.25, 0.25))
rotMat := gglm.NewRotMat(gglm.NewQuatEuler(gglm.NewVec3(0, 0, 0).AsRad()))
modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
simpleShader.SetUnifMat4("modelMat", &modelMat.Mat4)
//Game loop
for isRunning {
@ -109,27 +119,32 @@ func loadBuffers() {
vertices := []float32{
-0.5, 0.5, 0,
0.5, 0.5, 0,
-0.5, -0.5, 0,
0.5, 0.5, 0,
0.5, -0.5, 0,
-0.5, -0.5, 0,
}
// colors := []float32{
// 1, 0, 0,
// 0, 0, 1,
// 0, 0, 1,
// 0, 0, 1,
// }
indices := []uint32{0, 1, 3, 1, 2, 3}
colors := []float32{
1, 0, 0,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
//Load obj
objInfo, err := models.LoadObj("./res/models/obj.obj")
if err != nil {
panic(err)
}
logging.InfoLog.Printf("%v", objInfo.TriIndices)
vertices = objInfo.VertPos
indices = objInfo.TriIndices
bo = buffers.NewBufferObject()
bo.GenBuffer(vertices, buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3)
bo.GenBuffer(colors, buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec3)
// bo.GenBuffer(colors, buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec3)
bo.GenBufferUint32(indices, buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32)
}
func handleInputs() {
@ -162,7 +177,7 @@ func draw() {
//DRAW
bo.Activate()
gl.DrawArrays(gl.TRIANGLES, 0, 6)
gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, gl.PtrOffset(0))
bo.Deactivate()
window.GLSwap()

73
res/models/loader.go Executable file
View File

@ -0,0 +1,73 @@
package models
import (
"os"
"strconv"
"strings"
"github.com/bloeys/go-sdl-engine/logging"
)
type ObjInfo struct {
VertPos []float32
TriIndices []uint32
}
func LoadObj(file string) (objInfo ObjInfo, err error) {
b, err := os.ReadFile(file)
if err != nil {
return objInfo, err
}
lines := strings.Split(string(b), "\n")
for i := 0; i < len(lines); i++ {
s := strings.SplitN(lines[i], " ", 2)
switch s[0] {
case "v":
vertPosStrings := strings.Split(s[1], " ")
f, err := strconv.ParseFloat(vertPosStrings[0], 32)
if err != nil {
return objInfo, err
}
objInfo.VertPos = append(objInfo.VertPos, float32(f))
f, err = strconv.ParseFloat(vertPosStrings[1], 32)
if err != nil {
return objInfo, err
}
objInfo.VertPos = append(objInfo.VertPos, float32(f))
f, err = strconv.ParseFloat(vertPosStrings[2], 32)
if err != nil {
return objInfo, err
}
objInfo.VertPos = append(objInfo.VertPos, float32(f))
case "f":
facesStrings := strings.Split(s[1], " ")
objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[0]))
objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[1]))
objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[2]))
default:
}
}
return objInfo, nil
}
func getVertIndexFromFace(f string) uint32 {
indxStr := strings.SplitN(f, "/", 2)[0]
index, err := strconv.Atoi(indxStr)
if err != nil {
logging.ErrLog.Printf("Invalid face index '%v'. Err: %v", indxStr, err)
return 0
}
return uint32(index) - 1
}

46
res/models/obj.obj Executable file
View File

@ -0,0 +1,46 @@
# Blender v2.92.0 OBJ File: ''
# www.blender.org
mtllib obj.mtl
o Cube
v 2.275618 1.000000 0.349413
v 3.520138 -1.000000 0.102233
v 2.275618 1.000000 0.752820
v 3.520138 -1.000000 1.000000
v 0.244520 1.000000 0.349413
v -1.000000 -1.000000 0.102233
v 0.244520 1.000000 0.752820
v -1.000000 -1.000000 1.000000
vt 0.806168 0.568832
vt 0.693832 0.681168
vt 0.693832 0.568832
vt 0.375000 1.000000
vt 0.375000 0.750000
vt 0.375000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.806168 0.681168
vt 0.625000 0.931168
vt 0.625000 0.068832
vn 0.0000 1.0000 0.0000
vn 0.0000 0.1227 0.9924
vn -0.8490 0.5283 0.0000
vn 0.0000 -1.0000 0.0000
vn 0.8490 0.5283 0.0000
vn 0.0000 0.1227 -0.9924
usemtl Material
s off
f 5/1/1 3/2/1 1/3/1
f 3/2/2 8/4/2 4/5/2
f 8/6/3 5/7/3 6/8/3
f 2/9/4 8/10/4 6/11/4
f 1/3/5 4/5/5 2/9/5
f 5/7/6 2/9/6 6/8/6
f 5/1/1 7/12/1 3/2/1
f 3/2/2 7/13/2 8/4/2
f 8/6/3 7/14/3 5/7/3
f 2/9/4 4/5/4 8/10/4
f 1/3/5 3/2/5 4/5/5
f 5/7/6 1/3/6 2/9/6

View File

@ -6,5 +6,6 @@ out vec4 fragColor;
void main()
{
fragColor = vec4(outColor, 1.0);
fragColor = vec4(1,1,1, 1.0);
// fragColor = vec4(outColor, 1.0);
}

View File

@ -5,8 +5,10 @@ in vec3 vertColor;
out vec3 outColor;
uniform mat4 modelMat;
void main()
{
outColor = vertColor;
gl_Position = vec4(vertPos, 1.0); // vec4(vertPos.x, vertPos.y, vertPos.z, 1.0)
gl_Position = modelMat * (vec4(vertPos, 1.0)); // vec4(vertPos.x, vertPos.y, vertPos.z, 1.0)
}

View File

@ -1,9 +1,10 @@
package shaders
import (
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/go-sdl-engine/buffers"
"github.com/bloeys/go-sdl-engine/logging"
"github.com/go-gl/gl/v4.6-compatibility/gl"
"github.com/go-gl/gl/v4.6-core/gl"
)
type ShaderProgram struct {
@ -69,6 +70,36 @@ func (sp *ShaderProgram) DisableAttribute(attribName string) {
gl.DisableVertexAttribArray(uint32(sp.GetAttribLoc(attribName)))
}
func (sp *ShaderProgram) SetUnifVec2(uniformName string, vec2 *gglm.Vec2) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniform2fv(sp.ID, loc, 1, &vec2.Data[0])
}
func (sp *ShaderProgram) SetUnifVec3(uniformName string, vec3 *gglm.Vec3) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniform3fv(sp.ID, loc, 1, &vec3.Data[0])
}
func (sp *ShaderProgram) SetUnifVec4(uniformName string, vec4 *gglm.Vec4) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniform4fv(sp.ID, loc, 1, &vec4.Data[0])
}
func (sp *ShaderProgram) SetUnifMat2(uniformName string, mat2 *gglm.Mat2) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniformMatrix2fv(sp.ID, loc, 1, true, &mat2.Data[0])
}
func (sp *ShaderProgram) SetUnifMat3(uniformName string, mat3 *gglm.Mat3) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniformMatrix3fv(sp.ID, loc, 1, true, &mat3.Data[0])
}
func (sp *ShaderProgram) SetUnifMat4(uniformName string, mat4 *gglm.Mat4) {
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
gl.ProgramUniformMatrix4fv(sp.ID, loc, 1, true, &mat4.Data[0])
}
func (sp *ShaderProgram) Delete() {
gl.DeleteProgram(sp.ID)
}

View File

@ -1,6 +1,6 @@
package shaders
import "github.com/go-gl/gl/v4.6-compatibility/gl"
import "github.com/go-gl/gl/v4.6-core/gl"
type ShaderType int

View File

@ -6,7 +6,7 @@ import (
"strings"
"github.com/bloeys/go-sdl-engine/logging"
"github.com/go-gl/gl/v4.6-compatibility/gl"
"github.com/go-gl/gl/v4.6-core/gl"
)
type Shader struct {