mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Ep5: Obj file loading+indexed drawing+uniforms
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
@ -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
2
go.mod
@ -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
2
go.sum
@ -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
47
main.go
@ -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
73
res/models/loader.go
Executable 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
46
res/models/obj.obj
Executable 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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user