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 ( import (
"github.com/bloeys/go-sdl-engine/logging" "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 ( 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 BufTypeVertPos
BufTypeColor BufTypeColor
BufTypeIndex
) )
type BufferGLType int func (bt BufType) GetBufferGLType() BufGLType {
switch bt {
const ( case BufTypeColor:
//Generic array of data. Should be used for most data like vertex positions, vertex colors etc. fallthrough
BufGLTypeArrayBuffer BufferGLType = gl.ARRAY_BUFFER 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 ( const (
//Buffer is set only once and used many times //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 //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 //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 { type Buffer struct {
ID uint32 ID uint32
Type BufferType Type BufType
GLType BufferGLType GLType BufGLType
DataTypeInfo DataTypeInfo
} }
@ -50,9 +69,10 @@ type BufferObject struct {
VAOID uint32 VAOID uint32
VertPosBuf *Buffer VertPosBuf *Buffer
ColorBuf *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) gl.BindVertexArray(bo.VAOID)
@ -66,7 +86,35 @@ func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufferUsage, bufType
buf := &Buffer{ buf := &Buffer{
ID: vboID, ID: vboID,
Type: bufType, 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), DataTypeInfo: GetDataTypeInfo(bufDataType),
} }
bo.SetBuffer(buf) bo.SetBuffer(buf)
@ -87,6 +135,8 @@ func (bo *BufferObject) SetBuffer(buf *Buffer) {
bo.VertPosBuf = buf bo.VertPosBuf = buf
case BufTypeColor: case BufTypeColor:
bo.ColorBuf = buf bo.ColorBuf = buf
case BufTypeIndex:
bo.IndexBuf = buf
default: default:
logging.WarnLog.Println("Unknown buffer type in SetBuffer. Type:", buf.Type) logging.WarnLog.Println("Unknown buffer type in SetBuffer. Type:", buf.Type)
} }

View File

@ -2,13 +2,14 @@ package buffers
import ( import (
"github.com/bloeys/go-sdl-engine/logging" "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 type DataType int
const ( const (
DataTypeUnknown = iota DataTypeUnknown DataType = iota
DataTypeUint32
DataTypeInt32 DataTypeInt32
DataTypeFloat32 DataTypeFloat32
DataTypeFloat64 DataTypeFloat64
@ -37,6 +38,8 @@ func (dti *DataTypeInfo) GetSize() int32 {
func GetDataTypeInfo(dt DataType) DataTypeInfo { func GetDataTypeInfo(dt DataType) DataTypeInfo {
switch dt { switch dt {
case DataTypeUint32:
fallthrough
case DataTypeInt32: case DataTypeInt32:
return DataTypeInfo{ return DataTypeInfo{
ElementSize: 4, 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/veandco/go-sdl2 v0.4.10
require github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 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 h1:8q7+xl2D2qHPLTII1t4vSMNP2VKwDcn+Avf2WXvdB1A=
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM= 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= github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=

47
main.go
View File

@ -1,11 +1,13 @@
package main package main
import ( import (
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/go-sdl-engine/buffers" "github.com/bloeys/go-sdl-engine/buffers"
"github.com/bloeys/go-sdl-engine/input" "github.com/bloeys/go-sdl-engine/input"
"github.com/bloeys/go-sdl-engine/logging" "github.com/bloeys/go-sdl-engine/logging"
"github.com/bloeys/go-sdl-engine/res/models"
"github.com/bloeys/go-sdl-engine/shaders" "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" "github.com/veandco/go-sdl2/sdl"
) )
@ -48,8 +50,16 @@ func main() {
simpleShader.SetAttribute("vertPos", bo, bo.VertPosBuf) simpleShader.SetAttribute("vertPos", bo, bo.VertPosBuf)
simpleShader.EnableAttribute("vertPos") simpleShader.EnableAttribute("vertPos")
simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf) // simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf)
simpleShader.EnableAttribute("vertColor") // 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 //Game loop
for isRunning { for isRunning {
@ -109,27 +119,32 @@ func loadBuffers() {
vertices := []float32{ 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,
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{ //Load obj
1, 0, 0, objInfo, err := models.LoadObj("./res/models/obj.obj")
0, 0, 1, if err != nil {
0, 0, 1, panic(err)
0, 0, 1,
0, 0, 1,
0, 0, 1,
} }
logging.InfoLog.Printf("%v", objInfo.TriIndices)
vertices = objInfo.VertPos
indices = objInfo.TriIndices
bo = buffers.NewBufferObject() bo = buffers.NewBufferObject()
bo.GenBuffer(vertices, buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3) 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() { func handleInputs() {
@ -162,7 +177,7 @@ func draw() {
//DRAW //DRAW
bo.Activate() bo.Activate()
gl.DrawArrays(gl.TRIANGLES, 0, 6) gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, gl.PtrOffset(0))
bo.Deactivate() bo.Deactivate()
window.GLSwap() 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() 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; out vec3 outColor;
uniform mat4 modelMat;
void main() void main()
{ {
outColor = vertColor; 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 package shaders
import ( import (
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/go-sdl-engine/buffers" "github.com/bloeys/go-sdl-engine/buffers"
"github.com/bloeys/go-sdl-engine/logging" "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 { type ShaderProgram struct {
@ -69,6 +70,36 @@ func (sp *ShaderProgram) DisableAttribute(attribName string) {
gl.DisableVertexAttribArray(uint32(sp.GetAttribLoc(attribName))) 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() { func (sp *ShaderProgram) Delete() {
gl.DeleteProgram(sp.ID) gl.DeleteProgram(sp.ID)
} }

View File

@ -1,6 +1,6 @@
package shaders 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 type ShaderType int

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
"github.com/bloeys/go-sdl-engine/logging" "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 { type Shader struct {