335 lines
13 KiB
C
Executable File
335 lines
13 KiB
C
Executable File
// TODO: glIsEnabled(), glGetMap()
|
|
// TODO: GL_AUTO_NORMAL
|
|
|
|
#include "eval.h"
|
|
#include "math/eval.h"
|
|
|
|
static inline map_state_t **get_map_pointer(GLenum target) {
|
|
switch (target) {
|
|
case GL_MAP1_COLOR_4: return &glstate->map1.color4;
|
|
case GL_MAP1_INDEX: return &glstate->map1.index;
|
|
case GL_MAP1_TEXTURE_COORD_1: return &glstate->map1.texture1;
|
|
case GL_MAP1_TEXTURE_COORD_2: return &glstate->map1.texture2;
|
|
case GL_MAP1_TEXTURE_COORD_3: return &glstate->map1.texture3;
|
|
case GL_MAP1_TEXTURE_COORD_4: return &glstate->map1.texture4;
|
|
case GL_MAP1_VERTEX_3: return &glstate->map1.vertex3;
|
|
case GL_MAP1_VERTEX_4: return &glstate->map1.vertex4;
|
|
case GL_MAP2_COLOR_4: return &glstate->map2.color4;
|
|
case GL_MAP2_INDEX: return &glstate->map2.index;
|
|
case GL_MAP2_TEXTURE_COORD_1: return &glstate->map2.texture1;
|
|
case GL_MAP2_TEXTURE_COORD_2: return &glstate->map2.texture2;
|
|
case GL_MAP2_TEXTURE_COORD_3: return &glstate->map2.texture3;
|
|
case GL_MAP2_TEXTURE_COORD_4: return &glstate->map2.texture4;
|
|
case GL_MAP2_VERTEX_3: return &glstate->map2.vertex3;
|
|
case GL_MAP2_VERTEX_4: return &glstate->map2.vertex4;
|
|
default:
|
|
printf("libGL: unknown glMap target 0x%x\n", target);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#define set_map_coords(n) \
|
|
map->n._1 = n##1; \
|
|
map->n._2 = n##2; \
|
|
map->n.d = 1.0/(n##2 - n##1); \
|
|
map->n.stride = n##stride; \
|
|
map->n.order = n##order;
|
|
|
|
#define case_state(dims, magic, name) \
|
|
case magic: { \
|
|
map->width = get_map_width(magic); \
|
|
map_statef_t *m = (map_statef_t *)glstate->map##dims.name; \
|
|
if (m) { \
|
|
if (m->free) \
|
|
free((void *)m->points); \
|
|
free(m); \
|
|
} \
|
|
glstate->map##dims.name = (map_state_t *)map; \
|
|
break; \
|
|
}
|
|
|
|
#define map_switch(dims) \
|
|
switch (target) { \
|
|
case_state(dims, GL_MAP##dims##_COLOR_4, color4); \
|
|
case_state(dims, GL_MAP##dims##_INDEX, index); \
|
|
case_state(dims, GL_MAP##dims##_NORMAL, normal); \
|
|
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_1, texture1); \
|
|
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_2, texture2); \
|
|
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_3, texture3); \
|
|
case_state(dims, GL_MAP##dims##_TEXTURE_COORD_4, texture4); \
|
|
case_state(dims, GL_MAP##dims##_VERTEX_3, vertex3); \
|
|
case_state(dims, GL_MAP##dims##_VERTEX_4, vertex4); \
|
|
}
|
|
|
|
void glshim_glMap1d(GLenum target, GLdouble u1, GLdouble u2,
|
|
GLint ustride, GLint uorder, const GLdouble *points) {
|
|
noerrorShim();
|
|
map_statef_t *map = malloc(sizeof(map_statef_t));
|
|
map->type = GL_FLOAT; map->dims = 1; map->free = true;
|
|
set_map_coords(u);
|
|
map_switch(1);
|
|
map->points = copy_eval_double(target, ustride, uorder, 0, 1, points);
|
|
}
|
|
|
|
void glshim_glMap1f(GLenum target, GLfloat u1, GLfloat u2,
|
|
GLint ustride, GLint uorder, const GLfloat *points) {
|
|
noerrorShim();
|
|
map_statef_t *map = malloc(sizeof(map_statef_t));
|
|
map->type = GL_FLOAT; map->dims = 1; map->free = false;
|
|
set_map_coords(u);
|
|
map_switch(1);
|
|
map->points = points;
|
|
}
|
|
|
|
void glshim_glMap2d(GLenum target, GLdouble u1, GLdouble u2,
|
|
GLint ustride, GLint uorder, GLdouble v1, GLdouble v2,
|
|
GLint vstride, GLint vorder, const GLdouble *points) {
|
|
noerrorShim();
|
|
map_statef_t *map = malloc(sizeof(map_statef_t));
|
|
map->type = GL_FLOAT; map->dims = 2; map->free = true;
|
|
set_map_coords(u);
|
|
set_map_coords(v);
|
|
map_switch(2);
|
|
map->points = copy_eval_double(target, ustride, uorder, vstride, vorder, points);
|
|
}
|
|
|
|
void glshim_glMap2f(GLenum target, GLfloat u1, GLfloat u2,
|
|
GLint ustride, GLint uorder, GLfloat v1, GLfloat v2,
|
|
GLint vstride, GLint vorder, const GLfloat *points) {
|
|
noerrorShim();
|
|
map_statef_t *map = malloc(sizeof(map_statef_t));
|
|
map->type = GL_FLOAT; map->dims = 2; map->free = false;
|
|
set_map_coords(u);
|
|
set_map_coords(v);
|
|
map_switch(2);
|
|
map->points = points;
|
|
}
|
|
|
|
#undef set_map_coords
|
|
#undef case_state
|
|
#undef map_switch
|
|
|
|
#define p_map(d, name, func, code) { \
|
|
map_state_t *_map = glstate->map##d.name; \
|
|
if (_map) { \
|
|
if (_map->type == GL_DOUBLE) { \
|
|
map_stated_t *map = (map_stated_t *)_map; \
|
|
printf("double: not implemented\n"); \
|
|
} else if (_map->type == GL_FLOAT) { \
|
|
map_statef_t *map = (map_statef_t *)_map; \
|
|
GLfloat out[4]; \
|
|
code \
|
|
glshim_##func##v(out); \
|
|
} \
|
|
}}
|
|
|
|
#define iter_maps(d, code) \
|
|
p_map(d, color4, glColor4f, code); \
|
|
p_map(d, index, glIndexf, code); \
|
|
p_map(d, normal, glNormal3f, code); \
|
|
p_map(d, texture1, glTexCoord1f, code); \
|
|
p_map(d, texture2, glTexCoord2f, code); \
|
|
p_map(d, texture3, glTexCoord3f, code); \
|
|
p_map(d, texture4, glTexCoord4f, code); \
|
|
p_map(d, vertex3, glVertex3f, code); \
|
|
p_map(d, vertex4, glVertex4f, code);
|
|
|
|
void glshim_glEvalCoord1f(GLfloat u) {
|
|
noerrorShim();
|
|
iter_maps(1,
|
|
GLfloat uu = (u - map->u._1) * map->u.d;
|
|
_math_horner_bezier_curve(map->points, out, uu, map->width, map->u.order);
|
|
)
|
|
}
|
|
|
|
void glshim_glEvalCoord2f(GLfloat u, GLfloat v) {
|
|
noerrorShim();
|
|
iter_maps(2,
|
|
GLfloat uu = (u - map->u._1) * map->u.d;
|
|
GLfloat vv = (v - map->v._1) * map->v.d;
|
|
// TODO: GL_AUTONORMAL
|
|
|
|
_math_horner_bezier_surf((GLfloat *)map->points, out, uu, vv,
|
|
map->width, map->u.order, map->v.order);
|
|
)
|
|
}
|
|
|
|
#undef p_map
|
|
#undef iter_maps
|
|
|
|
void glshim_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) {
|
|
noerrorShim();
|
|
// TODO: double support?
|
|
map_statef_t *map;
|
|
if (! glstate->map_grid)
|
|
glstate->map_grid = malloc(sizeof(map_statef_t));
|
|
|
|
map = (map_statef_t *)glstate->map_grid;
|
|
map->dims = 1;
|
|
map->u.n = un;
|
|
map->u._1 = u1;
|
|
map->u._2 = u2;
|
|
}
|
|
|
|
void glshim_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2,
|
|
GLint vn, GLfloat v1, GLfloat v2) {
|
|
noerrorShim();
|
|
// TODO: double support?
|
|
map_statef_t *map;
|
|
if (! glstate->map_grid)
|
|
glstate->map_grid = malloc(sizeof(map_statef_t));
|
|
|
|
map = (map_statef_t *)glstate->map_grid;
|
|
map->dims = 2;
|
|
map->u.n = un;
|
|
map->u._1 = u1;
|
|
map->u._2 = u2;
|
|
map->v.n = vn;
|
|
map->v._1 = v1;
|
|
map->v._2 = v2;
|
|
}
|
|
|
|
static inline GLenum eval_mesh_prep(map_statef_t **map, GLenum mode) {
|
|
if (glstate->map2.vertex4) {
|
|
*map = (map_statef_t *)glstate->map2.vertex4;
|
|
} else if (glstate->map2.vertex3) {
|
|
*map = (map_statef_t *)glstate->map2.vertex3;
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
if ((*map)->type == GL_DOUBLE) {
|
|
printf("libGL: GL_DOUBLE map not implemented\n");
|
|
return 0;
|
|
}
|
|
|
|
switch (mode) {
|
|
case GL_POINT: return GL_POINTS;
|
|
case GL_LINE: return GL_LINE_STRIP;
|
|
case GL_FILL: return GL_TRIANGLE_STRIP;
|
|
case 0: return 1;
|
|
default:
|
|
printf("unknown glEvalMesh mode: %x\n", mode);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void glshim_glEvalMesh1(GLenum mode, GLint i1, GLint i2) {
|
|
noerrorShim();
|
|
map_statef_t *map;
|
|
GLenum renderMode = eval_mesh_prep(&map, mode);
|
|
if (! renderMode)
|
|
return;
|
|
|
|
GLfloat u, du, u1;
|
|
du = map->u.d;
|
|
GLint i;
|
|
glshim_glBegin(renderMode);
|
|
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
|
glshim_glEvalCoord1f(u);
|
|
}
|
|
glshim_glEnd();
|
|
}
|
|
|
|
void glshim_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) {
|
|
noerrorShim();
|
|
map_statef_t *map;
|
|
GLenum renderMode = eval_mesh_prep(&map, mode);
|
|
if (! renderMode)
|
|
return;
|
|
|
|
GLfloat u, du, u1, v, dv, v1;
|
|
du = map->u.d;
|
|
dv = map->v.d;
|
|
GLint i, j;
|
|
glshim_glBegin(renderMode);
|
|
for (v = v1, j = j1; j <= j2; j++, v += dv) {
|
|
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
|
glshim_glEvalCoord2f(u, v);
|
|
if (mode == GL_FILL)
|
|
glshim_glEvalCoord2f(u, v + dv);
|
|
}
|
|
}
|
|
glshim_glEnd();
|
|
if (mode == GL_LINE) {
|
|
glshim_glBegin(renderMode);
|
|
for (u = u1, i = i1; i <= i2; i++, u += du) {
|
|
for (v = v1, j = j1; j <= j2; j++, v += dv) {
|
|
glshim_glEvalCoord2f(u, v);
|
|
}
|
|
}
|
|
glshim_glEnd();
|
|
}
|
|
}
|
|
|
|
void glshim_glEvalPoint1(GLint i) {
|
|
map_statef_t *map;
|
|
if (eval_mesh_prep(&map, 0))
|
|
glshim_glEvalCoord1f(i + map->u.d);
|
|
}
|
|
|
|
void glshim_glEvalPoint2(GLint i, GLint j) {
|
|
map_statef_t *map;
|
|
if (eval_mesh_prep(&map, 0))
|
|
glshim_glEvalCoord2f(i + map->u.d, j + map->v.d);
|
|
}
|
|
|
|
#define GL_GET_MAP(t, type) \
|
|
void glshim_glGetMap##t##v(GLenum target, GLenum query, type *v) { \
|
|
noerrorShim(); \
|
|
map_statef_t *map = *(map_statef_t **)get_map_pointer(target); \
|
|
if (map) { \
|
|
switch (query) { \
|
|
case GL_COEFF: { \
|
|
const GLfloat *points = map->points; \
|
|
for (int i = 0; i < map->u.order; i++) { \
|
|
if (map->dims == 2) { \
|
|
for (int j = 0; j < map->v.order; j++) { \
|
|
*v++ = *points++; \
|
|
} \
|
|
} else { \
|
|
*v++ = *points++; \
|
|
} \
|
|
} \
|
|
return; \
|
|
} \
|
|
case GL_ORDER: \
|
|
*v++ = map->u.order; \
|
|
if (map->dims == 2) \
|
|
*v++ = map->v.order; \
|
|
return; \
|
|
case GL_DOMAIN: \
|
|
*v++ = map->u._1; \
|
|
*v++ = map->u._2; \
|
|
if (map->dims == 2) { \
|
|
*v++ = map->u._1; \
|
|
*v++ = map->u._2; \
|
|
} \
|
|
return; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
GL_GET_MAP(i, GLint)
|
|
GL_GET_MAP(f, GLfloat)
|
|
GL_GET_MAP(d, GLdouble)
|
|
|
|
#undef GL_GET_MAP
|
|
|
|
//Direct wrapper
|
|
void glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) AliasExport("glshim_glMap1d");
|
|
void glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) AliasExport("glshim_glMap1f");
|
|
void glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) AliasExport("glshim_glMap2d");
|
|
void glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) AliasExport("glshim_glMap2f");
|
|
void glEvalCoord1f(GLfloat u) AliasExport("glshim_glEvalCoord1f");
|
|
void glEvalCoord2f(GLfloat u, GLfloat v) AliasExport("glshim_glEvalCoord2f");
|
|
void glEvalMesh1(GLenum mode, GLint i1, GLint i2) AliasExport("glshim_glEvalMesh1");
|
|
void glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) AliasExport("glshim_glEvalMesh2");
|
|
void glEvalPoint1(GLint i) AliasExport("glshim_glEvalPoint1");
|
|
void glEvalPoint2(GLint i, GLint j) AliasExport("glshim_glEvalPoint2");
|
|
void glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) AliasExport("glshim_glMapGrid1f");
|
|
void glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) AliasExport("glshim_glMapGrid2f");
|
|
void glGetMapdv(GLenum target, GLenum query, GLdouble *v) AliasExport("glshim_glGetMapdv");
|
|
void glGetMapfv(GLenum target, GLenum query, GLfloat *v) AliasExport("glshim_glGetMapfv");
|
|
void glGetMapiv(GLenum target, GLenum query, GLint *v) AliasExport("glshim_glGetMapiv");
|