diff --git a/examples/models/gltf_loading/main.go b/examples/models/gltf_loading/main.go new file mode 100644 index 0000000..26f3120 --- /dev/null +++ b/examples/models/gltf_loading/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(1280) + screenHeight := int32(720) + + rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - gltf loading") + + camera := rl.Camera{} + camera.Position = rl.NewVector3(5.0, 5.0, 5.0) + camera.Target = rl.NewVector3(0.0, 2.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Fovy = 45.0 + camera.Projection = rl.CameraPerspective + + model := rl.LoadModel("robot.glb") + + animIndex := 0 + animCurrentFrame := 0 + + modelAnims := rl.LoadModelAnimations("robot.glb") + + position := rl.NewVector3(0, 0, 0) + rl.DisableCursor() + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + rl.UpdateCamera(&camera, rl.CameraOrbital) + + if rl.IsKeyPressed(rl.KeyUp) { + animIndex++ + if animIndex >= len(modelAnims) { + animIndex = 0 + } + } + if rl.IsKeyPressed(rl.KeyDown) { + animIndex-- + if animIndex < 0 { + animIndex = len(modelAnims) - 1 + } + } + + animPlaying := modelAnims[animIndex] + animCurrentFrame = (animCurrentFrame + 1) % int(animPlaying.FrameCount) + rl.UpdateModelAnimation(model, animPlaying, int32(animCurrentFrame)) + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginMode3D(camera) + + rl.DrawModel(model, position, 0.8, rl.White) + + rl.EndMode3D() + + rl.DrawText("current animation number: "+fmt.Sprint(animIndex), 10, 10, 10, rl.Black) + rl.DrawText("UP/DOWN ARROW KEYS CHANGE ANIMATION", 10, 30, 10, rl.Black) + + rl.EndDrawing() + } + + rl.UnloadModel(model) + + rl.CloseWindow() +} diff --git a/examples/models/gltf_loading/robot.glb b/examples/models/gltf_loading/robot.glb new file mode 100644 index 0000000..549011e Binary files /dev/null and b/examples/models/gltf_loading/robot.glb differ diff --git a/examples/models/mesh_generation/main.go b/examples/models/mesh_generation/main.go new file mode 100644 index 0000000..d7c7da1 --- /dev/null +++ b/examples/models/mesh_generation/main.go @@ -0,0 +1,102 @@ +package main + +import ( + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(1280) + screenHeight := int32(720) + + numModels := 8 + + rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation") + + camera := rl.Camera{} + camera.Position = rl.NewVector3(10.0, 5.0, 10.0) + camera.Target = rl.NewVector3(0.0, 0.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Fovy = 45.0 + camera.Projection = rl.CameraPerspective + + checked := rl.GenImageChecked(2, 2, 1, 1, rl.Black, rl.Red) + texture := rl.LoadTextureFromImage(checked) + rl.UnloadImage(checked) + + models := make([]rl.Model, numModels) + + models[0] = rl.LoadModelFromMesh(rl.GenMeshPlane(2, 2, 4, 3)) + models[1] = rl.LoadModelFromMesh(rl.GenMeshCube(2, 1, 2)) + models[2] = rl.LoadModelFromMesh(rl.GenMeshSphere(2, 32, 32)) + models[3] = rl.LoadModelFromMesh(rl.GenMeshHemiSphere(2, 16, 16)) + models[4] = rl.LoadModelFromMesh(rl.GenMeshCylinder(1, 2, 16)) + models[5] = rl.LoadModelFromMesh(rl.GenMeshTorus(0.25, 4, 16, 32)) + models[6] = rl.LoadModelFromMesh(rl.GenMeshKnot(1, 2, 16, 128)) + models[7] = rl.LoadModelFromMesh(rl.GenMeshPoly(5, 2)) + + for i := 0; i < numModels; i++ { + rl.SetMaterialTexture(models[i].Materials, rl.MapDiffuse, texture) + } + + position := rl.Vector3Zero() + + currentModel := 0 + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + rl.UpdateCamera(&camera, rl.CameraOrbital) + + if rl.IsKeyPressed(rl.KeyUp) { + currentModel++ + if currentModel >= numModels { + currentModel = 0 + } + } + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginMode3D(camera) + + rl.DrawModel(models[currentModel], position, 1, rl.White) + rl.DrawGrid(10, 1) + + rl.EndMode3D() + + rl.DrawRectangle(10, 10, 310, 30, rl.Fade(rl.SkyBlue, 0.5)) + rl.DrawRectangleLines(10, 10, 310, 30, rl.Fade(rl.DarkBlue, 0.5)) + rl.DrawText("UP ARROW KEY TO CHANGE MODELS", 20, 20, 10, rl.Blue) + + txt := "PLANE" + switch currentModel { + case 1: + txt = "CUBE" + case 2: + txt = "SPHERE" + case 3: + txt = "HEMISPHERE" + case 4: + txt = "CYLINDER" + case 5: + txt = "TORUS" + case 6: + txt = "KNOT" + case 7: + txt = "POLY" + } + txtlen := rl.MeasureText(txt, 20) + rl.DrawText(txt, screenWidth/2-txtlen/2, 10, 20, rl.DarkBlue) + + rl.EndDrawing() + } + + rl.UnloadTexture(texture) + for i := 0; i < numModels; i++ { + rl.UnloadModel(models[i]) + } + + rl.CloseWindow() +} diff --git a/examples/models/vox_loading/knight.vox b/examples/models/vox_loading/knight.vox new file mode 100644 index 0000000..c921bf5 Binary files /dev/null and b/examples/models/vox_loading/knight.vox differ diff --git a/examples/models/vox_loading/main.go b/examples/models/vox_loading/main.go new file mode 100644 index 0000000..93aaf35 --- /dev/null +++ b/examples/models/vox_loading/main.go @@ -0,0 +1,82 @@ +package main + +import ( + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(1280) + screenHeight := int32(720) + + rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - voxel loading") + + camera := rl.Camera{} + camera.Position = rl.NewVector3(10.0, 10.0, 10.0) + camera.Target = rl.NewVector3(0.0, 0.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Fovy = 45.0 + camera.Projection = rl.CameraPerspective + + voxFiles := []string{"knight.vox", "sword.vox", "monument.vox"} + + var models []rl.Model + + for i := 0; i < len(voxFiles); i++ { + models = append(models, rl.LoadModel(voxFiles[i])) + bb := rl.GetModelBoundingBox(models[i]) + center := rl.Vector3Zero() + center.X = bb.Min.X + ((bb.Max.X - bb.Min.X) / 2) + center.Z = bb.Min.Z + ((bb.Max.Z - bb.Min.Z) / 2) + + matTranslate := rl.MatrixTranslate(-center.X, 0, -center.Z) + models[i].Transform = matTranslate + } + + currentModel := 0 + + rl.DisableCursor() + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + rl.UpdateCamera(&camera, rl.CameraOrbital) + + if rl.IsKeyPressed(rl.KeyUp) { + currentModel++ + if currentModel >= len(models) { + currentModel = 0 + } + + } + if rl.IsKeyPressed(rl.KeyDown) { + currentModel-- + if currentModel < 0 { + currentModel = len(models) - 1 + } + + } + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginMode3D(camera) + + rl.DrawModel(models[currentModel], rl.Vector3Zero(), 1, rl.White) + + rl.EndMode3D() + + rl.DrawText("current voxel file: "+voxFiles[currentModel], 10, 10, 10, rl.Black) + rl.DrawText("UP/DOWN ARROW KEYS CHANGE FILE", 10, 30, 10, rl.Black) + rl.DrawText("MOUSE SCROLL OR KEYPAD + / - TO CHANGE ZOOM", 10, 50, 10, rl.Black) + + rl.EndDrawing() + } + + for i := 0; i < len(models); i++ { + rl.UnloadModel(models[i]) + } + + rl.CloseWindow() +} diff --git a/examples/models/vox_loading/monument.vox b/examples/models/vox_loading/monument.vox new file mode 100644 index 0000000..fd77111 Binary files /dev/null and b/examples/models/vox_loading/monument.vox differ diff --git a/examples/models/vox_loading/sword.vox b/examples/models/vox_loading/sword.vox new file mode 100644 index 0000000..05fc482 Binary files /dev/null and b/examples/models/vox_loading/sword.vox differ diff --git a/examples/models/waving_cubes/main.go b/examples/models/waving_cubes/main.go new file mode 100644 index 0000000..c86de19 --- /dev/null +++ b/examples/models/waving_cubes/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "math" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(1280) + screenHeight := int32(720) + + rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - waving cubes") + + camera := rl.Camera{} + camera.Position = rl.NewVector3(30.0, 20.0, 30.0) + camera.Target = rl.NewVector3(0.0, 0.0, 0.0) + camera.Up = rl.NewVector3(0.0, 1.0, 0.0) + camera.Fovy = 70.0 + camera.Projection = rl.CameraPerspective + + numBloks := 15 + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + time := rl.GetTime() + + scale := (2 + float32(math.Sin(time))) * 0.7 + + camTime := time * 0.3 + + camera.Position.X = float32(math.Cos(camTime)) * 40 + camera.Position.Z = float32(math.Sin(camTime)) * 40 + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginMode3D(camera) + + rl.DrawGrid(10, 5) + + for x := 0; x < numBloks; x++ { + + for y := 0; y < numBloks; y++ { + + for z := 0; z < numBloks; z++ { + + blockScale := float32((x + y + z)) / 30 + + scatter := math.Sin(float64(blockScale*20) + (time * 4)) + + cubePos := rl.NewVector3(float32((x-numBloks/2))*(scale*3)+float32(scatter), float32((y-numBloks/2))*(scale*2)+float32(scatter), float32((z-numBloks/2))*(scale*3)+float32(scatter)) + + cubeColor := rl.ColorFromHSV(float32(((x+y+z)*18)%360), 0.75, 0.9) + + cubeSize := (2.4 - scale) * blockScale + + rl.DrawCube(cubePos, cubeSize, cubeSize, cubeSize, cubeColor) + + } + } + } + + rl.EndMode3D() + + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + rl.CloseWindow() +} diff --git a/examples/shaders/eratosthenes/eratosthenes.fs b/examples/shaders/eratosthenes/eratosthenes.fs new file mode 100644 index 0000000..644e38d --- /dev/null +++ b/examples/shaders/eratosthenes/eratosthenes.fs @@ -0,0 +1,59 @@ +#version 330 + +/************************************************************************************* + + The Sieve of Eratosthenes -- a simple shader by ProfJski + An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + + The screen is divided into a square grid of boxes, each representing an integer value. + Each integer is tested to see if it is a prime number. Primes are colored white. + Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer. + + You can change the scale variable to make a larger or smaller grid. + Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers. + + WARNING: If you make scale too large, your GPU may bog down! + +***************************************************************************************/ + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Output fragment color +out vec4 finalColor; + +// Make a nice spectrum of colors based on counter and maxSize +vec4 Colorizer(float counter, float maxSize) +{ + float red = 0.0, green = 0.0, blue = 0.0; + float normsize = counter/maxSize; + + red = smoothstep(0.3, 0.7, normsize); + green = sin(3.14159*normsize); + blue = 1.0 - smoothstep(0.0, 0.4, normsize); + + return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0); +} + +void main() +{ + vec4 color = vec4(1.0); + float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. + int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values + + if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0); + else + { + for (int i = 2; (i < max(2, sqrt(value) + 1)); i++) + { + if ((value - i*floor(float(value)/float(i))) == 0) + { + color = Colorizer(float(i), scale); + //break; // Uncomment to color by the largest factor instead + } + } + + finalColor = color; + } +} diff --git a/examples/shaders/eratosthenes/main.go b/examples/shaders/eratosthenes/main.go new file mode 100644 index 0000000..c813e7e --- /dev/null +++ b/examples/shaders/eratosthenes/main.go @@ -0,0 +1,42 @@ +package main + +import ( + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(800) + screenHeight := int32(450) + + rl.InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Eratosthenes") + + shader := rl.LoadShader("", "eratosthenes.fs") + target := rl.LoadRenderTexture(screenWidth, screenHeight) + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + rl.BeginTextureMode(target) + rl.ClearBackground(rl.Black) + rl.DrawRectangle(0, 0, int32(rl.GetScreenWidth()), int32(rl.GetScreenHeight()), rl.Black) + rl.EndTextureMode() + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginShaderMode(shader) + + rl.DrawTextureRec(target.Texture, rl.NewRectangle(0, 0, float32(target.Texture.Width), float32(target.Texture.Height)), rl.Vector2Zero(), rl.White) + + rl.EndShaderMode() + + rl.EndDrawing() + } + + rl.UnloadShader(shader) + rl.UnloadRenderTexture(target) + + rl.CloseWindow() +} diff --git a/examples/shaders/texture_outline/gopher.png b/examples/shaders/texture_outline/gopher.png new file mode 100644 index 0000000..8347cee Binary files /dev/null and b/examples/shaders/texture_outline/gopher.png differ diff --git a/examples/shaders/texture_outline/main.go b/examples/shaders/texture_outline/main.go new file mode 100644 index 0000000..8b2b6d8 --- /dev/null +++ b/examples/shaders/texture_outline/main.go @@ -0,0 +1,65 @@ +package main + +import ( + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + screenWidth := int32(800) + screenHeight := int32(450) + + rl.InitWindow(screenWidth, screenHeight, "raylib [shaders] example - texture outline") + + texture := rl.LoadTexture("gopher.png") + + shader := rl.LoadShader("", "outline.fs") + + cnt := rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2)) + + outlineSize := []float32{2} + outlineColor := []float32{1, 0, 0, 1} + textureSize := []float32{float32(texture.Width), float32(texture.Height)} + + outlineSizeLoc := rl.GetShaderLocation(shader, "outlineSize") + outlineColorLoc := rl.GetShaderLocation(shader, "outlineColor") + textureSizeLoc := rl.GetShaderLocation(shader, "textureSize") + + rl.SetShaderValue(shader, outlineSizeLoc, outlineSize, rl.ShaderUniformFloat) + rl.SetShaderValue(shader, outlineColorLoc, outlineColor, rl.ShaderUniformVec4) + rl.SetShaderValue(shader, textureSizeLoc, textureSize, rl.ShaderUniformVec2) + + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + + if rl.IsKeyPressed(rl.KeyUp) { + outlineSize[0]++ + } else if rl.IsKeyPressed(rl.KeyDown) { + outlineSize[0]-- + if outlineSize[0] < 1 { + outlineSize[0] = 1 + } + } + + rl.SetShaderValue(shader, outlineSizeLoc, outlineSize, rl.ShaderUniformFloat) + + rl.BeginDrawing() + + rl.ClearBackground(rl.RayWhite) + + rl.BeginShaderMode(shader) + + rl.DrawTexture(texture, int32(cnt.X)-texture.Width/2, int32(cnt.Y)-texture.Height/2, rl.White) + + rl.EndShaderMode() + + rl.DrawText("UP/DOWN ARROW KEYS INCREASE OUTLINE THICKNESS", 10, 10, 10, rl.Black) + + rl.EndDrawing() + } + + rl.UnloadShader(shader) + rl.UnloadTexture(texture) + + rl.CloseWindow() +} diff --git a/examples/shaders/texture_outline/outline.fs b/examples/shaders/texture_outline/outline.fs new file mode 100644 index 0000000..2584a21 --- /dev/null +++ b/examples/shaders/texture_outline/outline.fs @@ -0,0 +1,35 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +uniform vec2 textureSize; +uniform float outlineSize; +uniform vec4 outlineColor; + +// Output fragment color +out vec4 finalColor; + +void main() +{ + vec4 texel = texture(texture0, fragTexCoord); // Get texel color + vec2 texelScale = vec2(0.0); + texelScale.x = outlineSize/textureSize.x; + texelScale.y = outlineSize/textureSize.y; + + // We sample four corner texels, but only for the alpha channel (this is for the outline) + vec4 corners = vec4(0.0); + corners.x = texture(texture0, fragTexCoord + vec2(texelScale.x, texelScale.y)).a; + corners.y = texture(texture0, fragTexCoord + vec2(texelScale.x, -texelScale.y)).a; + corners.z = texture(texture0, fragTexCoord + vec2(-texelScale.x, texelScale.y)).a; + corners.w = texture(texture0, fragTexCoord + vec2(-texelScale.x, -texelScale.y)).a; + + float outline = min(dot(corners, vec4(1.0)), 1.0); + vec4 color = mix(vec4(0.0), outlineColor, outline); + finalColor = mix(color, texel, texel.a); +} \ No newline at end of file