/******************************************************************************************* * * raylib [models] example - rlgl module usage with push/pop matrix transformations * * NOTE: This example uses [rlgl] module functionality (pseudo-OpenGL 1.1 style coding) * * Example originally created with raylib 2.5, last time updated with raylib 4.0 * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * * Copyright (c) 2018-2024 Ramon Santamaria (@raysan5) * ********************************************************************************************/ package main import ( "math" rl "github.com/gen2brain/raylib-go/raylib" ) const ( screenWidth = 800 screenHeight = 450 sunRadius = 4.0 earthRadius = 0.6 moonRadius = 0.16 earthOrbitRadius = 8.0 moonOrbitRadius = 1.5 rings, slices = 16, 16 ) func main() { // Initialization title := "raylib [models] example - rlgl module usage with push/pop matrix transformations" rl.InitWindow(screenWidth, screenHeight, title) // Define the camera to look into our 3d world camera := rl.Camera{ Position: rl.Vector3{ X: 16.0, Y: 16.0, Z: 16.0, }, // Camera position Target: rl.Vector3{}, // Camera looking at point Up: rl.Vector3{Y: 1.0}, // Camera up vector (rotation towards target) Fovy: 45.0, // Camera field-of-view Y Projection: rl.CameraPerspective, // Camera projection type } var rotationSpeed float32 = 0.2 // General system rotation speed var earthRotation float32 // Rotation of earth around itself (days) in degrees var earthOrbitRotation float32 // Rotation of earth around the Sun (years) in degrees var moonRotation float32 // Rotation of moon around itself var moonOrbitRotation float32 // Rotation of moon around earth in degrees rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second // Main game loop for !rl.WindowShouldClose() { // Detect window close button or ESC key // Update rl.UpdateCamera(&camera, rl.CameraOrbital) earthRotation += 5.0 * rotationSpeed earthOrbitRotation += 365 / 360.0 * (5.0 * rotationSpeed) * rotationSpeed moonRotation += 2.0 * rotationSpeed moonOrbitRotation += 8.0 * rotationSpeed // Draw rl.BeginDrawing() rl.ClearBackground(rl.RayWhite) rl.BeginMode3D(camera) rl.PushMatrix() rl.Scalef(sunRadius, sunRadius, sunRadius) // Scale Sun DrawSphereBasic(rl.Gold) // Draw the Sun rl.PopMatrix() rl.PushMatrix() rl.Rotatef(earthOrbitRotation, 0.0, 1.0, 0.0) // Rotation for Earth orbit around Sun rl.Translatef(earthOrbitRadius, 0.0, 0.0) // Translation for Earth orbit rl.PushMatrix() rl.Rotatef(earthRotation, 0.25, 1.0, 0.0) // Rotation for Earth itself rl.Scalef(earthRadius, earthRadius, earthRadius) // Scale Earth DrawSphereBasic(rl.Blue) // Draw the Earth rl.PopMatrix() rl.Rotatef(moonOrbitRotation, 0.0, 1.0, 0.0) // Rotation for Moon orbit around Earth rl.Translatef(moonOrbitRadius, 0.0, 0.0) // Translation for Moon orbit rl.Rotatef(moonRotation, 0.0, 1.0, 0.0) // Rotation for Moon itself rl.Scalef(moonRadius, moonRadius, moonRadius) // Scale Moon DrawSphereBasic(rl.LightGray) // Draw the Moon rl.PopMatrix() // Some reference elements (not affected by previous matrix transformations) rl.DrawCircle3D(rl.Vector3{}, earthOrbitRadius, rl.NewVector3(1, 0, 0), 90.0, rl.Fade(rl.Red, 0.5)) rl.DrawGrid(20, 1.0) rl.EndMode3D() rl.DrawText("EARTH ORBITING AROUND THE SUN!", 400, 10, 20, rl.Maroon) rl.DrawFPS(10, 10) rl.EndDrawing() } // De-Initialization rl.CloseWindow() // Close window and OpenGL context } // DrawSphereBasic draws a sphere without any matrix transformation // NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f func DrawSphereBasic(color rl.Color) { // Make sure there is enough space in the internal render batch // buffer to store all required vertex, batch is reset if required rl.CheckRenderBatchLimit((rings + 2) * slices * 6) rl.Begin(rl.Triangles) rl.Color4ub(color.R, color.G, color.B, color.A) for ring := int32(0); ring < (rings + 2); ring++ { for slice := int32(0); slice < slices; slice++ { rl.Vertex3f(getCoords(ring, slice)) rl.Vertex3f(getCoords(ring+1, slice+1)) rl.Vertex3f(getCoords(ring+1, slice)) rl.Vertex3f(getCoords(ring, slice)) rl.Vertex3f(getCoords(ring, slice+1)) rl.Vertex3f(getCoords(ring+1, slice+1)) } } rl.End() } func getCoords(ring, slice int32) (x, y, z float32) { ringF := float64(ring) sliceF := float64(slice) // Calculate angels alpha := rl.Deg2rad * (270 + (180/(float64(rings)+1))*ringF) beta := rl.Deg2rad * (sliceF * 360 / float64(slices)) // Calculate coords x = float32(math.Cos(alpha) * math.Sin(beta)) y = float32(math.Sin(alpha)) z = float32(math.Cos(alpha) * math.Cos(beta)) return x, y, z }