-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[rmodels] More performant point cloud rendering with `DrawModelPoints…
…()` (#4203) * Added the ability to draw a model as a point cloud * Added example to demonstrate drawing a model as a point cloud * polished the demo a bit * picture for example * adhere to conventions for example * update png to match aspect ratio * minor changes * address code convention comments * added point rendering to makefiles * added point rendering to readme and renumbered examples * comment formatting --------- Co-authored-by: Reese Gallagher <[email protected]> Co-authored-by: Ray <[email protected]>
- Loading branch information
1 parent
b0c3013
commit 7bde76c
Showing
7 changed files
with
224 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/******************************************************************************************* | ||
* | ||
* raylib example - point rendering | ||
* | ||
* Example originally created with raylib 5.0, last time updated with raylib 5.0 | ||
* | ||
* Example contributed by Reese Gallagher (@satchelfrost) 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) 2024 Reese Gallagher (@satchelfrost) | ||
* | ||
********************************************************************************************/ | ||
|
||
#include "raylib.h" | ||
#include <stdlib.h> // Required for: rand() | ||
#include <math.h> // Required for: cos(), sin() | ||
|
||
#define MAX_POINTS 10000000 // 10 million | ||
#define MIN_POINTS 1000 // 1 thousand | ||
|
||
static float RandFloat(); | ||
|
||
//------------------------------------------------------------------------------------ | ||
// Program main entry point | ||
//------------------------------------------------------------------------------------ | ||
int main() | ||
{ | ||
// Initialization | ||
//-------------------------------------------------------------------------------------- | ||
const int screenWidth = 800; | ||
const int screenHeight = 450; | ||
InitWindow(screenWidth, screenHeight, "raylib [models] example - point rendering"); | ||
SetTargetFPS(60); | ||
|
||
Camera camera = { | ||
.position = {3.0f, 3.0f, 3.0f}, | ||
.target = {0.0f, 0.0f, 0.0f}, | ||
.up = {0.0f, 1.0f, 0.0f}, | ||
.fovy = 45.0f, | ||
.projection = CAMERA_PERSPECTIVE, | ||
}; | ||
|
||
Vector3 position = {0.0f, 0.0f, 0.0f}; | ||
bool useDrawModelPoints = true; | ||
bool numPointsChanged = false; | ||
int numPoints = 1000; | ||
Mesh mesh = GenPoints(numPoints); | ||
Model model = LoadModelFromMesh(mesh); | ||
//-------------------------------------------------------------------------------------- | ||
|
||
// Main game loop | ||
while(!WindowShouldClose()) | ||
{ | ||
// Update | ||
//---------------------------------------------------------------------------------- | ||
UpdateCamera(&camera, CAMERA_ORBITAL); | ||
|
||
if (IsKeyPressed(KEY_SPACE)) useDrawModelPoints = !useDrawModelPoints; | ||
if (IsKeyPressed(KEY_UP)) | ||
{ | ||
numPoints = (numPoints * 10 > MAX_POINTS) ? MAX_POINTS : numPoints * 10; | ||
numPointsChanged = true; | ||
TraceLog(LOG_INFO, "num points %d", numPoints); | ||
} | ||
if (IsKeyPressed(KEY_DOWN)) | ||
{ | ||
numPoints = (numPoints / 10 < MIN_POINTS) ? MIN_POINTS : numPoints / 10; | ||
numPointsChanged = true; | ||
TraceLog(LOG_INFO, "num points %d", numPoints); | ||
} | ||
|
||
// upload a different point cloud size | ||
if (numPointsChanged) | ||
{ | ||
UnloadModel(model); | ||
mesh = GenPoints(numPoints); | ||
model = LoadModelFromMesh(mesh); | ||
numPointsChanged = false; | ||
} | ||
|
||
// Draw | ||
//---------------------------------------------------------------------------------- | ||
BeginDrawing(); | ||
ClearBackground(BLACK); | ||
BeginMode3D(camera); | ||
|
||
// The new method only uploads the points once to the GPU | ||
if (useDrawModelPoints) | ||
{ | ||
DrawModelPoints(model, position, 1.0f, WHITE); | ||
} | ||
// The old method must continually draw the "points" (lines) | ||
else | ||
{ | ||
for (int i = 0; i < numPoints; i++) | ||
{ | ||
Vector3 pos = { | ||
.x = mesh.vertices[i * 3 + 0], | ||
.y = mesh.vertices[i * 3 + 1], | ||
.z = mesh.vertices[i * 3 + 2], | ||
}; | ||
Color color = { | ||
.r = mesh.colors[i * 4 + 0], | ||
.g = mesh.colors[i * 4 + 1], | ||
.b = mesh.colors[i * 4 + 2], | ||
.a = mesh.colors[i * 4 + 3], | ||
}; | ||
DrawPoint3D(pos, color); | ||
} | ||
} | ||
|
||
// Draw a unit sphere for reference | ||
DrawSphereWires(position, 1.0f, 10, 10, YELLOW); | ||
EndMode3D(); | ||
|
||
// Text formatting | ||
Color color = WHITE; | ||
int fps = GetFPS(); | ||
if ((fps < 30) && (fps >= 15)) color = ORANGE; | ||
else if (fps < 15) color = RED; | ||
DrawText(TextFormat("%2i FPS", fps), 20, 20, 40, color); | ||
DrawText(TextFormat("Point Count: %d", numPoints), 20, screenHeight - 50, 40, WHITE); | ||
DrawText("Up - increase points", 20, 70, 20, WHITE); | ||
DrawText("Down - decrease points", 20, 100, 20, WHITE); | ||
DrawText("Space - drawing function", 20, 130, 20, WHITE); | ||
if (useDrawModelPoints) DrawText("DrawModelPoints()", 20, 160, 20, GREEN); | ||
else DrawText("DrawPoint3D()", 20, 160, 20, RED); | ||
EndDrawing(); | ||
//---------------------------------------------------------------------------------- | ||
} | ||
|
||
// De-Initialization | ||
//-------------------------------------------------------------------------------------- | ||
UnloadModel(model); | ||
CloseWindow(); | ||
//-------------------------------------------------------------------------------------- | ||
return 0; | ||
} | ||
|
||
// Generate a spherical point cloud | ||
Mesh GenPoints(int numPoints) | ||
{ | ||
Mesh mesh = { | ||
.triangleCount = 1, | ||
.vertexCount = numPoints, | ||
.vertices = (float *)MemAlloc(numPoints * 3 * sizeof(float)), | ||
.colors = (unsigned char*)MemAlloc(numPoints * 4 * sizeof(unsigned char)), | ||
}; | ||
|
||
// https://en.wikipedia.org/wiki/Spherical_coordinate_system | ||
for (int i = 0; i < numPoints; i++) | ||
{ | ||
float theta = PI * rand() / RAND_MAX; | ||
float phi = 2.0f * PI * rand() / RAND_MAX; | ||
float r = 10.0f * rand() / RAND_MAX; | ||
mesh.vertices[i * 3 + 0] = r * sin(theta) * cos(phi); | ||
mesh.vertices[i * 3 + 1] = r * sin(theta) * sin(phi); | ||
mesh.vertices[i * 3 + 2] = r * cos(theta); | ||
Color color = ColorFromHSV(r * 360.0f, 1.0f, 1.0f); | ||
mesh.colors[i * 4 + 0] = color.r; | ||
mesh.colors[i * 4 + 1] = color.g; | ||
mesh.colors[i * 4 + 2] = color.b; | ||
mesh.colors[i * 4 + 3] = color.a; | ||
} | ||
|
||
// Upload mesh data from CPU (RAM) to GPU (VRAM) memory | ||
UploadMesh(&mesh, false); | ||
return mesh; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.