Fix bugs with the targets/boxes being created.

Fully understand the shader after reading OpenGL Superbible.

Attempted to cross compile for windows, but it fails on the shader compile for some reason.
main
Sean Hickey 2021-10-31 02:04:02 -07:00
parent 4bafcb2957
commit c11dc24b68
11 changed files with 205 additions and 95 deletions

View File

@ -4,7 +4,10 @@ dependencies:
go mod tidy
build: dependencies
go build
go build -x -v
release: dependencies
go build -ldflags "-s -w"
go build -x -v -ldflags "-s -w"
cross_windows:
./build_cross_windows.sh

13
build_cross_windows.sh Executable file
View File

@ -0,0 +1,13 @@
#!/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 GOOS=windows
export GOARCH=386
#export CGO_LDFLAGS="-lmingw32 -lSDL2 -lSDL2main"
#export CGO_CFLAGS="-I/usr/x86_64-w64-mingw32/include -D_REENTRANT"
#go build -x -v -ldflags "-s -w"
go build -x -v

15
main.go
View File

@ -52,7 +52,8 @@ func main() {
}
func runOpenGL() {
err := sdl.Init(sdl.INIT_EVERYTHING)
var sdlInitFlags uint32 = sdl.INIT_TIMER | sdl.INIT_AUDIO | sdl.INIT_VIDEO | sdl.INIT_EVENTS | sdl.INIT_JOYSTICK | sdl.INIT_HAPTIC | sdl.INIT_GAMECONTROLLER // ignore sensor subsystem
err := sdl.Init(sdlInitFlags)
if err != nil {
log.Fatal(err)
}
@ -68,8 +69,8 @@ func runOpenGL() {
sdl.SetRelativeMouseMode(true)
// Init and configure global settings
sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 2) // Smooth
gl.Init()
sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 2) // Smooth
gameWindow, err := game_window.NewGameWindow(GameTitle)
if err != nil {
@ -77,11 +78,11 @@ func runOpenGL() {
}
defer gameWindow.Destroy()
sunLight := gl_objects.NewDirectionalLight(mgl32.Vec3{1, -1, -1})
sunLight := gl_objects.NewPointLight(mgl32.Vec3{-10, 10, 30})
sunLight.GLInit(gameWindow.GLProgram)
camera := gl_objects.NewCamera(gameWindow.GLProgram)
camera.Position = mgl32.Vec3{0, 0, 60}
camera.Position = mgl32.Vec3{0, 0, 30}
gameWindow.SetCamera(camera)
gameWindow.AddObject(camera)
@ -93,7 +94,7 @@ func runOpenGL() {
// TODO bounding box
// Brick Targets
targets := breakout.NewTargets(4, 5, mgl32.Vec3{-8, 4, 0})
targets := breakout.NewTargets(4, 5, mgl32.Vec3{0, 6, 0})
targets.GLInit(gameWindow.GLProgram)
for _, brick := range targets.Bricks {
gameWindow.AddObject(brick)
@ -105,7 +106,7 @@ func runOpenGL() {
// Paddle
paddleMaterial := gl_objects.NewMaterial()
paddleMaterial.Color = mgl32.Vec3{0, 1, 0}
paddleMaterial.Color = mgl32.Vec4{0, 1, 0, 1}
paddle := gl_objects.NewBox(6.0, 1.0, 4.0, mgl32.Vec3{0, -6, 0}, paddleMaterial)
paddle.GLInit(gameWindow.GLProgram)
gameWindow.AddObject(paddle)
@ -113,7 +114,7 @@ func runOpenGL() {
// Ball
ballMaterial := gl_objects.NewMaterial()
ballMaterial.Color = mgl32.Vec3{1, 1, 1}
ballMaterial.Color = mgl32.Vec4{1, 1, 1, 1}
ball := gl_objects.NewBox(1, 1, 1, mgl32.Vec3{-8, 0, 0}, ballMaterial)
ball.GLInit(gameWindow.GLProgram)
gameWindow.AddObject(ball)

View File

@ -12,7 +12,7 @@ type Targets struct {
Bricks []*Brick
}
func NewTargets(numRows, numColumns int, lowerLeftPos mgl32.Vec3) *Targets {
func NewTargets(numRows, numColumns int, adjustPos mgl32.Vec3) *Targets {
targets := Targets{
Rows: numRows,
Columns: numColumns,
@ -23,13 +23,26 @@ func NewTargets(numRows, numColumns int, lowerLeftPos mgl32.Vec3) *Targets {
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)
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.Vec3{red, 0, blue}
m.Color = mgl32.Vec4{red, 0, blue, 1}
materials[i] = m
}
@ -37,8 +50,8 @@ func NewTargets(numRows, numColumns int, lowerLeftPos mgl32.Vec3) *Targets {
for i := 0; i < numRows; i++ {
for j := 0; j < numColumns; j++ {
position := lowerLeftPos.Add(mgl32.Vec3{
float32(j) * brickWidth,
float32(i) * brickHeight,
float32(j) * bw,
float32(i) * bh,
0})
targets.Bricks[n] = NewBrick(brickWidth, brickHeight, brickDepth, position, materials[i])
n++

View File

@ -1,89 +1,99 @@
package gl_helpers
var FragmentShaderSource = `
#version 140
var FragmentShaderSource string = `
#version 330
in vec3 fragPos;
in vec3 fragNormal;
precision mediump float;
// Inputs
smooth in vec3 fragNormal;
in vec2 fragTexCoord;
smooth in vec3 lightDir;
// Outputs
out vec4 outputColor;
struct Material {
sampler2D textureDiffuse;
sampler2D textureSpecular;
float shininess;
vec3 color;
vec4 color;
int textureOn; // if textureOn == 0, then just color is used
};
struct DirectionalLight {
vec3 direction;
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform DirectionalLight dirLight;
uniform Light light;
uniform Material material;
uniform vec3 cameraPos;
uniform int lightsOn;
vec3 GetTextureDiffuse();
vec3 GetTextureSpecular();
vec3 DirectionalLightColor(DirectionalLight light, vec3 normal, vec3 viewDir);
vec4 GetTextureDiffuse();
vec4 GetTextureSpecular();
vec4 LightColor(Light light, vec3 normal, vec3 viewDir);
void main() {
vec3 normal = normalize(fragNormal);
vec3 viewDir = normalize(fragPos - cameraPos);
vec3 directionalLightColor;
if (lightsOn != 0) {
directionalLightColor = DirectionalLightColor(dirLight, normal, viewDir);
} else {
directionalLightColor = material.color;
vec4 lightColor;
if (lightsOn != 0) {
lightColor = LightColor(light, normal, lightDir);
} else {
lightColor = material.color;
}
if (lightColor.a < 0.1f) {
discard;
}
outputColor = vec4(directionalLightColor, 1);
outputColor = lightColor;
}
vec3 GetTextureDiffuse() {
vec3 t = material.color;
vec4 GetTextureDiffuse() {
vec4 t = material.color;
if (material.textureOn != 0) {
t = t * vec3(texture(material.textureDiffuse, fragTexCoord));
t = t * vec4(texture(material.textureDiffuse, fragTexCoord));
}
return t;
}
vec3 GetTextureSpecular() {
vec3 t = material.color;
vec4 GetTextureSpecular() {
vec4 t = material.color;
if (material.textureOn != 0) {
t = t * vec3(texture(material.textureSpecular, fragTexCoord));
t = t * vec4(texture(material.textureSpecular, fragTexCoord));
}
return t;
}
vec3 DirectionalLightColor(DirectionalLight light, vec3 normal, vec3 viewDir)
vec4 LightColor(Light light, vec3 normal, vec3 lightDir)
{
vec3 lightDir = normalize(light.direction);
lightDir = normalize(lightDir);
normal = normalize(normal);
// Diffuse
float diffuseAmount = max(dot(normal, -lightDir), 0.0);
float diffuseAmount = max(dot(normal, lightDir), 0.0);
// Specular
vec3 reflectDir = reflect(-lightDir, normal);
float specularAmount = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 reflectDir = normalize(reflect(-lightDir, normal));
float specularAmount = max(dot(normal, reflectDir), 0.0);
// Textures
vec3 tDiffuse = GetTextureDiffuse();
vec3 tSpecular = GetTextureSpecular();
if (diffuseAmount != 0) {
specularAmount = pow(specularAmount, material.shininess);
}
// Multiply to get each value, then add to get the final result
vec3 a = light.ambient * tDiffuse;
vec3 d = light.diffuse * diffuseAmount * tDiffuse;
vec3 s = light.specular * specularAmount * tSpecular;
// Textures
vec4 tDiffuse = GetTextureDiffuse();
vec4 tSpecular = GetTextureSpecular();
// Multiply to get each value, then add to get the final result
vec4 a = light.ambient * tDiffuse;
vec4 d = light.diffuse * diffuseAmount * tDiffuse;
vec4 s = light.specular * specularAmount * tSpecular;
return (a + d + s);
}
` + "\x00"
`

View File

@ -56,7 +56,8 @@ func NewProgram(vertexShaderSource string, fragmentShaderSource string) (uint32,
func compileShader(source string, shaderType uint32) (uint32, error) {
shader := gl.CreateShader(shaderType)
csources, free := gl.Strs(source)
sourceWithZero := source + "\x00"
csources, free := gl.Strs(sourceWithZero)
gl.ShaderSource(shader, 1, csources, nil)
free()
gl.CompileShader(shader)
@ -154,6 +155,11 @@ func SetUniformVec3f(glProgram uint32, name string, v mgl32.Vec3) {
gl.Uniform3f(location, v.X(), v.Y(), v.Z())
}
func SetUniformVec4f(glProgram uint32, name string, v mgl32.Vec4) {
location := gl.GetUniformLocation(glProgram, GLStr(name))
gl.Uniform4f(location, v.X(), v.Y(), v.Z(), v.W())
}
func SetUniformMatrix4f(glProgram uint32, name string, m *mgl32.Mat4) {
location := gl.GetUniformLocation(glProgram, GLStr(name))
gl.UniformMatrix4fv(location, 1, false, &m[0])

View File

@ -1,24 +1,51 @@
package gl_helpers
var VertexShaderSource = `
#version 140
uniform mat4 projection;
uniform mat4 camera;
uniform mat4 model;
// Adapted from the OpenGL Superbible
var VertexShaderSource string = `
#version 330
precision mediump float;
struct Light {
vec3 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform mat4 model; // Model
uniform mat4 camera; // View
uniform mat4 projection; // Projection
uniform Light light;
// Inputs
in vec3 vertPos;
in vec3 vertNormal;
in vec2 vertTexCoord;
out vec3 fragPos;
out vec3 fragNormal;
// Outputs
smooth out vec3 fragNormal;
out vec2 fragTexCoord;
smooth out vec3 lightDir;
void main() {
fragPos = vec3(model * vec4(vertPos, 1));
fragNormal = mat3(transpose(inverse(model))) * vertNormal;
// Get the surface normal in eye coordinates
fragNormal = mat3(transpose(inverse(model))) * vertNormal;
fragNormal = normalize(fragNormal);
// Get the vertex position in eye coordinates
vec3 position3 = vec3(model * vec4(vertPos, 1));
// Get the vector to the light source(s)
lightDir = light.position - position3;
lightDir = normalize(lightDir);
// Pass through the texture coordinates
fragTexCoord = vertTexCoord;
gl_Position = projection * camera * vec4(fragPos, 1);
// Transform the geometry
gl_Position = projection * camera * vec4(position3, 1);
}
` + "\x00"
`

View File

@ -35,30 +35,31 @@ func NewBox(
// height = y axis (up)
box := Box{
Size: 6,
Width: width,
Depth: depth,
Height: height,
Translation: position,
Material: material,
Size: 6,
Width: width,
Depth: depth,
Height: height,
Translation: position,
Material: material,
RotationVelocity: mgl32.Vec3{0, 0, 0},
}
topPos := mgl32.Vec3{position.X(), position.Y() + height/2.0, position.Z()}
topPos := mgl32.Vec3{0, height / 2.0, 0}
top := NewFace(width, depth, topPos, mgl32.Vec3{0, 1, 0}, material)
bottomPos := mgl32.Vec3{position.X(), position.Y() - height/2.0, position.Z()}
bottomPos := mgl32.Vec3{0, -height / 2.0, 0}
bottom := NewFace(width, depth, bottomPos, mgl32.Vec3{0, -1, 0}, material)
frontPos := mgl32.Vec3{position.X(), position.Y(), position.Z() + depth/2.0}
frontPos := mgl32.Vec3{0, 0, depth / 2.0}
front := NewFace(width, height, frontPos, mgl32.Vec3{0, 0, 1}, material)
backPos := mgl32.Vec3{position.X(), position.Y(), position.Z() - depth/2.0}
backPos := mgl32.Vec3{0, 0, -depth / 2.0}
back := NewFace(width, height, backPos, mgl32.Vec3{0, 0, -1}, material)
rightPos := mgl32.Vec3{position.X() + width/2.0, position.Y(), position.Z()}
rightPos := mgl32.Vec3{width / 2.0, 0, 0}
right := NewFace(height, depth, rightPos, mgl32.Vec3{1, 0, 0}, material)
leftPos := mgl32.Vec3{position.X() - width/2.0, position.Y(), position.Z()}
leftPos := mgl32.Vec3{-width / 2.0, 0, 0}
left := NewFace(height, depth, leftPos, mgl32.Vec3{-1, 0, 0}, material)
box.Faces = []*Face{
@ -97,12 +98,16 @@ func (b *Box) Update() {
func (b *Box) GLDraw() {
// Apply rotation
rotate := mgl32.HomogRotate3D(b.Rotation.Y(), mgl32.Vec3{0, 1, 0})
rotateX := mgl32.HomogRotate3D(b.Rotation.X(), mgl32.Vec3{1, 0, 0})
rotateY := mgl32.HomogRotate3D(b.Rotation.Y(), mgl32.Vec3{0, 1, 0})
rotateZ := mgl32.HomogRotate3D(b.Rotation.Z(), mgl32.Vec3{0, 0, 1})
rotate := rotateX.Mul4(rotateY)
rotate = rotate.Mul4(rotateZ)
// Apply translation
translate := mgl32.Translate3D(b.Translation.X(), b.Translation.Y(), b.Translation.Z())
model := rotate.Add(translate)
model := translate.Mul4(rotate)
gl_helpers.SetUniformMatrix4f(b.GLProgram, "model", &model)

View File

@ -6,27 +6,27 @@ import (
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/gl_helpers"
)
// Directional Light (e.g. the Sun)
// Directional Light
type DirectionalLight struct {
Direction mgl32.Vec3 // the direction the light is travelling from the sun
AmbientColor mgl32.Vec3
DiffuseColor mgl32.Vec3
SpecularColor mgl32.Vec3
AmbientColor mgl32.Vec4
DiffuseColor mgl32.Vec4
SpecularColor mgl32.Vec4
}
func NewDirectionalLight(direction mgl32.Vec3) *DirectionalLight {
d := DirectionalLight{
Direction: direction,
AmbientColor: mgl32.Vec3{0.2, 0.2, 0.2},
DiffuseColor: mgl32.Vec3{1, 1, 1},
SpecularColor: mgl32.Vec3{1, 1, 1},
AmbientColor: mgl32.Vec4{0.1, 0.1, 0.1, 1},
DiffuseColor: mgl32.Vec4{1, 1, 1, 1},
SpecularColor: mgl32.Vec4{1, 1, 1, 1},
}
return &d
}
func (l *DirectionalLight) GLInit(glProgram uint32) {
gl_helpers.SetUniformVec3f(glProgram, "dirLight.ambient", l.AmbientColor)
gl_helpers.SetUniformVec3f(glProgram, "dirLight.diffuse", l.DiffuseColor)
gl_helpers.SetUniformVec3f(glProgram, "dirLight.specular", l.SpecularColor)
gl_helpers.SetUniformVec3f(glProgram, "dirLight.direction", l.Direction)
gl_helpers.SetUniformVec4f(glProgram, "dirLight.ambient", l.AmbientColor)
gl_helpers.SetUniformVec4f(glProgram, "dirLight.diffuse", l.DiffuseColor)
gl_helpers.SetUniformVec4f(glProgram, "dirLight.specular", l.SpecularColor)
}

View File

@ -10,15 +10,15 @@ type Material struct {
TextureDiffuse int32
TextureSpecular int32
Shininess float32
Color mgl32.Vec3
Color mgl32.Vec4
TextureOn bool
TextureId uint32
}
func NewMaterial() *Material {
m := Material{
Shininess: 64.0,
Color: mgl32.Vec3{1, 1, 1},
Shininess: 128.0,
Color: mgl32.Vec4{1, 1, 1, 1},
TextureOn: false,
}
@ -30,7 +30,7 @@ func (m *Material) GLDraw(glProgram uint32) {
gl_helpers.SetUniformInt(glProgram, "material.textureSpecular", m.TextureSpecular)
gl_helpers.SetUniformFloat(glProgram, "material.shininess", m.Shininess)
gl_helpers.SetUniformVec3f(glProgram, "material.color", m.Color)
gl_helpers.SetUniformVec4f(glProgram, "material.color", m.Color)
var tOn int32 = 0
if m.TextureOn {

View File

@ -0,0 +1,32 @@
package gl_objects
import (
"github.com/go-gl/mathgl/mgl32"
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/gl_helpers"
)
// Point Light
type PointLight struct {
Position mgl32.Vec3
AmbientColor mgl32.Vec4
DiffuseColor mgl32.Vec4
SpecularColor mgl32.Vec4
}
func NewPointLight(position mgl32.Vec3) *PointLight {
d := PointLight{
Position: position,
AmbientColor: mgl32.Vec4{0.1, 0.1, 0.1, 1},
DiffuseColor: mgl32.Vec4{1, 1, 1, 1},
SpecularColor: mgl32.Vec4{1, 1, 1, 1},
}
return &d
}
func (l *PointLight) GLInit(glProgram uint32) {
gl_helpers.SetUniformVec3f(glProgram, "light.position", l.Position)
gl_helpers.SetUniformVec4f(glProgram, "light.ambient", l.AmbientColor)
gl_helpers.SetUniformVec4f(glProgram, "light.diffuse", l.DiffuseColor)
gl_helpers.SetUniformVec4f(glProgram, "light.specular", l.SpecularColor)
}