wasm/gl1: the GL1.x fixed-function emulation layer replacing the gl_ffp_stub.c no-ops in the 3d-regression harness link. This batch: - symbol split: 52 FFP-only entry points implemented; 10 Emscripten-owned names intercepted via wasm-ld --wrap (sources.txt/wrapped_symbols.txt are the shared manifests for both link sites; production hookup lands in M7) - matrix stacks (MODELVIEW/PROJECTION, glGetFloatv readback), immediate mode with all 8 GL1 primitive conversions, GL1-default state mirror - full GL 1.5 Gouraud lighting uber-shader (eye-space light capture at glLightfv time, color-material, two-side, COMBINE evaluator + alpha test wired but inert until M3/M5) - draw routing: FFP traffic identified by GL_VERTEX_ARRAY client state; blit/2D-GAL draws pass through untouched - display lists: correct glGenLists/glIsList existing-empty semantics; recorder itself is M3 (recorded commands drop with a one-time warning) Parity: 20/47 under the 0.02 floor, of which 12 verified genuinely rendering (bg-gradient x2, bounding-box, half-open-cylinder, segment x2, material x3, light x3 — eyeballed against baselines); the other 8 are small-geometry scenarios whose missing GLU/display-list content sits under the floor (become real in M3/M4). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
106 lines
2.5 KiB
C++
106 lines
2.5 KiB
C++
/*
|
|
* gl1_matrix — GL_MODELVIEW / GL_PROJECTION matrix stacks.
|
|
*
|
|
* Only the operations the KiCad 3D renderer uses exist (no glOrtho/glFrustum/
|
|
* glMultMatrix — projection and view arrive prebuilt via glLoadMatrixf, and
|
|
* gluPerspective covers the gizmo). glGetFloatv(GL_MODELVIEW_MATRIX/
|
|
* GL_PROJECTION_MATRIX) readback is served from these stacks by the
|
|
* __wrap_glGetFloatv interceptor.
|
|
*/
|
|
|
|
#include "gl1_shim.h"
|
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
namespace gl1
|
|
{
|
|
|
|
// GL 1.5 minimums; KiCad never goes deeper than a few levels.
|
|
static constexpr size_t MV_STACK_MAX = 64;
|
|
static constexpr size_t PROJ_STACK_MAX = 8;
|
|
|
|
void matrixLoadIdentity()
|
|
{
|
|
S().currentTop() = glm::mat4( 1.0f );
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixLoadf( const GLfloat* m )
|
|
{
|
|
S().currentTop() = glm::make_mat4( m );
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixPush()
|
|
{
|
|
State& s = S();
|
|
auto& stack = s.currentStack();
|
|
|
|
const size_t maxDepth = ( s.matrixMode == GL_PROJECTION ) ? PROJ_STACK_MAX : MV_STACK_MAX;
|
|
|
|
if( stack.size() >= maxDepth )
|
|
{
|
|
GL1_WARN_ONCE( "glPushMatrix: stack overflow (mode 0x%x)", s.matrixMode );
|
|
return;
|
|
}
|
|
|
|
stack.push_back( stack.back() );
|
|
}
|
|
|
|
|
|
void matrixPop()
|
|
{
|
|
State& s = S();
|
|
auto& stack = s.currentStack();
|
|
|
|
if( stack.size() <= 1 )
|
|
{
|
|
GL1_WARN_ONCE( "glPopMatrix: stack underflow (mode 0x%x)", s.matrixMode );
|
|
return;
|
|
}
|
|
|
|
stack.pop_back();
|
|
s.matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixTranslate( float x, float y, float z )
|
|
{
|
|
glm::mat4& top = S().currentTop();
|
|
top = glm::translate( top, glm::vec3( x, y, z ) );
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixRotate( float angleDeg, float x, float y, float z )
|
|
{
|
|
glm::mat4& top = S().currentTop();
|
|
top = glm::rotate( top, glm::radians( angleDeg ), glm::vec3( x, y, z ) );
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixScale( float x, float y, float z )
|
|
{
|
|
glm::mat4& top = S().currentTop();
|
|
top = glm::scale( top, glm::vec3( x, y, z ) );
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
|
|
void matrixPerspective( double fovyDeg, double aspect, double zNear, double zFar )
|
|
{
|
|
// gluPerspective multiplies onto the current matrix (KiCad calls it right
|
|
// after glLoadIdentity on GL_PROJECTION, but multiply is the GLU semantic).
|
|
glm::mat4 p = glm::perspective( glm::radians( (float) fovyDeg ), (float) aspect,
|
|
(float) zNear, (float) zFar );
|
|
|
|
glm::mat4& top = S().currentTop();
|
|
top = top * p;
|
|
S().matricesDirty = true;
|
|
}
|
|
|
|
} // namespace gl1
|