Skip to content

Commit 582d336

Browse files
committed
fix the 3d orderbok orientation
1 parent af17cde commit 582d336

4 files changed

Lines changed: 61 additions & 10 deletions

File tree

docs/RLOrderBookVis.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ struct RLOrderBookVisStyle {
126126
|--------|-------------|
127127
| `update(float aDt)` | Update animations and textures (call each frame) |
128128
| `draw2D() const` | Draw the 2D heatmap view |
129-
| `draw3D(const Camera3D &rCamera) const` | Draw the 3D landscape view |
129+
| `draw3D(const Camera3D &rCamera) const` | Draw the 3D landscape view (renders to internal texture for proper viewport centering within bounds) |
130130

131131
### Getters
132132

@@ -280,6 +280,7 @@ int main() {
280280
- **Y-axis (height)**: Liquidity/size
281281
- Separate meshes for bids and asks
282282
- Color corresponds to height/intensity
283+
- Renders to an internal RenderTexture for proper centering within bounds
283284

284285
### Interpreting the Display
285286
- **Bright walls**: Large resting orders (support/resistance)

src/charts/RLOrderBookVis.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ RLOrderBookVis::RLOrderBookVis(Rectangle aBounds, size_t aHistoryLength, size_t
3535
RLOrderBookVis::~RLOrderBookVis() {
3636
cleanupTexture();
3737
cleanupMesh();
38+
cleanupRenderTarget();
3839
}
3940

4041
void RLOrderBookVis::cleanupTexture() {
@@ -59,6 +60,33 @@ void RLOrderBookVis::cleanupMesh() {
5960
}
6061
}
6162

63+
void RLOrderBookVis::cleanupRenderTarget() const {
64+
if (mRenderTargetValid && mRenderTarget.id != 0) {
65+
UnloadRenderTexture(mRenderTarget);
66+
mRenderTarget = RenderTexture2D{};
67+
mRenderTargetValid = false;
68+
mRenderTargetWidth = 0;
69+
mRenderTargetHeight = 0;
70+
}
71+
}
72+
73+
void RLOrderBookVis::ensureRenderTarget() const {
74+
int lWidth = (int)mBounds.width;
75+
int lHeight = (int)mBounds.height;
76+
77+
// Recreate if dimensions changed or not valid
78+
if (mRenderTargetValid && (mRenderTargetWidth != lWidth || mRenderTargetHeight != lHeight)) {
79+
cleanupRenderTarget();
80+
}
81+
82+
if (!mRenderTargetValid || mRenderTarget.id == 0) {
83+
mRenderTarget = LoadRenderTexture(lWidth, lHeight);
84+
mRenderTargetValid = (mRenderTarget.id != 0);
85+
mRenderTargetWidth = lWidth;
86+
mRenderTargetHeight = lHeight;
87+
}
88+
}
89+
6290
void RLOrderBookVis::setBounds(Rectangle aBounds) {
6391
mBounds = aBounds;
6492
}
@@ -770,6 +798,16 @@ void RLOrderBookVis::draw3D(const Camera3D& rCamera) const {
770798
return;
771799
}
772800

801+
// Ensure render target exists and matches bounds dimensions
802+
ensureRenderTarget();
803+
if (!mRenderTargetValid || mRenderTarget.id == 0) {
804+
return;
805+
}
806+
807+
// Render 3D scene to offscreen texture
808+
BeginTextureMode(mRenderTarget);
809+
ClearBackground(mStyle.mBackground);
810+
773811
BeginMode3D(rCamera);
774812

775813
// Center the mesh
@@ -809,5 +847,17 @@ void RLOrderBookVis::draw3D(const Camera3D& rCamera) const {
809847
DrawMesh(mAskMesh, lMat, lTransform);
810848

811849
EndMode3D();
850+
EndTextureMode();
851+
852+
// Draw the render texture at the bounds position
853+
// Note: RenderTexture Y is flipped, so we use negative height in source rect
854+
const Rectangle lSrc = {0, 0, (float)mRenderTargetWidth, -(float)mRenderTargetHeight};
855+
const Rectangle lDst = {mBounds.x, mBounds.y, mBounds.width, mBounds.height};
856+
DrawTexturePro(mRenderTarget.texture, lSrc, lDst, Vector2{0, 0}, 0.0f, WHITE);
857+
858+
// Draw border on top if enabled
859+
if (mStyle.mShowBorder) {
860+
DrawRectangleLinesEx(mBounds, mStyle.mBorderThickness, mStyle.mBorderColor);
861+
}
812862
}
813863

src/charts/RLOrderBookVis.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ class RLOrderBookVis {
159159
bool mMeshValid{false};
160160
bool mMeshDirty{true};
161161

162+
// 3D render target for proper viewport centering
163+
mutable RenderTexture2D mRenderTarget{};
164+
mutable bool mRenderTargetValid{false};
165+
mutable int mRenderTargetWidth{0};
166+
mutable int mRenderTargetHeight{0};
167+
162168
// Internal helpers
163169
void ensureBuffers();
164170
void rebuildLUT();
@@ -168,6 +174,8 @@ class RLOrderBookVis {
168174
void updateMeshData();
169175
void cleanupTexture();
170176
void cleanupMesh();
177+
void cleanupRenderTarget() const;
178+
void ensureRenderTarget() const;
171179

172180
// Price mapping helpers
173181
[[nodiscard]] float priceToNormalized(float aPrice) const;

src/examples/orderbook.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11

2-
//The orderbook visualization 3D mode is WIP and not 100% correct
3-
42
// orderbook.cpp
53
// Order Book Visualization Demo
64
// Demonstrates 2D heatmap and 3D landscape views of depth-of-market data
@@ -346,14 +344,8 @@ int main() {
346344
DrawTextEx(lFont, "Time ->", Vector2{lBounds2D.x + lBounds2D.width/2 - 30, lBounds2D.y + lBounds2D.height + 15}, 16, 1.0f, Color{120, 120, 130, 255});
347345
DrawTextPro(lFont, "Price", Vector2{lBounds2D.x - 25, lBounds2D.y + lBounds2D.height/2 + 20}, Vector2{0, 0}, -90.0f, 16, 1, Color{120, 120, 130, 255});
348346
} else {
349-
// 3D view
350-
DrawRectangle((int)lBounds2D.x, (int)lBounds2D.y, (int)lBounds2D.width, (int)lBounds2D.height, Color{15, 17, 22, 255});
351-
DrawRectangleLinesEx(lBounds2D, 1.0f, Color{50, 55, 65, 255});
352-
353-
// Draw 3D in a viewport-like area
354-
BeginScissorMode((int)lBounds2D.x, (int)lBounds2D.y, (int)lBounds2D.width, (int)lBounds2D.height);
347+
// 3D view - draw3D handles viewport centering internally via RenderTexture
355348
lOrderBook.draw3D(lCamera);
356-
EndScissorMode();
357349
}
358350

359351
// Info panel

0 commit comments

Comments
 (0)