void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { clone_gl_pointer(state.pointers.color, size); if (state.remote) return; LOAD_GLES(glColorPointer); gles_glColorPointer(size, type, stride, pointer); }
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { LOAD_GLES(glVertexPointer); clone_gl_pointer(state.pointers.vertex, size); glGetError(); gles_glVertexPointer(size, type, stride, pointer); }
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { clone_gl_pointer(state.pointers.tex_coord[state.texture.client], size); if (state.remote) return; LOAD_GLES(glTexCoordPointer); gles_glTexCoordPointer(size, type, stride, pointer); }
// config functions const GLubyte *glGetString(GLenum name) { LOAD_GLES(glGetString); switch (name) { case GL_VERSION: #ifdef USE_ES2 return (GLubyte *)"4.3 glshim wrapper"; #else return (GLubyte *)"1.4 glshim wrapper"; #endif case GL_EXTENSIONS: return (const GLubyte *)(char *){ #ifndef USE_ES2 // "GL_ARB_vertex_buffer_object " "GL_EXT_secondary_color " #else "GL_ARB_vertex_shader " "GL_ARB_fragment_shader " "GL_ARB_vertex_buffer_object " "GL_EXT_framebuffer_object " #endif }; default: return gles_glGetString(name); } }
// Function to deactivate the Streaming texture on current tex... void DeactivateStreaming() { //printf("DeactivateStreaming()\n"); LOAD_GLES(glDisable); if (!gl_streaming) return; // gles_glDisable(GL_TEXTURE_STREAM_IMG); }
void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) { //printf("%sglLightModelfv(%04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", pname, params[0], params[1], params[2], params[3]); if (glstate->list.compiling && glstate->list.active) { NewStage(glstate->list.active, STAGE_LIGHTMODEL); /* if (glstate->list.active->lightmodel) glstate->list.active = extend_renderlist(glstate->list.active);*/ glstate->list.active->lightmodelparam = pname; glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); memcpy(glstate->list.active->lightmodel, params, 4*sizeof(GLfloat)); noerrorShim(); return; } LOAD_GLES(glLightModelfv); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: case GL_LIGHT_MODEL_TWO_SIDE: errorGL(); gles_glLightModelfv(pname, params); break; default: errorShim(GL_INVALID_ENUM); //printf("stubbed glLightModelfv(%i, %p [%.2f])\n", pname, params, params[0]); break; } }
void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { LOAD_GLES(glMaterialfv); if (state.list.active) { rlMaterialfv(state.list.active, face, pname, params); } else { gles_glMaterialfv(face, pname, params); } }
void glDisable(GLenum cap) { if (state.list.compiling && state.list.active) { push_glDisable(cap); } else { LOAD_GLES(glDisable); proxy_glEnable(cap, false, gles_glDisable); } }
// calls upstream glGetError and saves the flag for the next caller GLenum gl_get_error() { if (state.remote) { state.error = forward_glGetError(); } else { LOAD_GLES(glGetError); state.error = gles_glGetError(); } return state.error; }
void gl_set_error(GLenum error) { // call upstream glGetError to clear the driver's error flag if (state.remote) { forward_glGetError(); } else { LOAD_GLES(glGetError); gles_glGetError(); } state.error = error; }
void glNormal3f(GLfloat x, GLfloat y, GLfloat z) { if (state.list.active) { rlNormal3f(state.list.active, x, y, z); } #ifndef USE_ES2 else { LOAD_GLES(glNormal3f); gles_glNormal3f(x, y, z); } #endif }
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { PUSH_IF_COMPILING(glViewport); LOAD_GLES(glViewport); if (raster) { render_raster(); } gles_glViewport(x, y, width, height); viewport.x = x; viewport.y = y; viewport.width = width; viewport.height = height; }
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { PUSH_IF_COMPILING(glViewport); if (state.raster.buf) { render_raster(); } if (width < 0 || height < 0) { ERROR(GL_INVALID_VALUE); } update_viewport(x, y, width, height); LOAD_GLES(glViewport); gles_glViewport(x, y, width, height); }
void gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params) { //printf("%sglLightfv(%04X, %04X, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", light, pname, params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f); if (glstate->list.compiling && glstate->list.active) { NewStage(glstate->list.active, STAGE_LIGHT); rlLightfv(glstate->list.active, light, pname, params); noerrorShim(); return; } LOAD_GLES(glLightfv); gles_glLightfv(light, pname, params); errorGL(); }
GLboolean glIsEnabled(GLenum cap) { LOAD_GLES(glIsEnabled); switch (cap) { case GL_LINE_STIPPLE: return state.enable.line_stipple; case GL_TEXTURE_GEN_S: return state.enable.texgen_s; case GL_TEXTURE_GEN_T: return state.enable.texgen_t; default: return gles_glIsEnabled(cap); } }
void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { if (state.list.active) { rlColor4f(state.list.active, r, g, b, a); } #ifndef USE_ES2 else { LOAD_GLES(glColor4f); gles_glColor4f(r, g, b, a); state.color[0] = r; state.color[1] = g; state.color[2] = b; state.color[3] = a; } #endif }
void glGetIntegerv(GLenum pname, GLint *params) { LOAD_GLES(glGetIntegerv); switch (pname) { case GL_MAX_ELEMENTS_INDICES: *params = 1024; break; case GL_AUX_BUFFERS: *params = 0; break; default: gles_glGetIntegerv(pname, params); } }
// Function to activate the Steaming texture ID on current tex... void ActivateStreaming(int ID) { //printf("ActivateStreaming(%i)\n", ID); LOAD_GLES(glEnable); if (!gl_streaming) return; if ((ID<0) || (ID>9)) return; if (tex_free[ID]) return; if (!stream_cache[ID].active) return; // gles_glEnable(GL_TEXTURE_STREAM_IMG); glTexBindStreamIMG(ID, 0); }
GLenum glGetError() { if (state.block.active) { return GL_INVALID_OPERATION; } GLenum error; if (state.remote) { error = forward_glGetError(); } else { LOAD_GLES(glGetError); error = gles_glGetError(); } if (error == GL_NO_ERROR) { error = state.error; } state.error = GL_NO_ERROR; return error; }
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { block_t *block = state.block.active; if (block) { bl_track_normal(block); } GLfloat *normal = CURRENT->normal; normal[0] = nx; normal[1] = ny; normal[2] = nz; if (! block) { PUSH_IF_COMPILING(glNormal3f); LOAD_GLES(glNormal3f); gles_glNormal3f(nx, ny, nz); } }
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { block_t *block = state.block.active; if (block) { bl_track_color(block); } GLfloat *color = CURRENT->color; color[0] = red; color[1] = green; color[2] = blue; color[3] = alpha; #ifndef USE_ES2 if (! block) { PUSH_IF_COMPILING(glColor4f); LOAD_GLES(glColor4f); gles_glColor4f(red, green, blue, alpha); } #endif }
// config functions const GLubyte *glGetString(GLenum name) { FORWARD_IF_REMOTE(glGetString); LOAD_GLES(glGetString); if (state.block.active) { gl_set_error(GL_INVALID_OPERATION); return NULL; } switch (name) { case GL_VERSION: #ifdef USE_ES2 return (GLubyte *)"4.3 glshim wrapper"; #else return (GLubyte *)"1.4 glshim wrapper"; #endif case GL_EXTENSIONS: return (const GLubyte *)(char *){ #ifndef USE_ES2 // "GL_ARB_vertex_buffer_object " "GL_ARB_multitexture " "GL_ARB_texture_cube_map " "GL_EXT_secondary_color " "GL_EXT_texture_env_combine " "GL_EXT_texture_env_dot3 " // blending extensions "GL_EXT_blend_color " "GL_EXT_blend_equation_separate " "GL_EXT_blend_func_separate " "GL_EXT_blend_logic_op " "GL_EXT_blend_subtract " #else "GL_ARB_vertex_shader " "GL_ARB_fragment_shader " "GL_ARB_vertex_buffer_object " "GL_EXT_framebuffer_object " #endif }; default: return gles_glGetString(name); } }
void gl4es_glLightModelf(GLenum pname, GLfloat param) { //printf("%sglLightModelf(%04X, %.2f)\n", (state.list.compiling)?"list":"", pname, param); if (glstate->list.compiling && glstate->list.active) { GLfloat dummy[4]; dummy[0]=param; gl4es_glLightModelfv(pname, dummy); return; } LOAD_GLES(glLightModelf); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: case GL_LIGHT_MODEL_TWO_SIDE: errorGL(); gles_glLightModelf(pname, param); break; default: errorShim(GL_INVALID_ENUM); //printf("stubbed glLightModelf(%i, %.2f)\n", pname, param); break; } }
GLboolean glIsEnabled(GLenum cap) { if (state.block.active) { gl_set_error(GL_INVALID_OPERATION); return 0; } FORWARD_IF_REMOTE(glIsEnabled); switch (cap) { case GL_LINE_STIPPLE: return state.enable.line_stipple; case GL_TEXTURE_GEN_S: return state.enable.texgen_s[state.texture.active]; case GL_TEXTURE_GEN_T: return state.enable.texgen_t[state.texture.active]; case GL_TEXTURE_COORD_ARRAY: return state.enable.tex_coord_array[state.texture.client]; default: { LOAD_GLES(glIsEnabled); return gles_glIsEnabled(cap); } } }
void glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (mode == GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; displaylist_t *active = state.list.active; if (active) { block_t *block = block_from_arrays(mode, first, count); bl_end(block); dl_append_block(active, block); return; } if (should_intercept_render(mode)) { block_t *block = block_from_arrays(mode, first, count); bl_end(block); bl_draw(block); bl_free(block); } else { LOAD_GLES(glDrawArrays); gles_glDrawArrays(mode, first, count); } }
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *uindices) { // TODO: split for count > 65535? GLushort *indices = copy_gl_array(uindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); // TODO: do this in a more direct fashion. if (should_intercept_render(mode)) { glBegin(mode); for (int i = 0; i < count; i++) { glArrayElement(indices[i]); } glEnd(); free(indices); return; } bool compiling = (state.list.active && state.list.compiling); if (compiling) { renderlist_t *list = NULL; GLsizei min, max; if (compiling) list = state.list.active = extend_renderlist(state.list.active); normalize_indices(indices, &max, &min, count); list = arrays_to_renderlist(list, mode, 0, max + 1); list->indices = indices; list->len = count; end_renderlist(list); if (! compiling) { draw_renderlist(list); free_renderlist(list); } } else { LOAD_GLES(glDrawElements); gles_glDrawElements(mode, count, type, indices); free(indices); } }
void glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (mode == GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; renderlist_t *list, *active = state.list.active; if (active && state.list.compiling) { list = state.list.active = extend_renderlist(active); arrays_to_renderlist(list, mode, first, count); return; } if (should_intercept_render(mode)) { list = arrays_to_renderlist(NULL, mode, first, count); end_renderlist(list); draw_renderlist(list); free_renderlist(list); } else { // TODO: some draw states require us to use the full pipeline here // like texgen, stipple, npot LOAD_GLES(glDrawArrays); gles_glDrawArrays(mode, first, count); } }
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *uindices) { // TODO: split for count > 65535? GLushort *indices = gl_copy_array(uindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count, false); // TODO: do this in a more direct fashion. if (should_intercept_render(mode)) { glBegin(mode); state.block.active->artificial = true; for (int i = 0; i < count; i++) { glArrayElement(indices[i]); } glEnd(); free(indices); return; } displaylist_t *list = state.list.active; if (list) { GLsizei min, max; normalize_indices(indices, &max, &min, count); block_t *block = block_from_arrays(mode, min, max + 1); block->indices = indices; block->count = count; bl_end(block); if (list) { dl_append_block(list, block); } else { bl_draw(block); bl_free(block); } } else { LOAD_GLES(glDrawElements); gles_glDrawElements(mode, count, type, indices); free(indices); } }
void render_raster() { if (!state.viewport.width || !state.viewport.height || !state.raster.buf) return; // FIXME #ifndef USE_ES2 glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); GLfloat vert[] = { -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0, }; float sw = state.viewport.width / (GLfloat)state.viewport.nwidth; float sh = state.viewport.height / (GLfloat)state.viewport.nheight; GLfloat tex[] = { 0, sh, sw, sh, sw, 0, 0, 0, }; glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT | GL_CLIENT_PIXEL_STORE_BIT); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vert); glTexCoordPointer(2, GL_FLOAT, 0, tex); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, state.viewport.nwidth, state.viewport.nheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, state.raster.buf); LOAD_GLES(glDrawArrays); gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDeleteTextures(1, &texture); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glPopClientAttrib(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); #endif free(state.raster.buf); state.raster.buf = NULL; }
void glEnableClientState(GLenum cap) { LOAD_GLES(glEnableClientState); proxy_glEnable(cap, true, gles_glEnableClientState); }