void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { if (state.block.active) { ERROR(GL_INVALID_OPERATION); } PROXY_GLES(glRasterPos3f); raster_state_t *raster = &state.raster; // TODO: glRasterPos4f? // TODO: actually project, and clear the valid bit if we end up outside the viewport raster->pos.x = x; raster->pos.y = y; raster->pos.z = z; 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) { raster_state_t *raster = &state.raster; if (! raster->valid) { return; } const GLubyte *from, *pixels = data; GLubyte *to; GLvoid *dst = NULL; PROXY_GLES(glDrawPixels); 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(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 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 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 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 glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { PROXY_GLES(glBitmap); raster_state_t *raster = &state.raster; if (! raster->valid) { return; } // TODO: negative width/height mirrors bitmap? if (!width && !height) { raster->pos.x += xmove; raster->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++) { to = (GLuint *)raster->buf + (GLuint)(raster->pos.x + ((raster->pos.y - y) * state.viewport.nwidth)); from = bitmap + (y * 2); for (x = 0; x < width; x += 8) { if (raster->pos.x + x > state.viewport.width || raster->pos.y - y > state.viewport.height) continue; GLubyte b = *from++; for (int j = 8; j--; ) { *to++ = (b & (1 << j)) ? raster->pixel : 0; } } } raster->pos.x += xmove; raster->pos.y += ymove; }