tests/3d-regression mirrors the gal-regression pattern at renderer scale: shared C++ scenarios call real KiCad 3D-viewer code (opengl_utils, display lists + DrawCulled stencil subtraction, MODEL_3D VBOs, private generators via a rob-template accessor, and full reload()+Redraw() composites over a synthetic BOARD_ADAPTER). A native macOS harness renders them on real OpenGL into 47 committed goldens (bit-deterministic, FBO capture); the wasm harness compiles the same TUs against wasm/stubs/gl_ffp_stub.c no-ops so every scenario renders blank — the TDD red state (parity meter: 47/47 changed). Comparisons use the CI pixelmatch engine via the new generic compare-dirs.ts (floors.json levels; manifest.json cmp-guards registry drift). Documents an upstream bug: appendPostMachiningGeometry's countersink path adds middle quads without normals, silently erasing the walls of any display list it is batched into (3d-post-machining.png keeps the lists separate to record it). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
46 lines
1.2 KiB
C++
46 lines
1.2 KiB
C++
/**
|
|
* Offscreen FBO for deterministic fixed-size capture, mirroring
|
|
* EDA_3D_CANVAS::RenderToFrameBuffer (eda_3d_canvas.cpp:736-772):
|
|
* GL_RGBA8 color texture + GL_DEPTH24_STENCIL8 renderbuffer on
|
|
* GL_DEPTH_STENCIL_ATTACHMENT (the stencil is required by
|
|
* OPENGL_RENDER_LIST::DrawCulled hole cutting).
|
|
*
|
|
* Rendering into an FBO makes the output independent of window size and
|
|
* Retina scaling — pixels are exactly aWidth x aHeight.
|
|
*/
|
|
|
|
#ifndef FBO_CAPTURE_H
|
|
#define FBO_CAPTURE_H
|
|
|
|
#include <kicad_gl/kiglad.h>
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
class FBO_CAPTURE
|
|
{
|
|
public:
|
|
/// Create the FBO; returns false if the framebuffer is incomplete.
|
|
/// Falls back to the EXT entry points if the core ARB ones didn't load
|
|
/// (Apple GL 2.1 exposes both; glad loads by symbol name).
|
|
bool Create( int aWidth, int aHeight );
|
|
|
|
void Bind();
|
|
|
|
/// glFinish + glReadPixels(GL_RGBA); aOut is resized to w*h*4.
|
|
bool ReadPixels( std::vector<uint8_t>& aOut );
|
|
|
|
void Destroy();
|
|
|
|
int Width() const { return m_width; }
|
|
int Height() const { return m_height; }
|
|
|
|
private:
|
|
int m_width = 0;
|
|
int m_height = 0;
|
|
GLuint m_fbo = 0;
|
|
GLuint m_colorTexture = 0;
|
|
GLuint m_depthStencil = 0;
|
|
};
|
|
|
|
#endif // FBO_CAPTURE_H
|