#include #include "state.h" #include "../passthrough.h" // GL State gl_state_t gl_state = { .color = { .red = 1, .green = 1, .blue = 1, .alpha = 1 }, .matrix_stacks = { .mode = GL_MODELVIEW }, .alpha_test = 0, .texture_2d = 0, .fog = { .enabled = 0, .mode = GL_LINEAR, .color = {0, 0, 0, 0}, .start = 0, .end = 1 } }; // Change Color void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { gl_state.color.red = red; gl_state.color.green = green; gl_state.color.blue = blue; gl_state.color.alpha = alpha; } // Array Pointer Storage #define ARRAY_POINTER_FUNC(func, name) \ void func(GLint size, GLenum type, GLsizei stride, const void *pointer) { \ gl_state.array_pointers.name.size = size; \ gl_state.array_pointers.name.type = type; \ gl_state.array_pointers.name.stride = stride; \ gl_state.array_pointers.name.pointer = pointer; \ } ARRAY_POINTER_FUNC(glVertexPointer, vertex) ARRAY_POINTER_FUNC(glColorPointer, color) ARRAY_POINTER_FUNC(glTexCoordPointer, tex_coord) static array_pointer_t *get_array_pointer(GLenum array) { switch (array) { case GL_VERTEX_ARRAY: { return &gl_state.array_pointers.vertex; } case GL_COLOR_ARRAY: { return &gl_state.array_pointers.color; } case GL_TEXTURE_COORD_ARRAY: { return &gl_state.array_pointers.tex_coord; } default: { ERR("Unsupported Array Pointer: %i", array); } } } void glEnableClientState(GLenum array) { get_array_pointer(array)->enabled = 1; } void glDisableClientState(GLenum array) { get_array_pointer(array)->enabled = 0; } // Enable/Disable State GL_FUNC(glEnable, void, (GLenum cap)); void glEnable(GLenum cap) { switch (cap) { case GL_ALPHA_TEST: { gl_state.alpha_test = 1; break; } case GL_TEXTURE_2D: { gl_state.texture_2d = 1; break; } case GL_COLOR_MATERIAL: { // Ignore break; } case GL_FOG: { gl_state.fog.enabled = 1; break; } default: { real_glEnable()(cap); break; } } } GL_FUNC(glDisable, void, (GLenum cap)); void glDisable(GLenum cap) { switch (cap) { case GL_ALPHA_TEST: { gl_state.alpha_test = 0; break; } case GL_TEXTURE_2D: { gl_state.texture_2d = 0; break; } case GL_COLOR_MATERIAL: { // Ignore break; } case GL_FOG: { gl_state.fog.enabled = 0; break; } default: { real_glDisable()(cap); break; } } } void glAlphaFunc(GLenum func, GLclampf ref) { if (func != GL_GREATER && ref != 0.1f) { ERR("Unsupported Alpha Function"); } } // Fog #define UNSUPPORTED_FOG() ERR("Unsupported Fog Configuration") void glFogfv(GLenum pname, const GLfloat *params) { if (pname == GL_FOG_COLOR) { memcpy((void *) gl_state.fog.color, params, sizeof (gl_state.fog.color)); } else { UNSUPPORTED_FOG(); } } void glFogx(GLenum pname, GLfixed param) { if (pname == GL_FOG_MODE && (param == GL_LINEAR || param == GL_EXP)) { gl_state.fog.mode = param; } else { UNSUPPORTED_FOG(); } } void glFogf(GLenum pname, GLfloat param) { switch (pname) { case GL_FOG_DENSITY: case GL_FOG_START: { gl_state.fog.start = param; break; } case GL_FOG_END: { gl_state.fog.end = param; break; } default: { UNSUPPORTED_FOG(); break; } } } // Get Matrix Data GL_FUNC(glGetFloatv, void, (GLenum pname, GLfloat *params)); void glGetFloatv(GLenum pname, GLfloat *params) { switch (pname) { case GL_MODELVIEW_MATRIX: { memcpy((void *) params, gl_state.matrix_stacks.model_view.stack[gl_state.matrix_stacks.model_view.i].data, MATRIX_DATA_SIZE); break; } case GL_PROJECTION_MATRIX: { memcpy((void *) params, gl_state.matrix_stacks.projection.stack[gl_state.matrix_stacks.projection.i].data, MATRIX_DATA_SIZE); break; } default: { real_glGetFloatv()(pname, params); break; } } }