Fix license.

Fix lighting.

Start bounding box, not working yet.
main
Sean Hickey 2021-11-21 23:36:51 -08:00
parent 26ae65e90b
commit 897ea4222c
13 changed files with 193 additions and 63 deletions

View File

@ -21,6 +21,11 @@ to my fragment shader. I had learned the Phong shading model at
university, but this showed me how to actually apply it with OpenGL
shaders.
[The OpenGL SuperBible][7] is a book that I've had for over a
decade. After finally wrapping my head around shaders from
LearnOpenGL.com, I went back to this book and reworked a lot of the
lighting models to get them into a much more understandable state.
[1]: https://open.gl/introduction
[2]: https://learnopengl.com/Lighting/Basic-Lighting
@ -28,3 +33,4 @@ shaders.
[4]: https://github.com/veandco/go-sdl2
[5]: https://github.com/veandco/go-sdl2-examples
[6]: https://github.com/go-gl/example
[7]: https://www.opengl.org/sdk/docs/books/SuperBible/

View File

@ -1,4 +1,4 @@
all: build
all: release
dependencies:
go mod tidy
@ -10,4 +10,15 @@ release: dependencies
go build -x -v -ldflags "-s -w"
cross_windows:
./build_cross_windows.sh
export CGO_ENABLED=1
export CC=x86_64-w64-mingw32-gcc
export GOOS=windows
export GOARCH=amd64
go build -x -v -ldflags "-s -w"
cross_windows_x86:
export CGO_ENABLED=1
export CC=i686-w64-mingw32-gcc
export GOOS=windows
export GOARCH=386
go build -x -v -ldflags "-s -w"

View File

@ -8,13 +8,13 @@ and OpenGL stuff. It ended up being a bit nicer than I expected.
## License/Copyright
This project is licensed under the [ISC License][1], a permissive open
source license. Essentially you can use this code for any purpose so
long as you acknowledge me for creating it. You can find the full text
in `License.md`.
This project is licensed under the [2-Clause BSD License][1], a
permissive open source license. Essentially you can use this code for
any purpose so long as you acknowledge me for creating it. You can
find the full text in `License.md`.
Another file called `Attribution.md` contains links to the other
projects used to build this one.
[1]: https://opensource.org/licenses/ISC
[1]: https://opensource.org/licenses/BSD-2-Clause

View File

@ -1,11 +1,11 @@
#!/usr/bin/env sh
export CGO_ENABLED=1
export CC=i686-w64-mingw32-gcc
#export CC=x86_64-w64-mingw32-gcc
#export CXX=x86_64-w64-mingw32-g++
#export CC=i686-w64-mingw32-gcc
export CC=x86_64-w64-mingw32-gcc
export GOOS=windows
export GOARCH=386
#export GOARCH=386
export GOARCH=amd64
#export CGO_LDFLAGS="-lmingw32 -lSDL2 -lSDL2main"
#export CGO_CFLAGS="-I/usr/x86_64-w64-mingw32/include -D_REENTRANT"

2
go.mod
View File

@ -3,7 +3,7 @@ module gitea.wisellama.rocks/Wisellama/carpy-breakout
go 1.17
require (
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784
github.com/go-gl/mathgl v1.0.0
github.com/veandco/go-sdl2 v0.4.10
)

4
go.sum
View File

@ -1,5 +1,5 @@
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 h1:1Zi56D0LNfvkzM+BdoxKryvUEdyWO7LP8oRT+oSYJW0=
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
github.com/go-gl/mathgl v1.0.0 h1:t9DznWJlXxxjeeKLIdovCOVJQk/GzDEL7h/h+Ro2B68=
github.com/go-gl/mathgl v1.0.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=

77
main.go
View File

@ -17,8 +17,6 @@ import (
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
var openglMode = flag.Bool("opengl", true, "Draw game using OpenGL rendering")
var sdlMode = flag.Bool("sdl", false, "Draw game using SDL rendering")
const GameTitle = "Carpy Breakout"
const LogFile = "output.log"
@ -44,11 +42,7 @@ func main() {
// goroutine.
runtime.LockOSThread()
if *sdlMode {
runSDL()
} else if *openglMode {
runOpenGL()
}
runOpenGL()
}
func runOpenGL() {
@ -59,18 +53,7 @@ func runOpenGL() {
}
defer sdl.Quit()
// Disable the Linux compositor flicker.
// https://github.com/mosra/magnum/issues/184#issuecomment-425952900
sdl.SetHint(sdl.HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")
sdl.DisableScreenSaver()
// Capture the mouse for movement
sdl.SetRelativeMouseMode(true)
// Init and configure global settings
gl.Init()
sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 2) // Smooth
sdlSettings()
gameWindow, err := game_window.NewGameWindow(GameTitle)
if err != nil {
@ -78,6 +61,20 @@ func runOpenGL() {
}
defer gameWindow.Destroy()
// GL Init requires an active OpenGL context (e.g. the game window)
err = gl.Init()
if err != nil {
log.Fatalf("Failed to initialize OpenGL: %v", err)
}
glVersion := gl.GetString(gl.VERSION)
if glVersion == nil {
log.Printf("Error getting OpenGL version.\n")
}
log.Printf("OpenGL Version: %v\n", gl.GoStr(glVersion))
// Then we can setup the OpenGL specific stuff in the game window
gameWindow.GLInit()
sunLight := gl_objects.NewPointLight(mgl32.Vec3{-10, 10, 30})
sunLight.GLInit(gameWindow.GLProgram)
@ -91,19 +88,22 @@ func runOpenGL() {
// log.Fatal(err)
// }
// TODO bounding box
// Brick Targets
targets := breakout.NewTargets(4, 5, mgl32.Vec3{0, 6, 0})
targets.GLInit(gameWindow.GLProgram)
for _, brick := range targets.Bricks {
gameWindow.AddObject(brick)
}
positiveBoundary := mgl32.Vec3{8, 16, 0}
negativeBoundary := mgl32.Vec3{-8, -16, 0}
positiveBoundary := targets.TopRight
negativeBoundary := positiveBoundary.Mul(-1)
gameWindow.PositiveBoundary = positiveBoundary
gameWindow.NegativeBoundary = negativeBoundary
// Bounding Box
boundingBoxMaterial := gl_objects.NewMaterial()
boundingBoxMaterial.Color = mgl32.Vec4{0.3, 0.3, 0.3, 1}
boundingBox := breakout.NewBoundingBox(negativeBoundary, positiveBoundary, boundingBoxMaterial)
// Paddle
paddleMaterial := gl_objects.NewMaterial()
paddleMaterial.Color = mgl32.Vec4{0, 1, 0, 1}
@ -119,12 +119,7 @@ func runOpenGL() {
ball.GLInit(gameWindow.GLProgram)
gameWindow.AddObject(ball)
// Global options after setup is all done
gl.ClearColor(0.0, 0.0, 0.0, 1.0)
gl.Enable(gl.DEPTH_TEST)
gl.DepthFunc(gl.LESS)
gl.LineWidth(2.0)
glSettings()
for gameWindow.IsRunning() {
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
@ -148,7 +143,25 @@ func setupLogging() {
log.Println("=== START ===")
}
func runSDL() {
// I really need to think through how to separate the physical objects from how they are drawn.
log.Println("TODO runSDL()")
func glSettings() {
// Global options after setup is all done
gl.ClearColor(0.0, 0.0, 0.0, 1.0)
gl.Enable(gl.DEPTH_TEST)
gl.DepthFunc(gl.LESS)
gl.LineWidth(2.0)
}
func sdlSettings() {
// Smooth
sdl.GLSetAttribute(sdl.GL_MULTISAMPLEBUFFERS, 1)
sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 4)
// Disable the Linux compositor flicker.
// https://github.com/mosra/magnum/issues/184#issuecomment-425952900
sdl.SetHint(sdl.HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")
sdl.DisableScreenSaver()
// Capture the mouse for movement
sdl.SetRelativeMouseMode(true)
}

View File

@ -0,0 +1,80 @@
package breakout
import (
"github.com/go-gl/mathgl/mgl32"
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/gl_objects"
)
type BoundingBox struct {
Boxes []*gl_objects.Box
}
func NewBoundingBox(lowerLeft, topRight mgl32.Vec3, material gl_objects.Material) *BoundingBox {
var brickWidth float32 = 4.0
var brickHeight float32 = 1.0
var brickDepth float32 = 4.0
var widthOffset float32 = 0.5
var heightOffset float32 = 1
bw := brickWidth + widthOffset
bh := brickHeight + heightOffset
lowerLeftPos := mgl32.Vec3{
bw/2 - float32(numColumns)*(bw)/2,
bh/2 - float32(numRows)*(bh)/2,
0,
}
lowerLeftPos = lowerLeftPos.Add(adjustPos)
topRightPos := mgl32.Vec3{
bw/2 + float32(numColumns)*(bw)/2,
bh/2 + float32(numRows)*(bh)/2,
0,
}
topRightPos = topRightPos.Add(adjustPos)
targets.TopRight = topRightPos
targets.LowerLeft = lowerLeftPos
materials := make([]*gl_objects.Material, numColumns)
for i := 0; i < numColumns; i++ {
red := 0 + float32(i)/float32(numColumns)
blue := 1 - float32(i)/float32(numColumns)
m := gl_objects.NewMaterial()
m.Color = mgl32.Vec4{red, 0, blue, 1}
materials[i] = m
}
n := 0
for i := 0; i < numRows; i++ {
for j := 0; j < numColumns; j++ {
position := lowerLeftPos.Add(mgl32.Vec3{
float32(j) * bw,
float32(i) * bh,
0})
targets.Bricks[n] = NewBrick(brickWidth, brickHeight, brickDepth, position, materials[i])
n++
}
}
boundingBox := BoundingBox{
Boxes: boxes,
}
return &boundingBox
}
func (t *BoundingBox) GLInit(glProgram uint32) {
for _, brick := range t.Bricks {
brick.GLInit(glProgram)
}
}
func (t *BoundingBox) GLDraw() {
for _, brick := range t.Bricks {
brick.GLDraw()
}
}

View File

@ -7,9 +7,11 @@ import (
)
type Targets struct {
Rows int
Columns int
Bricks []*Brick
Rows int
Columns int
Bricks []*Brick
TopRight mgl32.Vec3
LowerLeft mgl32.Vec3
}
func NewTargets(numRows, numColumns int, adjustPos mgl32.Vec3) *Targets {
@ -36,6 +38,16 @@ func NewTargets(numRows, numColumns int, adjustPos mgl32.Vec3) *Targets {
}
lowerLeftPos = lowerLeftPos.Add(adjustPos)
topRightPos := mgl32.Vec3{
bw/2 + float32(numColumns)*(bw)/2,
bh/2 + float32(numRows)*(bh)/2,
0,
}
topRightPos = topRightPos.Add(adjustPos)
targets.TopRight = topRightPos
targets.LowerLeft = lowerLeftPos
materials := make([]*gl_objects.Material, numColumns)
for i := 0; i < numColumns; i++ {

View File

@ -52,6 +52,7 @@ func NewGameWindow(title string) (*GameWindow, error) {
log.Println("Failed creating SDL window")
return nil, err
}
gameWindow.SDLWindow = window
context, err := window.GLCreateContext()
if err != nil {
@ -60,18 +61,20 @@ func NewGameWindow(title string) (*GameWindow, error) {
}
gameWindow.GLContext = &context
return &gameWindow, err
}
func (w *GameWindow) GLInit() error {
program, err := gl_helpers.NewDefaultProgram()
if err != nil {
panic(err)
return err
}
gl.UseProgram(program)
gameWindow.SDLWindow = window
gameWindow.GLProgram = program
w.GLProgram = program
gameWindow.WindowProjection()
return &gameWindow, err
w.WindowProjection()
return nil
}
func (w *GameWindow) AddObject(object gl_objects.GLObject) {

View File

@ -23,16 +23,22 @@ func NewProgram(vertexShaderSource string, fragmentShaderSource string) (uint32,
if err != nil {
return 0, err
}
defer gl.DeleteShader(vertexShader)
fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
if err != nil {
return 0, err
}
defer gl.DeleteShader(fragmentShader)
program := gl.CreateProgram()
gl.AttachShader(program, vertexShader)
defer gl.DetachShader(program, vertexShader)
gl.AttachShader(program, fragmentShader)
defer gl.DetachShader(program, fragmentShader)
gl.LinkProgram(program)
var status int32
@ -47,19 +53,20 @@ func NewProgram(vertexShaderSource string, fragmentShaderSource string) (uint32,
return 0, fmt.Errorf("failed to link program: %v", log)
}
gl.DeleteShader(vertexShader)
gl.DeleteShader(fragmentShader)
return program, nil
}
func compileShader(source string, shaderType uint32) (uint32, error) {
shader := gl.CreateShader(shaderType)
if shader == 0 {
return 0, fmt.Errorf("Error creating shader - type: %v", shaderType)
}
sourceWithZero := source + "\x00"
csources, free := gl.Strs(sourceWithZero)
defer free()
gl.ShaderSource(shader, 1, csources, nil)
free()
gl.CompileShader(shader)
var status int32

View File

@ -30,7 +30,6 @@ func NewFace(
center,
normal,
mgl32.Vec2{0, 1})
v1_2 := *v1
// bottom left
v2 := newFaceVertex(
@ -47,7 +46,6 @@ func NewFace(
center,
normal,
mgl32.Vec2{1, 0})
v3_2 := *v3
// top right
v4 := newFaceVertex(
@ -58,7 +56,7 @@ func NewFace(
mgl32.Vec2{1, 1})
t1 := NewTriangle(v1, v2, v3)
t2 := NewTriangle(&v3_2, v4, &v1_2)
t2 := NewTriangle(v3, v4, v1)
face := Face{
Material: material,

View File

@ -17,7 +17,7 @@ type PointLight struct {
func NewPointLight(position mgl32.Vec3) *PointLight {
d := PointLight{
Position: position,
AmbientColor: mgl32.Vec4{0.1, 0.1, 0.1, 1},
AmbientColor: mgl32.Vec4{0.2, 0.2, 0.2, 1},
DiffuseColor: mgl32.Vec4{1, 1, 1, 1},
SpecularColor: mgl32.Vec4{1, 1, 1, 1},
}