1. Compilation Requirements
Pip3D uses C++17.
For PlatformIO:
build_unflags =
-std=gnu++11
build_flags =
-std=gnu++17
2. Build-time Configuration
Main compile-time flags for Pip3D and the lower PipCore layer:
PIP3D_SCREEN_WIDTH- logical screen width
PIP3D_SCREEN_HEIGHT- logical screen height
PIP3D_SCREEN_BAND_COUNT- number of horizontal bands for banded rendering
PIPCORE_PLATFORMPipCoreplatform- example:
ESP32
PIPCORE_DISPLAY- display driver
- example:
ILI9488,ST7789
PIPCORE_ENABLE_PREFS0or1
PIPCORE_ENABLE_WIFI0or1
PIPCORE_ENABLE_OTA0or1
PIPCORE_OTA_PROJECT_URL- OTA backend URL when OTA is actually used
Example via platformio.ini:
build_flags =
-std=gnu++17
-Ilib/Pip3D
-Ilib/Pip3D/Pip3D
-Iinclude
-DPIP3D_SCREEN_WIDTH=480
-DPIP3D_SCREEN_HEIGHT=320
-DPIP3D_SCREEN_BAND_COUNT=2
-DPIPCORE_PLATFORM=ESP32
-DPIPCORE_DISPLAY=ILI9488
You can also define the same values through include/config.hpp if that is a more convenient place for project-level config.
Important:
PIP3D_SCREEN_WIDTHandPIP3D_SCREEN_HEIGHTare engine-level compile-time constants, not cosmetic values- runtime
begin3D(width, height, ...)must not contradict those macros - if your project uses a
480x320screen, the compile-time flags must also be480x320 PIP3D_SCREEN_BAND_COUNT=2or higher lowers framebuffer/z-buffer memory usage, but makes the pipeline more complex2is a sensible default for regular projects- optional
PipCoremodules are disabled by default, so external code should not call Wi-Fi / OTA API without explicitly enabling the flags
3. Include and Entry Point
Main include:
#include "Pip3D.h"
using namespace pip3D;
Main public entry points:
const char* getVersion()Color RGB888(uint8_t r, uint8_t g, uint8_t b)Renderer& renderer()Renderer& begin3D(uint16_t width, uint16_t height, int8_t cs, int8_t dc, int8_t rst, int8_t bl = -1, uint32_t spi_freq = 80000000)Renderer& begin3D(int8_t cs, int8_t dc, int8_t rst, int8_t bl = -1, uint32_t spi_freq = 80000000)
Example:
Renderer& r = begin3D(480, 320, 10, 9, 8, -1, 80000000);
What begin3D(...) does:
- initializes the singleton renderer
- sets up the display, framebuffer and z-buffer
- enables
SKYBOX_DAY - enables shadows
- places the shadow plane at
Y = 0
Important:
- the overload
begin3D(cs, dc, rst, ...)uses the default320x240 - if your project is not
320x240, use the overload with explicitwidthandheight renderer()returns the globalRenderersingleton
16. Minimal Working Example
#include <Arduino.h>
#include "Pip3D.h"
using namespace pip3D;
Renderer* g_renderer = nullptr;
Cube* g_cube = nullptr;
void setup()
{
g_renderer = &begin3D(480, 320, 10, 9, 8);
Camera& cam = g_renderer->getCamera();
cam.position = Vector3(0.0f, 2.0f, -6.0f);
cam.lookAt(Vector3(0.0f, 0.5f, 5.0f));
cam.setPerspective(60.0f, 0.1f, 100.0f);
g_renderer->setSkyboxWithLighting(SKYBOX_DAY);
g_renderer->setShadowPlaneY(0.0f);
g_cube = new Cube(1.0f, Color::fromRGB888(220, 220, 230));
g_cube->setPosition(0.0f, 0.5f, 5.0f);
}
void loop()
{
float dt = getDeltaTime();
g_cube->rotate(0.0f, 40.0f * dt, 0.0f);
g_renderer->beginFrame();
g_renderer->drawMesh(g_cube);
g_renderer->drawText(8, 8, "Pip3D", Color::WHITE);
g_renderer->endFrame();
}
17. Practical Notes
- External code should usually start with
begin3D(...),Renderer,Camera,MeshandLight. - If you need many similar objects, use
MeshInstanceandInstanceManagerinstead of separateMeshcopies. - If you need a full object hierarchy, use
SceneGraphandNode-derived types. - If you need a cutscene, use
CameraTimeline. - If you need a day/night cycle, use
TimeOfDayController. - If you need a simple test character, use
CharacterController. - If you need a quick effect prototype, use
FXSystem. - Internal renderer and pipeline headers should not be the main integration point for user code.