diff --git a/examples/models/skybox/main.go b/examples/models/skybox/main.go new file mode 100644 index 0000000..f43d633 --- /dev/null +++ b/examples/models/skybox/main.go @@ -0,0 +1,125 @@ +package main + +import ( + "fmt" + "path/filepath" + "unsafe" + + rl "github.com/gen2brain/raylib-go/raylib" +) + +func main() { + skyboxFilename := "skybox.png" + + rl.InitWindow(800, 450, "raylib [models] example - skybox loading and drawing") + + camera := rl.NewCamera3D( + rl.NewVector3(1.0, 1.0, 1.0), + rl.NewVector3(4.0, 1.0, 4.0), + rl.NewVector3(0.0, 1.0, 0.0), + 45.0, + rl.CameraPerspective, + ) + + // load skybox shader and set required locations + skyboxShader := rl.LoadShader("skybox.vs", "skybox.fs") + + setShaderIntValue(skyboxShader, "environmentMap", rl.MapCubemap) + + // load skybox model + cube := rl.GenMeshCube(1.0, 1.0, 1.0) + skybox := rl.LoadModelFromMesh(cube) + + skybox.Materials.Shader = skyboxShader + + // load cubemap texture + skyboxImg := rl.LoadImage(skyboxFilename) + + skyboxTexture := rl.LoadTextureCubemap(skyboxImg, rl.CubemapLayoutAutoDetect) + + rl.UnloadImage(skyboxImg) + + rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture) + + // limit cursor to relative movement inside the window + rl.DisableCursor() + + // set our game to run at 60 frames-per-second + rl.SetTargetFPS(60) + + for !rl.WindowShouldClose() { + rl.UpdateCamera(&camera, rl.CameraFirstPerson) + + // load new cubemap texture on drag&drop + if rl.IsFileDropped() { + droppedFiles := rl.LoadDroppedFiles() + + // only support one file dropped + if len(droppedFiles) == 1 { + switch filepath.Ext(droppedFiles[0]) { + case ".png", ".jpg", ".bmp", ".tga": + skyboxFilename = droppedFiles[0] + + rl.UnloadTexture(skyboxTexture) + + img := rl.LoadImage(skyboxFilename) + + skyboxTexture = rl.LoadTextureCubemap(img, rl.CubemapLayoutAutoDetect) + + rl.UnloadImage(img) + + rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture) + } + } + + rl.UnloadDroppedFiles() + } + + rl.BeginDrawing() + + rl.ClearBackground(rl.White) + + rl.BeginMode3D(camera) + + // we are inside the cube, we need to disable backface culling + rl.DisableBackfaceCulling() + rl.DisableDepthMask() + + rl.DrawModel(skybox, rl.NewVector3(0, 0, 0), 1.0, rl.White) + + // restore depth and backface culling + rl.EnableBackfaceCulling() + rl.EnableDepthMask() + + rl.DrawGrid(10, 1.0) + + rl.EndMode3D() + + rl.DrawText( + fmt.Sprintf("File: %s", skyboxFilename), + 10, + int32(rl.GetScreenHeight()-20), + 10, + rl.Black, + ) + + rl.DrawFPS(10, 10) + + rl.EndDrawing() + } + + rl.UnloadModel(skybox) + rl.UnloadTexture(skyboxTexture) + rl.UnloadShader(skyboxShader) + + rl.CloseWindow() +} + +func setShaderIntValue(shader rl.Shader, name string, value int32) { + rl.SetShaderValue( + shader, + rl.GetShaderLocation(shader, name), + unsafe.Slice((*float32)(unsafe.Pointer(&value)), 4), + rl.ShaderUniformInt, + ) +} diff --git a/examples/models/skybox/skybox.fs b/examples/models/skybox/skybox.fs new file mode 100644 index 0000000..25ae075 --- /dev/null +++ b/examples/models/skybox/skybox.fs @@ -0,0 +1,19 @@ +#version 330 + +// input vertex attributes (from vertex shader) +in vec3 fragPosition; + +// input uniform values +uniform samplerCube environmentMap; + +// output fragment color +out vec4 finalColor; + +void main() +{ + // fetch color from texture map + vec3 color = texture(environmentMap, fragPosition).rgb; + + // calculate final fragment color + finalColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/examples/models/skybox/skybox.png b/examples/models/skybox/skybox.png new file mode 100644 index 0000000..36a79b2 Binary files /dev/null and b/examples/models/skybox/skybox.png differ diff --git a/examples/models/skybox/skybox.vs b/examples/models/skybox/skybox.vs new file mode 100644 index 0000000..e43c329 --- /dev/null +++ b/examples/models/skybox/skybox.vs @@ -0,0 +1,24 @@ +#version 330 + +// input vertex attributes +in vec3 vertexPosition; + +// input uniform values +uniform mat4 matProjection; +uniform mat4 matView; + +// output vertex attributes (to fragment shader) +out vec3 fragPosition; + +void main() +{ + // calculate fragment position based on model transformations + fragPosition = vertexPosition; + + // remove translation from the view matrix + mat4 rotView = mat4(mat3(matView)); + vec4 clipPos = matProjection*rotView*vec4(vertexPosition, 1.0); + + // calculate final vertex position + gl_Position = clipPos; +} \ No newline at end of file