Watch
2
0
Fork
You've already forked raylib-cs
0
raylib-cs/Examples/Shaders/DepthRendering.cs
2026-07-29 19:58:47 +02:00

223 lines
7.8 KiB
C#

/*******************************************************************************************
*
* raylib [shaders] example - depth rendering
*
* Example complexity rating: [★★★☆] 3/4
*
* Example originally created with raylib 6.0, last time updated with raylib 6.0
*
* Example contributed by Luís Almeida (@luis605) and reviewed by Ramon Santamaria (@raysan5)
*
* 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) 2025 Luís Almeida (@luis605)
*
********************************************************************************************/
namespace Examples.Shaders;
public class DepthRendering : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
#if BROWSER
const int GlslVersion = 100; // WebGL1 needs GLSL ES 100
#else
private const int GlslVersion = 330;
#endif
public string Name => "Shaders / Depth Rendering";
public string Title => "raylib [shaders] example - depth rendering";
public bool CursorDisabled => true;
private Camera3D camera;
private RenderTexture2D target;
private Shader depthShader;
private int depthLoc;
private Model cube;
private Model floor;
public void Init()
{
// Define the camera to look into our 3d world
camera = new();
camera.Position = new Vector3(4.0f, 1.0f, 5.0f);
camera.Target = new Vector3(0.0f, 0.0f, 0.0f);
camera.Up = new Vector3(0.0f, 1.0f, 0.0f);
camera.FovY = 45.0f;
camera.Projection = CameraProjection.Perspective;
// Load render texture with a depth texture attached
target = LoadRenderTextureDepthTex(screenWidth, screenHeight);
// Load depth shader and get depth texture shader location
depthShader = LoadShader(null, $"resources/shaders/glsl{GlslVersion}/depth_render.fs");
depthLoc = GetShaderLocation(depthShader, "depthTexture");
var flipTextureLoc = GetShaderLocation(depthShader, "flipY");
Raylib.SetShaderValue(depthShader, flipTextureLoc, 1, ShaderUniformDataType.Int); // Flip Y texture
// Load scene models
cube = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
floor = LoadModelFromMesh(GenMeshPlane(20.0f, 20.0f, 1, 1));
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(ref camera, CameraMode.Free);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginTextureMode(target);
ClearBackground(Color.White);
BeginMode3D(camera);
DrawModel(cube, new Vector3(0.0f, 0.0f, 0.0f), 3.0f, Color.Yellow);
DrawModel(floor, new Vector3(10.0f, 0.0f, 2.0f), 2.0f, Color.Red);
EndMode3D();
EndTextureMode();
// Draw into screen (main framebuffer)
BeginDrawing();
ClearBackground(Color.RayWhite);
BeginShaderMode(depthShader);
SetShaderValueTexture(depthShader, depthLoc, target.Depth);
DrawTexture(target.Depth, 0, 0, Color.White);
EndShaderMode();
DrawRectangle(10, 10, 320, 93, Fade(Color.SkyBlue, 0.5f));
DrawRectangleLines(10, 10, 320, 93, Color.Blue);
DrawText("Camera Controls:", 20, 20, 10, Color.Black);
DrawText("- WASD to move", 40, 40, 10, Color.DarkGray);
DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, Color.DarkGray);
DrawText("- Z to zoom to (0, 0, 0)", 40, 80, 10, Color.DarkGray);
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
UnloadModel(cube); // Unload model
UnloadModel(floor); // Unload model
UnloadRenderTextureDepthTex(target);
UnloadShader(depthShader); // Unload shader
}
// Load custom render texture, create a writable depth texture buffer
private static unsafe RenderTexture2D LoadRenderTextureDepthTex(int width, int height)
{
RenderTexture2D target = new();
// Load an empty framebuffer
target.Id = Rlgl.LoadFramebuffer();
if (target.Id > 0)
{
Rlgl.EnableFramebuffer(target.Id);
// Create color texture (default to RGBA)
target.Texture.Id = Rlgl.LoadTexture(
null,
width,
height,
PixelFormat.UncompressedR8G8B8A8,
1
);
target.Texture.Width = width;
target.Texture.Height = height;
target.Texture.Format = PixelFormat.UncompressedR8G8B8A8;
target.Texture.Mipmaps = 1;
// Create depth texture buffer (instead of raylib default renderbuffer)
target.Depth.Id = Rlgl.LoadTextureDepth(width, height, false);
target.Depth.Width = width;
target.Depth.Height = height;
target.Depth.Format = PixelFormat.CompressedPvrtRgba; // DEPTH_COMPONENT_24BIT: Not defined in raylib
target.Depth.Mipmaps = 1;
// Attach color texture and depth texture to FBO
Rlgl.FramebufferAttach(
target.Id,
target.Texture.Id,
FramebufferAttachType.ColorChannel0,
FramebufferAttachTextureType.Texture2D,
0
);
Rlgl.FramebufferAttach(
target.Id,
target.Depth.Id,
FramebufferAttachType.Depth,
FramebufferAttachTextureType.Texture2D,
0
);
// Check if fbo is complete with attachments (valid)
if (Rlgl.FramebufferComplete(target.Id) != 0)
{
TraceLog(TraceLogLevel.Info, $"FBO: [ID {target.Id}] Framebuffer object created successfully");
}
Rlgl.DisableFramebuffer();
}
else
{
TraceLog(TraceLogLevel.Warning, "FBO: Framebuffer object can not be created");
}
return target;
}
// Unload render texture from GPU memory (VRAM)
private static void UnloadRenderTextureDepthTex(RenderTexture2D target)
{
if (target.Id > 0)
{
// Color texture attached to FBO is deleted
Rlgl.UnloadTexture(target.Texture.Id);
Rlgl.UnloadTexture(target.Depth.Id);
// NOTE: Depth texture is automatically
// queried and deleted before deleting framebuffer
Rlgl.UnloadFramebuffer(target.Id);
}
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - depth rendering");
DisableCursor(); // Limit cursor to relative movement inside the window
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
var game = new DepthRendering();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}