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/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/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