Abstracting out drawing a box, doesn't work correctly.
parent
0ed95e851b
commit
ccc61e9a07
128
main.go
128
main.go
|
@ -8,13 +8,13 @@ import (
|
|||
"runtime"
|
||||
"runtime/pprof"
|
||||
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/game_window"
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/gl_helpers"
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/gl_objects"
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/game_window"
|
||||
)
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||
|
@ -23,16 +23,16 @@ const GameTitle = "Carpy Breakout"
|
|||
const LogFile = "output.log"
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *cpuprofile != "" {
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
if *cpuprofile != "" {
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
setupLogging()
|
||||
run()
|
||||
}
|
||||
|
@ -40,8 +40,6 @@ func main() {
|
|||
func run() {
|
||||
runtime.LockOSThread() // TODO can rework stuff to not need this.
|
||||
|
||||
log.Println(os.Environ())
|
||||
|
||||
err := sdl.Init(sdl.INIT_EVERYTHING)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -60,8 +58,6 @@ func run() {
|
|||
sdl.SetRelativeMouseMode(true)
|
||||
|
||||
gl.Init()
|
||||
version := gl.GoStr(gl.GetString(gl.VERSION))
|
||||
log.Println("OpenGL version", version)
|
||||
gl.ClearColor(0.0, 0.0, 0.0, 1.0)
|
||||
|
||||
gameWindow, err := game_window.NewGameWindow(GameTitle)
|
||||
|
@ -83,22 +79,31 @@ func run() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
box := gl_objects.NewBox(6.0, 4.0, 2.0, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{1, 1, 1}, true)
|
||||
vertices := box.GetVertexArray()
|
||||
|
||||
log.Println(vertices)
|
||||
|
||||
var vao uint32
|
||||
gl.GenVertexArrays(1, &vao)
|
||||
gl.BindVertexArray(vao)
|
||||
|
||||
|
||||
var vbo uint32
|
||||
gl.GenBuffers(1, &vbo)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW)
|
||||
gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW)
|
||||
|
||||
vertAttrib := uint32(gl.GetAttribLocation(gameWindow.GLProgram, gl.Str("vert\x00")))
|
||||
gl.EnableVertexAttribArray(vertAttrib)
|
||||
gl.VertexAttribPointerWithOffset(vertAttrib, 3, gl.FLOAT, false, 5*4, 0)
|
||||
gl.VertexAttribPointerWithOffset(vertAttrib, 3, gl.FLOAT, false, 8*4, 0)
|
||||
|
||||
vertColorAttrib := uint32(gl.GetAttribLocation(gameWindow.GLProgram, gl.Str("vertColor\x00")))
|
||||
gl.EnableVertexAttribArray(vertColorAttrib)
|
||||
gl.VertexAttribPointerWithOffset(vertColorAttrib, 3, gl.FLOAT, false, 8*4, 3*4)
|
||||
|
||||
texCoordAttrib := uint32(gl.GetAttribLocation(gameWindow.GLProgram, gl.Str("vertTexCoord\x00")))
|
||||
gl.EnableVertexAttribArray(texCoordAttrib)
|
||||
gl.VertexAttribPointerWithOffset(texCoordAttrib, 2, gl.FLOAT, false, 5*4, 3*4)
|
||||
gl.VertexAttribPointerWithOffset(texCoordAttrib, 2, gl.FLOAT, false, 8*4, 6*4)
|
||||
|
||||
// Configure global settings
|
||||
gl.Enable(gl.DEPTH_TEST)
|
||||
|
@ -110,30 +115,29 @@ func run() {
|
|||
|
||||
running := true
|
||||
var angle float32 = 0.0
|
||||
var move float32 = 0.0
|
||||
for running {
|
||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
model = mgl32.Ident4()
|
||||
|
||||
move += 0.01
|
||||
|
||||
camera.Update()
|
||||
camera.Draw(gameWindow.GLProgram)
|
||||
|
||||
angle += 0.00
|
||||
angle += 0.01
|
||||
model = mgl32.HomogRotate3D(angle, mgl32.Vec3{0, 1, 0})
|
||||
|
||||
gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])
|
||||
|
||||
|
||||
// I think this is what I might need to abstract out into each Draw()
|
||||
gl.BindVertexArray(vao)
|
||||
|
||||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, texture)
|
||||
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6 * 2 * 3) // 6 sides, 2 triangles, 3 points each
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) // 6 sides, 2 triangles, 3 points each
|
||||
// end Draw()
|
||||
|
||||
gameWindow.SDLWindow.GLSwap()
|
||||
|
||||
|
||||
running = handleEvents(running, gameWindow, &camera)
|
||||
sdl.Delay(16)
|
||||
}
|
||||
|
@ -149,19 +153,6 @@ func setupLogging() {
|
|||
log.Println("=== START ===")
|
||||
}
|
||||
|
||||
func drawSDLRenderer(renderer *sdl.Renderer) {
|
||||
renderer.SetDrawColor(0, 0, 0, 255)
|
||||
renderer.Clear()
|
||||
|
||||
rect := sdl.Rect{0, 0, 100, 100}
|
||||
renderer.SetDrawColor(0, 0, 255, 255)
|
||||
renderer.DrawRect(&rect)
|
||||
|
||||
renderer.Present()
|
||||
}
|
||||
|
||||
|
||||
|
||||
func handleEvents(running bool, gameWindow *game_window.GameWindow, camera *gl_objects.Camera) bool {
|
||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||
switch t := event.(type) {
|
||||
|
@ -172,7 +163,7 @@ func handleEvents(running bool, gameWindow *game_window.GameWindow, camera *gl_o
|
|||
running = false
|
||||
case *sdl.MouseMotionEvent:
|
||||
if t.XRel != 0 || t.YRel != 0 {
|
||||
camera.Rotate(t.XRel, t.YRel)
|
||||
camera.RotateInput(t.XRel, t.YRel)
|
||||
}
|
||||
case *sdl.MouseButtonEvent:
|
||||
fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n",
|
||||
|
@ -209,7 +200,8 @@ func handleEvents(running bool, gameWindow *game_window.GameWindow, camera *gl_o
|
|||
camera.SetZVelocity(-1)
|
||||
} else if t.Type == sdl.KEYUP {
|
||||
camera.SetZVelocity(0)
|
||||
} }
|
||||
}
|
||||
}
|
||||
if t.Keysym.Sym == sdl.K_d {
|
||||
if t.Type == sdl.KEYDOWN {
|
||||
camera.SetXVelocity(1)
|
||||
|
@ -250,55 +242,3 @@ func handleEvents(running bool, gameWindow *game_window.GameWindow, camera *gl_o
|
|||
|
||||
return running
|
||||
}
|
||||
|
||||
var cubeVertices = []float32{
|
||||
// X, Y, Z, texture U, V
|
||||
// Bottom
|
||||
-1.0, -1.0, -1.0, 0.0, 0.0,
|
||||
1.0, -1.0, -1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 1.0, 0.0, 1.0,
|
||||
1.0, -1.0, -1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 1.0, 1.0, 1.0,
|
||||
-1.0, -1.0, 1.0, 0.0, 1.0,
|
||||
|
||||
// Top
|
||||
-1.0, 1.0, -1.0, 0.0, 0.0,
|
||||
-1.0, 1.0, 1.0, 0.0, 1.0,
|
||||
1.0, 1.0, -1.0, 1.0, 0.0,
|
||||
1.0, 1.0, -1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 1.0, 0.0, 1.0,
|
||||
1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
|
||||
// Front
|
||||
-1.0, -1.0, 1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 1.0, 0.0, 0.0,
|
||||
-1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
1.0, -1.0, 1.0, 0.0, 0.0,
|
||||
1.0, 1.0, 1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
|
||||
// Back
|
||||
-1.0, -1.0, -1.0, 0.0, 0.0,
|
||||
-1.0, 1.0, -1.0, 0.0, 1.0,
|
||||
1.0, -1.0, -1.0, 1.0, 0.0,
|
||||
1.0, -1.0, -1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, -1.0, 0.0, 1.0,
|
||||
1.0, 1.0, -1.0, 1.0, 1.0,
|
||||
|
||||
// Left
|
||||
-1.0, -1.0, 1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, -1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, -1.0, 0.0, 0.0,
|
||||
-1.0, -1.0, 1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
-1.0, 1.0, -1.0, 1.0, 0.0,
|
||||
|
||||
// Right
|
||||
1.0, -1.0, 1.0, 1.0, 1.0,
|
||||
1.0, -1.0, -1.0, 1.0, 0.0,
|
||||
1.0, 1.0, -1.0, 0.0, 0.0,
|
||||
1.0, -1.0, 1.0, 1.0, 1.0,
|
||||
1.0, 1.0, -1.0, 0.0, 0.0,
|
||||
1.0, 1.0, 1.0, 0.0, 1.0,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ package game_window
|
|||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/gl_helpers"
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ type GameWindow struct {
|
|||
SDLWindow *sdl.Window
|
||||
GLContext *sdl.GLContext
|
||||
GLProgram uint32
|
||||
|
||||
|
||||
fullscreen bool
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ func NewGameWindow(title string) (*GameWindow, error) {
|
|||
log.Println("Failed creating SDL window")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
context, err := window.GLCreateContext()
|
||||
if err != nil {
|
||||
log.Println("Failed Creating GL context.")
|
||||
|
@ -51,7 +51,6 @@ func NewGameWindow(title string) (*GameWindow, error) {
|
|||
}
|
||||
gl.UseProgram(program)
|
||||
|
||||
|
||||
gameWindow.SDLWindow = window
|
||||
gameWindow.GLProgram = program
|
||||
gameWindow.fullscreen = false
|
||||
|
@ -91,9 +90,12 @@ uniform mat4 projection;
|
|||
uniform mat4 camera;
|
||||
uniform mat4 model;
|
||||
in vec3 vert;
|
||||
in vec3 vertColor;
|
||||
in vec2 vertTexCoord;
|
||||
out vec3 outColor;
|
||||
out vec2 fragTexCoord;
|
||||
void main() {
|
||||
outColor = vertColor;
|
||||
fragTexCoord = vertTexCoord;
|
||||
gl_Position = projection * camera * model * vec4(vert, 1);
|
||||
}
|
||||
|
@ -103,8 +105,11 @@ var fragmentShader = `
|
|||
#version 330
|
||||
uniform sampler2D tex;
|
||||
in vec2 fragTexCoord;
|
||||
in vec3 inColor;
|
||||
out vec4 outputColor;
|
||||
void main() {
|
||||
outputColor = texture(tex, fragTexCoord);
|
||||
outputColor = vec4(inColor, 1);
|
||||
}
|
||||
` + "\x00"
|
||||
|
||||
// outputColor = texture(tex, fragTexCoord) * vec4(inColor, 1);
|
||||
|
|
|
@ -3,11 +3,11 @@ package gl_helpers
|
|||
// https://github.com/go-gl/example
|
||||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/draw"
|
||||
_ "image/png"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
|
@ -62,7 +62,7 @@ func compileShader(source string, shaderType uint32) (uint32, error) {
|
|||
var logLength int32
|
||||
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
|
||||
|
||||
log := strings.Repeat("\x00", int(logLength + 1))
|
||||
log := strings.Repeat("\x00", int(logLength+1))
|
||||
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
|
||||
|
||||
return 0, fmt.Errorf("failed to compile %v: %v", source, log)
|
||||
|
@ -76,7 +76,7 @@ func NewTexture(file string) (uint32, error) {
|
|||
if err != nil {
|
||||
return 0, fmt.Errorf("texture %q file not found found: %v", file, err)
|
||||
}
|
||||
|
||||
|
||||
img, _, err := image.Decode(imgFile)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -86,7 +86,7 @@ func NewTexture(file string) (uint32, error) {
|
|||
if rgba.Stride != rgba.Rect.Size().X*4 {
|
||||
return 0, fmt.Errorf("unsupported stride")
|
||||
}
|
||||
|
||||
|
||||
draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)
|
||||
|
||||
var texture uint32
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package gl_objects
|
||||
|
||||
import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
type Box struct {
|
||||
Size int32
|
||||
Faces []*Face
|
||||
Color mgl32.Vec3
|
||||
Position mgl32.Vec3
|
||||
TextureOn bool
|
||||
}
|
||||
|
||||
func NewBox(
|
||||
length, width, depth float32,
|
||||
position, color mgl32.Vec3, textureOn bool) *Box {
|
||||
// length = z axis (towards)
|
||||
// width = x axis (right)
|
||||
// depth = y axis (up)
|
||||
|
||||
box := Box{}
|
||||
box.Color = color
|
||||
box.Size = 6
|
||||
|
||||
topPos := mgl32.Vec3{position.X(), position.Y() + depth/2.0, position.Z()}
|
||||
top := NewFace(width, length, topPos, mgl32.Vec3{0, 1, 0}, color, textureOn)
|
||||
|
||||
bottomPos := mgl32.Vec3{position.X(), position.Y() - depth/2.0, position.Z()}
|
||||
bottom := NewFace(width, length, bottomPos, mgl32.Vec3{0, -1, 0}, color, textureOn)
|
||||
|
||||
frontPos := mgl32.Vec3{position.X(), position.Y(), position.Z() + length/2.0}
|
||||
front := NewFace(width, depth, frontPos, mgl32.Vec3{0, 0, 1}, color, textureOn)
|
||||
|
||||
backPos := mgl32.Vec3{position.X(), position.Y(), position.Z() - length/2.0}
|
||||
back := NewFace(width, depth, backPos, mgl32.Vec3{0, 0, -1}, color, textureOn)
|
||||
|
||||
rightPos := mgl32.Vec3{position.X() + width/2.0, position.Y(), position.Z()}
|
||||
right := NewFace(length, depth, rightPos, mgl32.Vec3{1, 0, 0}, color, textureOn)
|
||||
|
||||
leftPos := mgl32.Vec3{position.X() - width/2.0, position.Y(), position.Z()}
|
||||
left := NewFace(length, depth, leftPos, mgl32.Vec3{-1, 0, 0}, color, textureOn)
|
||||
|
||||
box.Faces = []*Face{
|
||||
top,
|
||||
bottom,
|
||||
front,
|
||||
back,
|
||||
right,
|
||||
left,
|
||||
}
|
||||
|
||||
return &box
|
||||
}
|
||||
|
||||
func (b *Box) GetVertexArray() []float32 {
|
||||
// Boxes have 6 faces, 2 triangles per face, 3 vertices per triangle
|
||||
// (technically 2 vertices overlap in a face, but ignore that for now)
|
||||
totalVertices := 6 * 2 * 3 * VertexSize
|
||||
a := make([]float32, totalVertices)
|
||||
|
||||
i := 0
|
||||
for _, face := range b.Faces {
|
||||
for _, triangle := range face.Triangles {
|
||||
for _, vertex := range triangle.Vertices {
|
||||
for _, elem := range vertex.GetVertexArray() {
|
||||
a[i] = elem
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
|
@ -10,30 +10,30 @@ import (
|
|||
Positive Y = up
|
||||
Positive Z = backward (outward, towards you)
|
||||
Negative Z = forwards (inward)
|
||||
*/
|
||||
*/
|
||||
|
||||
type Camera struct {
|
||||
Position mgl32.Vec3
|
||||
Direction mgl32.Vec3
|
||||
Position mgl32.Vec3
|
||||
Direction mgl32.Vec3
|
||||
OriginalDirection mgl32.Vec3
|
||||
Up mgl32.Vec3
|
||||
OriginalUp mgl32.Vec3
|
||||
Velocity mgl32.Vec3
|
||||
MoveStep float32
|
||||
RotationVelocity float32
|
||||
RotateStep float32
|
||||
MouseSensitivity float32
|
||||
Up mgl32.Vec3
|
||||
OriginalUp mgl32.Vec3
|
||||
Velocity mgl32.Vec3
|
||||
MoveStep float32
|
||||
RotationVelocity float32
|
||||
RotateStep float32
|
||||
MouseSensitivity float32
|
||||
}
|
||||
|
||||
func NewCamera() (Camera) {
|
||||
func NewCamera() Camera {
|
||||
camera := Camera{}
|
||||
camera.Up = mgl32.Vec3{0, 1, 0}
|
||||
camera.OriginalUp = mgl32.Vec3{0, 1, 0}
|
||||
camera.Direction = mgl32.Vec3{0, 0, -1}
|
||||
camera.OriginalDirection = mgl32.Vec3{0, 0, -1}
|
||||
camera.MoveStep = 0.1
|
||||
camera.RotateStep = 0.02
|
||||
camera.MouseSensitivity = 0.02
|
||||
camera.RotateStep = 0.01
|
||||
camera.MouseSensitivity = 0.06
|
||||
return camera
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,15 @@ func (c *Camera) Draw(program uint32) {
|
|||
}
|
||||
|
||||
func (c *Camera) Update() {
|
||||
c.Rotate(0, 0)
|
||||
c.Rotate()
|
||||
c.Move(c.Velocity)
|
||||
}
|
||||
|
||||
func (c *Camera) Rotate(mouseX, mouseY int32) {
|
||||
func (c *Camera) Rotate() {
|
||||
c.RotateInput(0, 0)
|
||||
}
|
||||
|
||||
func (c *Camera) RotateInput(mouseX, mouseY int32) {
|
||||
angle := mgl32.Vec3{}
|
||||
// X Rotation (pitch) - mouse up/down
|
||||
angle[0] = -1 * float32(mouseY) * c.MouseSensitivity
|
||||
|
@ -69,7 +73,7 @@ func (c *Camera) Rotate(mouseX, mouseY int32) {
|
|||
relativeY := c.Up
|
||||
relativeZ := c.Direction
|
||||
relativeX := relativeZ.Cross(relativeY)
|
||||
|
||||
|
||||
quatX := mgl32.QuatRotate(angle.X(), relativeX)
|
||||
c.Up = quatX.Rotate(c.Up)
|
||||
c.Direction = quatX.Rotate(c.Direction)
|
||||
|
@ -90,11 +94,11 @@ func (c *Camera) Move(vec mgl32.Vec3) {
|
|||
|
||||
vec = vec.Normalize()
|
||||
vec = vec.Mul(c.MoveStep)
|
||||
|
||||
|
||||
perp := c.Direction.Cross(c.Up)
|
||||
relativeY := c.Up.Mul(vec.Y())
|
||||
relativeZ := c.Direction.Mul(vec.Z())
|
||||
relativeX := perp.Mul(vec.X())
|
||||
relativeY := c.Up.Mul(vec.Y())
|
||||
relativeZ := c.Direction.Mul(vec.Z())
|
||||
relativeX := perp.Mul(vec.X())
|
||||
|
||||
relativeMove := mgl32.Vec3{}
|
||||
relativeMove = relativeMove.Add(relativeX)
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package gl_objects
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
|
||||
"gitea.wisellama.rocks/carpy-breakout/pkg/math_helpers"
|
||||
)
|
||||
|
||||
type Face struct {
|
||||
Triangles []*Triangle
|
||||
}
|
||||
|
||||
func NewFace(
|
||||
width, height float32,
|
||||
center, normal mgl32.Vec3,
|
||||
color mgl32.Vec3, textureOn bool) *Face {
|
||||
|
||||
// TODO texture
|
||||
texture := mgl32.Vec2{0, 0}
|
||||
|
||||
// top left
|
||||
v1 := newFaceVertex(
|
||||
height/2.0,
|
||||
-1*width/2.0,
|
||||
center,
|
||||
normal,
|
||||
color,
|
||||
texture)
|
||||
|
||||
// bottom left
|
||||
v2 := newFaceVertex(
|
||||
-1*height/2.0,
|
||||
-1*width/2.0,
|
||||
center,
|
||||
normal,
|
||||
color,
|
||||
texture)
|
||||
|
||||
// bottom right
|
||||
v3 := newFaceVertex(
|
||||
-1*height/2.0,
|
||||
width/2.0,
|
||||
center,
|
||||
normal,
|
||||
color,
|
||||
texture)
|
||||
|
||||
// top right
|
||||
v4 := newFaceVertex(
|
||||
height/2.0,
|
||||
width/2.0,
|
||||
center,
|
||||
normal,
|
||||
color,
|
||||
texture)
|
||||
|
||||
t1 := NewTriangle(v1, v2, v3)
|
||||
t2 := NewTriangle(v3, v4, v1)
|
||||
|
||||
face := Face{}
|
||||
face.Triangles = []*Triangle{t1, t2}
|
||||
|
||||
return &face
|
||||
}
|
||||
|
||||
func newFaceVertex(
|
||||
xoffset, zoffset float32,
|
||||
center, normal mgl32.Vec3,
|
||||
color mgl32.Vec3, texture mgl32.Vec2) *Vertex {
|
||||
// We'll create the face as though the normal were simply upward
|
||||
// {0, 1, 0} and then rotate all the points to fit the actual
|
||||
// normal.
|
||||
|
||||
// Create the vertex offset from the center
|
||||
v := mgl32.Vec3{center.X() + xoffset, center.Y(), center.Z() + zoffset}
|
||||
// Subtract the center to create a vector pointing out so we can rotate it
|
||||
v = v.Sub(center)
|
||||
|
||||
up := mgl32.Vec3{0, 1, 0}
|
||||
angle, err := math_helpers.AngleBetweenVectors(up, normal)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
}
|
||||
rotationAxis := up.Cross(normal)
|
||||
|
||||
// rotate
|
||||
quat := mgl32.QuatRotate(angle, rotationAxis)
|
||||
v = quat.Rotate(v)
|
||||
|
||||
// add back the center so we get the correct absolute position
|
||||
v = v.Add(center)
|
||||
|
||||
log.Println(v)
|
||||
|
||||
vertex := NewVertex(
|
||||
v.X(), v.Y(), v.Z(),
|
||||
color[0], color[1], color[2],
|
||||
texture[0], texture[1])
|
||||
|
||||
return vertex
|
||||
}
|
||||
|
||||
func (f *Face) GetVertexArray() []float32 {
|
||||
a := make([]float32, 2*3*VertexSize)
|
||||
|
||||
for _, triangle := range f.Triangles {
|
||||
for _, vertex := range triangle.Vertices {
|
||||
a = append(a, vertex.GetVertexArray()...)
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package gl_objects
|
||||
|
||||
type globject interface {
|
||||
Update()
|
||||
Draw(uint32)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package gl_objects
|
||||
|
||||
type Triangle struct {
|
||||
Vertices []*Vertex
|
||||
}
|
||||
|
||||
func NewTriangle(a, b, c *Vertex) *Triangle {
|
||||
triangle := Triangle{}
|
||||
triangle.Vertices = []*Vertex{a, b, c}
|
||||
|
||||
return &triangle
|
||||
}
|
||||
|
||||
func (t *Triangle) GetVertexArray() []float32 {
|
||||
a := make([]float32, 3*VertexSize)
|
||||
|
||||
for _, vertex := range t.Vertices {
|
||||
a = append(a, vertex.GetVertexArray()...)
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package gl_objects
|
||||
|
||||
import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
const VertexSize int32 = 8
|
||||
|
||||
type Vertex struct {
|
||||
Position mgl32.Vec3
|
||||
Color mgl32.Vec3
|
||||
Texture mgl32.Vec2
|
||||
}
|
||||
|
||||
func NewVertex(x, y, z, r, g, b, u, v float32) *Vertex {
|
||||
vertex := Vertex{}
|
||||
vertex.Position = mgl32.Vec3{x, y, z}
|
||||
vertex.Color = mgl32.Vec3{r, g, b}
|
||||
vertex.Texture = mgl32.Vec2{u, v}
|
||||
return &vertex
|
||||
}
|
||||
|
||||
func (v *Vertex) GetVertexArray() []float32 {
|
||||
a := make([]float32, VertexSize)
|
||||
|
||||
a[0] = v.Position[0]
|
||||
a[1] = v.Position[1]
|
||||
a[2] = v.Position[2]
|
||||
|
||||
a[3] = v.Color[0]
|
||||
a[4] = v.Color[1]
|
||||
a[5] = v.Color[2]
|
||||
|
||||
a[6] = v.Texture[0]
|
||||
a[7] = v.Texture[1]
|
||||
|
||||
return a
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package math_helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
func AngleBetweenVectors(v1, v2 mgl32.Vec3) (float32, error) {
|
||||
len1 := v1.LenSqr()
|
||||
len2 := v2.LenSqr()
|
||||
if len1 == 0 || len2 == 0 {
|
||||
return 0.0, fmt.Errorf("AngleBetweenVectors given zero length vector")
|
||||
}
|
||||
|
||||
if len1 != 1 {
|
||||
v1 = v1.Normalize()
|
||||
}
|
||||
|
||||
if len2 != 1 {
|
||||
v2 = v2.Normalize()
|
||||
}
|
||||
|
||||
dotProd := v1.Dot(v2)
|
||||
angle := math.Acos(float64(dotProd))
|
||||
|
||||
return float32(angle), nil
|
||||
}
|
Loading…
Reference in New Issue