static int GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLshort *vertices; GLES_SetBlendMode(data, renderer->blendMode, 1); data->glColor4f((GLfloat) renderer->r * inv255f, (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); vertices = SDL_stack_alloc(GLshort, count*2); for (i = 0; i < count; ++i) { vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+1] = (GLshort)points[i].y; } data->glVertexPointer(2, GL_SHORT, 0, vertices); data->glEnableClientState(GL_VERTEX_ARRAY); if (count > 2 && points[0].x == points[count-1].x && points[0].y == points[count-1].y) { /* GL_LINE_LOOP takes care of the final segment */ --count; data->glDrawArrays(GL_LINE_LOOP, 0, count); } else { data->glDrawArrays(GL_LINE_STRIP, 0, count); } data->glDisableClientState(GL_VERTEX_ARRAY); SDL_stack_free(vertices); return 0; }
static int GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLshort *vertices; GLES_SetBlendMode(data, renderer->blendMode, 1); data->glColor4f((GLfloat) renderer->r * inv255f, (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); vertices = SDL_stack_alloc(GLshort, count*2); for (i = 0; i < count; ++i) { vertices[2*i+0] = (GLshort)points[i].x; vertices[2*i+1] = (GLshort)points[i].y; } data->glVertexPointer(2, GL_SHORT, 0, vertices); data->glEnableClientState(GL_VERTEX_ARRAY); data->glDrawArrays(GL_POINTS, 0, count); data->glDisableClientState(GL_VERTEX_ARRAY); SDL_stack_free(vertices); return 0; }
static int GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; int i; GLES_SetBlendMode(data, renderer->blendMode, 1); data->glColor4f((GLfloat) renderer->r * inv255f, (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); data->glEnableClientState(GL_VERTEX_ARRAY); for (i = 0; i < count; ++i) { const SDL_Rect *rect = rects[i]; GLshort minx = rect->x; GLshort maxx = rect->x + rect->w; GLshort miny = rect->y; GLshort maxy = rect->y + rect->h; GLshort vertices[8]; vertices[0] = minx; vertices[1] = miny; vertices[2] = maxx; vertices[3] = miny; vertices[4] = minx; vertices[5] = maxy; vertices[6] = maxx; vertices[7] = maxy; data->glVertexPointer(2, GL_SHORT, 0, vertices); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } data->glDisableClientState(GL_VERTEX_ARRAY); return 0; }
/* This is called if we need to invalidate all of the SDL OpenGL state */ static void GLES_ResetState(SDL_Renderer *renderer) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; if (SDL_CurrentContext == data->context) { GLES_UpdateViewport(renderer); } else { GLES_ActivateRenderer(renderer); } data->current.color = 0xffffffff; data->current.blendMode = SDL_BLENDMODE_INVALID; data->current.tex_coords = SDL_FALSE; data->glDisable(GL_DEPTH_TEST); data->glDisable(GL_CULL_FACE); data->glMatrixMode(GL_MODELVIEW); data->glLoadIdentity(); data->glEnableClientState(GL_VERTEX_ARRAY); data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; int minx, miny, maxx, maxy; GLfloat minu, maxu, minv, maxv; int i; void *temp_buffer; /* used for reformatting dirty rect pixels */ void *temp_ptr; data->glEnable(GL_TEXTURE_2D); if (texturedata->dirty.list) { SDL_DirtyRect *dirty; void *pixels; int bpp = SDL_BYTESPERPIXEL(texture->format); int pitch = texturedata->pitch; SetupTextureUpdate(data, texture, pitch); data->glBindTexture(texturedata->type, texturedata->texture); for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { SDL_Rect *rect = &dirty->rect; pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + rect->x * bpp); /* There is no GL_UNPACK_ROW_LENGTH in OpenGLES we must do this reformatting ourselves(!) maybe it'd be a good idea to keep a temp buffer around for this purpose rather than allocating it each time */ temp_buffer = SDL_malloc(rect->w * rect->h * bpp); temp_ptr = temp_buffer; for (i = 0; i < rect->h; i++) { SDL_memcpy(temp_ptr, pixels, rect->w * bpp); temp_ptr += rect->w * bpp; pixels += pitch; } data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y, rect->w, rect->h, texturedata->format, texturedata->formattype, temp_buffer); SDL_free(temp_buffer); } SDL_ClearDirtyRects(&texturedata->dirty); } data->glBindTexture(texturedata->type, texturedata->texture); if (texture->modMode) { data->glColor4f((GLfloat) texture->r * inv255f, (GLfloat) texture->g * inv255f, (GLfloat) texture->b * inv255f, (GLfloat) texture->a * inv255f); } else { data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } GLES_SetBlendMode(data, texture->blendMode, 0); switch (texture->scaleMode) { case SDL_TEXTURESCALEMODE_NONE: case SDL_TEXTURESCALEMODE_FAST: data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST); data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; case SDL_TEXTURESCALEMODE_SLOW: case SDL_TEXTURESCALEMODE_BEST: data->glTexParameteri(texturedata->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); data->glTexParameteri(texturedata->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; } if (data->GL_OES_draw_texture_supported && data->useDrawTexture) { /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */ SDL_Window *window = renderer->window; GLint cropRect[4]; cropRect[0] = srcrect->x; cropRect[1] = srcrect->y + srcrect->h; cropRect[2] = srcrect->w; cropRect[3] = -srcrect->h; data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); data->glDrawTexiOES(dstrect->x, window->h - dstrect->y - dstrect->h, 0, dstrect->w, dstrect->h); } else { minx = dstrect->x; miny = dstrect->y; maxx = dstrect->x + dstrect->w; maxy = dstrect->y + dstrect->h; minu = (GLfloat) srcrect->x / texture->w; minu *= texturedata->texw; maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; maxu *= texturedata->texw; minv = (GLfloat) srcrect->y / texture->h; minv *= texturedata->texh; maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; maxv *= texturedata->texh; GLshort vertices[8]; GLfloat texCoords[8]; vertices[0] = minx; vertices[1] = miny; vertices[2] = maxx; vertices[3] = miny; vertices[4] = minx; vertices[5] = maxy; vertices[6] = maxx; vertices[7] = maxy; texCoords[0] = minu; texCoords[1] = minv; texCoords[2] = maxu; texCoords[3] = minv; texCoords[4] = minu; texCoords[5] = maxv; texCoords[6] = maxu; texCoords[7] = maxv; data->glVertexPointer(2, GL_SHORT, 0, vertices); data->glEnableClientState(GL_VERTEX_ARRAY); data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); data->glEnableClientState(GL_TEXTURE_COORD_ARRAY); data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); data->glDisableClientState(GL_VERTEX_ARRAY); } data->glDisable(GL_TEXTURE_2D); return 0; }