void glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) { ERROR_IN_BLOCK(); PUSH_IF_COMPILING(glWindowPos3f); PROXY_GLES(glWindowPos3f); raster_state_t *raster = &state.raster; raster->pos.x = x; raster->pos.y = y; raster->pos.z = z; init_raster(); viewport_state_t *v = &state.viewport; if (x < v->x || x >= v->width || y < v->y || y >= v->height) { raster->valid = 0; } else { raster->valid = 1; } GLuint *dst = NULL; GLfloat *color = raster->color; if (pixel_convert(CURRENT->color, (GLvoid **)&dst, 1, 1, GL_RGBA, GL_FLOAT, GL_RGBA, GL_UNSIGNED_BYTE)) { memcpy(color, CURRENT->color, sizeof(GLfloat) * 4); raster->pixel = *dst; free(dst); } else { for (int i = 0; i < 4; i++) { color[i] = 1.0f; } raster->pixel = 0xFFFFFFFF; } }
void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { const GLubyte *from, *pixels = data; PUSH_IF_COMPILING(glDrawPixels); PROXY_GLES(glDrawPixels); raster_state_t *raster = &state.raster; if (! raster->valid) { return; } GLubyte *to; GLvoid *dst = NULL; init_raster(); if (! pixel_convert(data, &dst, width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE)) { return; } pixels = (GLubyte *)dst; // shrink our pixel ranges to stay inside the viewport int ystart = MAX(0, -raster->pos.y); height = MIN(state.viewport.height - raster->pos.y, height); int xstart = MAX(0, -raster->pos.x); int screen_width = MIN(state.viewport.width - raster->pos.x, width); for (int y = ystart; y < height; y++) { to = raster->buf + 4 * (GLuint)(raster->pos.x + ((raster->pos.y + y) * state.viewport.nwidth)); from = pixels + 4 * (xstart + y * width); memcpy(to, from, 4 * screen_width); } if (pixels != data) free((void *)pixels); }
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 glCallList(GLuint list) { PUSH_IF_COMPILING(glCallList); if (state.list.recursion >= 64) { return; } state.list.recursion++; displaylist_t *l = get_list(list); displaylist_t *active = state.list.active; if (l) { dl_call(l); } state.list.recursion--; }
void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { ERROR_IN_BLOCK(); PUSH_IF_COMPILING(glRasterPos3f); PROXY_GLES(glRasterPos3f); GLfloat v[3] = {x, y, z}; gl_transform_vertex(v, v); init_raster(); viewport_state_t *vs = &state.viewport; v[0] = (((v[0] + 1.0f) * 0.5f) * vs->width) + vs->x; v[1] = (((-v[1] + 1.0f) * 0.5f) * vs->height) + vs->y; // TODO: deal with Z glWindowPos3f(v[0], v[1], v[2]); }
void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) { block_t *block = state.block.active; if (block) { bl_track_tex(block, target); } GLfloat *tex = CURRENT->tex[target - GL_TEXTURE0]; tex[0] = s; tex[1] = t; if (! block) { PUSH_IF_COMPILING(glMultiTexCoord2f); } }
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { PUSH_IF_COMPILING(glViewport); PROXY_GLES(glViewport); if (state.raster.buf) { render_raster(); } gles_glViewport(x, y, width, height); viewport_state_t *viewport = &state.viewport; viewport->x = x; viewport->y = y; viewport->width = width; viewport->height = height; viewport->nwidth = npot(width); viewport->nheight = npot(height); }
void glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { // TODO: support xorig/yorig PUSH_IF_COMPILING(glBitmap); PROXY_GLES(glBitmap); raster_state_t *raster = &state.raster; struct { GLfloat x, y, z, w; } *pos = (void *)&raster->pos; if (! raster->valid) { return; } // TODO: negative width/height mirrors bitmap? if (!width && !height) { pos->x += xmove; pos->y += ymove; return; } init_raster(); const GLubyte *from; GLuint *to; int x, y; // copy to pixel data // TODO: strip blank lines and mirror vertically? for (y = 0; y < height; y++) { float dy = pos->y - y; to = (GLuint *)raster->buf + (GLuint)(pos->x + (dy * state.viewport.nwidth)); from = bitmap + (y * 2); for (x = 0; x < width; x += 8) { float dx = pos->x + x; if (dx < 0 || dx > state.viewport.width || dy < 0 || dy > state.viewport.height) continue; int max = 8; if (dx + 8 > state.viewport.width) max = state.viewport.width - dx; GLubyte b = *from++; for (int j = max - 1; j >= 0; j--) { *to++ = (b & (1 << j)) ? raster->pixel : 0; } } } pos->x += xmove; pos->y += ymove; }
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 }
void glDisable(GLenum cap) { PUSH_IF_COMPILING(glDisable); LOAD_GLES_SILENT(glDisable); ERROR_IN_BLOCK(); proxy_glEnable(cap, false, gles_glDisable); }