Merge branch 'master' of github.com:hrydgard/native

This commit is contained in:
Henrik Rydgard 2012-07-08 18:51:17 +02:00
commit b061f3aa80
5 changed files with 22 additions and 451 deletions

View file

@ -1,34 +1,8 @@
#pragma once
// #define COLOR16
#ifdef COLOR16
typedef unsigned short Color;
#else
typedef unsigned int Color;
#endif
//have to use a define to ensure constant folding.. with an inline I don't get that, sucks
#ifdef COLOR16
#error
#define COLOR(i) (short16)(((i&0xF80000)>>8) | ((i&0xFC00)>>5) | ((i&0xF8)>>3))
inline Color darkenColor(Color color) {
return (color>>1)&0x7BEF;
}
inline Color whitenColor(Color color) {
return ((color>>1)&0x7BEF)+0x7BEF;
}
//single multiplication 16-bit color alpha blending... pretty cool huh?
inline Color colorInterpol(Color x, Color y, int n)
{
uint32 c1 = (x|(x<<16))&0x7E0F81F;
uint32 c2 = (y|(y<<16))&0x7E0F81F;
uint32 c = (c1 + ((c2 - c1)*n >> 5)) & 0x7E0F81F;
return c | (c >> 16);
}
#else
#define COLOR(i) (((i << 16) & 0xFF0000) | (i & 0xFF00) | ((i >> 16) & 0xFF) | 0xFF000000)
inline Color darkenColor(Color color) {
return (color & 0xFF000000) | ((color >> 1)&0x7F7F7F);
@ -39,5 +13,4 @@ inline Color whitenColor(Color color) {
inline Color colorInterpol(Color x, Color y, int n) {
// TODO
return x;
}
#endif
}

View file

@ -1,10 +0,0 @@
set(SRCS
draw_buffer.cpp
)
set(SRCS ${SRCS})
add_library(gfx_es1 STATIC ${SRCS})
if(UNIX)
add_definitions(-fPIC)
endif(UNIX)

View file

@ -1,287 +0,0 @@
// OpenGL ES 1.1
#ifdef ANDROID
#include <GLES/gl.h>
#else
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include "gfx_es1/draw_buffer.h"
#include "gfx/texture_atlas.h"
#include "main_atlas.h"
LAMEBuffer buffer;
LAMEBuffer topbuffer;
#define MAX_VERTS 16384
LAMEBuffer::LAMEBuffer() {
verts = new Vertex[MAX_VERTS];
vcount = 0;
xoffset = 0;
yoffset = 0;
fontscalex = 0.37f;
fontscaley = 0.37f;
}
LAMEBuffer::~LAMEBuffer() {
delete [] verts;
verts = 0;
}
void LAMEBuffer::Setup() {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
void LAMEBuffer::Finish() {
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// Draws what we have collected so far, so that we can change blend modes etc.
// TODO: Collect states and then blast at the end?
void LAMEBuffer::Flush() {
if (vcount > 0) {
glVertexPointer (3, GL_FLOAT, sizeof(Vertex), (void *)&verts[0].x);
glColorPointer (4, GL_UNSIGNED_BYTE, sizeof(Vertex), (void *)&verts[0].rgba);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void *)&verts[0].u);
glDrawArrays(GL_TRIANGLES, 0, vcount);
// printf("Drawing %i triangles\n", vcount / 3);
}
vcount = 0;
}
void LAMEBuffer::V(float x, float y, uint32 color, float u, float v) {
#ifndef ANDROID
if (vcount >= MAX_VERTS) {
printf("Hit max # verts\n");
}
#endif
verts[vcount].x = x + xoffset;
verts[vcount].y = y + yoffset;
verts[vcount].z = 0.0;
verts[vcount].rgba = color;
verts[vcount].u = u;
verts[vcount].v = v;
vcount++;
}
void LAMEBuffer::rectFill(int x1, int y1, int x2, int y2, Color color) {
rectFillFaded(x1, y1, x2, y2, color, color);
}
void LAMEBuffer::rectFillFaded(int x1, int y1, int x2, int y2, Color color1, Color color2) {
V(x1, y1, color1, 0, 0);
V(x2, y1, color1, 1, 0);
V(x2, y2, color2, 1, 1);
V(x1, y1, color1, 0, 0);
V(x2, y2, color2, 1, 1);
V(x1, y2, color2, 0, 1);
}
void LAMEBuffer::MeasureImage(int atlas_image, float *w, float *h) {
const AtlasImage &image = atlas->images[atlas_image];
*w = image.w;
*h = image.h;
}
void LAMEBuffer::DrawImage(int atlas_image, float x, float y, Color color) {
const AtlasImage &image = atlas->images[atlas_image];
float w = image.w;
float h = image.h;
DrawImageStretch(atlas_image, x, y, x + w, y + h, color);
}
void LAMEBuffer::DrawImageCenter(int atlas_image, float x, float y, Color color) {
const AtlasImage &image = atlas->images[atlas_image];
DrawImage(atlas_image, x - image.w/2, y - image.h/2, color);
}
void LAMEBuffer::DrawImageStretch(int atlas_image, float x1, float y1, float x2, float y2, Color color) {
const AtlasImage &image = atlas->images[atlas_image];
V(x1, y1, color, image.u1, image.v1);
V(x2, y1, color, image.u2, image.v1);
V(x2, y2, color, image.u2, image.v2);
V(x1, y1, color, image.u1, image.v1);
V(x2, y2, color, image.u2, image.v2);
V(x1, y2, color, image.u1, image.v2);
}
void LAMEBuffer::DrawTexRect(float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, Color color) {
V(x1, y1, color, u1, v1);
V(x2, y1, color, u2, v1);
V(x2, y2, color, u2, v2);
V(x1, y1, color, u1, v1);
V(x2, y2, color, u2, v2);
V(x1, y2, color, u1, v2);
}
void LAMEBuffer::DrawImage4Grid(int atlas_image, float x1, float y1, float x2, float y2, Color color, float corner_scale) {
const AtlasImage &image = atlas->images[atlas_image];
float um = (image.u2 - image.u1) * 0.5f;
float vm = (image.v2 - image.v1) * 0.5f;
float iw2 = (image.w * 0.5f) * corner_scale;
float ih2 = (image.h * 0.5f) * corner_scale;
float xa = x1 + iw2;
float xb = x2 - iw2;
float ya = y1 + ih2;
float yb = y2 - ih2;
float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2;
// Top row
DrawTexRect(x1, y1, xa, ya, u1, v1, um, vm, color);
DrawTexRect(xa, y1, xb, ya, um, v1, um, vm, color);
DrawTexRect(xb, y1, x2, ya, um, v1, u2, vm, color);
// Middle row
DrawTexRect(x1, ya, xa, yb, u1, vm, um, vm, color);
DrawTexRect(xa, ya, xb, yb, um, vm, um, vm, color);
DrawTexRect(xb, ya, x2, yb, um, vm, u2, vm, color);
// Bottom row
DrawTexRect(x1, yb, xa, y2, u1, vm, um, v2, color);
DrawTexRect(xa, yb, xb, y2, um, vm, um, v2, color);
DrawTexRect(xb, yb, x2, y2, um, vm, u2, v2, color);
}
void LAMEBuffer::DrawImage2GridH(int atlas_image, float x1, float y1, float x2, Color color, float corner_scale) {
const AtlasImage &image = atlas->images[atlas_image];
float um = (image.u2 - image.u1) * 0.5f;
float iw2 = (image.w * 0.5f) * corner_scale;
float xa = x1 + iw2;
float xb = x2 - iw2;
float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2;
float y2 = y1 + image.h;
DrawTexRect(x1, y1, xa, y2, u1, v1, um, v2, color);
DrawTexRect(xa, y1, xb, y2, um, v1, um, v2, color);
DrawTexRect(xb, y1, x2, y2, um, v1, u2, v2, color);
}
void LAMEBuffer::MeasureText(int font, const char *text, float *w, float *h) {
const AtlasFont &atlasfont = *atlas->fonts[font];
unsigned char cval;
float wacc = 0, maxh = 0;
while ((cval = *text++) != '\0') {
if (cval < 32) continue;
if (cval > 127) continue;
AtlasChar c = atlasfont.chars[cval - 32];
wacc += c.wx * fontscalex;
maxh = 10.0;
}
*w = wacc;
*h = maxh;
}
void LAMEBuffer::DrawText(int font, const char *text, float x, float y, Color color, int flags) {
const AtlasFont &atlasfont = *atlas->fonts[font];
unsigned char cval;
if (flags) {
float w, h;
MeasureText(font, text, &w, &h);
if (flags & TEXT_HCENTER) x -= w / 2;
if (flags & TEXT_RIGHT) x -= w;
if (flags & TEXT_VCENTER) y -= h / 2;
}
float sx = x;
while ((cval = *text++) != '\0') {
if (cval == '\n') {
y += 10;
x = sx;
continue;
}
if (cval < 32) continue;
if (cval > 127) continue;
AtlasChar c = atlasfont.chars[cval - 32];
float cx1 = x + c.ox * fontscalex;
float cy1 = y + c.oy * fontscaley;
float cx2 = x + (c.ox + c.pw) * fontscalex;
float cy2 = y + (c.oy + c.ph) * fontscaley;
V(cx1, cy1, color, c.sx, c.sy);
V(cx2, cy1, color, c.ex, c.sy);
V(cx2, cy2, color, c.ex, c.ey);
V(cx1, cy1, color, c.sx, c.sy);
V(cx2, cy2, color, c.ex, c.ey);
V(cx1, cy2, color, c.sx, c.ey);
x += c.wx * fontscalex;
}
}
void LAMEBuffer::hLine(int x1, int y, int x2, Color color) {
rectFill(x1, y, x2, y + 1, color | 0xFF000000);
}
void LAMEBuffer::hLineDarken(int x1, int y, int x2) {
rectFill(x1, y, x2, y + 1, 0x80000000);
}
void LAMEBuffer::vLine(int x, int y1, int y2, Color color) {
rectFill(x, y1, x + 1, y2, color);
}
void LAMEBuffer::vLineAlpha50(int x, int y1, int y2, Color color) {
vLine(x, y1, y2, (color & 0x00FFFFFF) | 0x80);
}
void LAMEBuffer::rect(int x1, int y1, int x2, int y2, Color color) {
hLine(x1, y1, x2, color);
hLine(x1, y2, x2, color);
vLine(x1, y1, y2, color);
vLine(x2, y1, y2, color);
}
void LAMEBuffer::rectFillDarken(int x1, int y1, int x2, int y2) {
rectFill(x1, y1, x2, y2, 0x80000000);
}
void LAMEBuffer::RotateSprite(int atlas_entry, float x, float y, float angle, float scale, Color color) {
// TODO - will be good for knobs
/*
float c = cos(angle + PI/4);
float s = sin(angle + PI/4);
float x1 = x + c * scale;
float y1 = y + s * scale;
float x2 = x + c * scale;
float y2 = y + s * scale;
float x3 = x + c * scale;
float y3 = y + s * scale;
V(x1, y1, color1, 0, 0);
V(x2, y1, color1, 1, 0);
V(x2, y2, color2, 1, 1);
V(x1, y1, color1, 0, 0);
V(x2, y2, color2, 1, 1);
V(x1, y2, color2, 0, 1);
*/
}
void LAMEBuffer::drawText(const TCHAR *text, int x, int y, Color color, int font) {
DrawText(UBUNTU24, text, x, y+3, color);
}
void LAMEBuffer::drawTextCenter(const TCHAR *text, int x, int y, Color color, int font) {
DrawText(UBUNTU24, text, x, y+3, color, TEXT_HCENTER);
}
void LAMEBuffer::drawTextShadow(const TCHAR *text, int x, int y, Color color, Color shadowColor, int font) {
DrawText(UBUNTU24, text, x, y+3, color);
}
void LAMEBuffer::drawTextShadowCenter(const TCHAR *text, int x, int y, Color color, Color shadowColor, int font) {
DrawText(UBUNTU24, text, x, y+3, color, TEXT_HCENTER);
}
void LAMEBuffer::drawTextContrastCenter(const TCHAR *text, int x, int y, Color color, Color shadowColor, int font) {
DrawText(UBUNTU24, text, x, y+3, color, TEXT_HCENTER);
}
void LAMEBuffer::drawTextContrast(const TCHAR *text, int x, int y, Color color, Color shadowColor, int font) {
DrawText(UBUNTU24, text, x, y+3, color);
}

View file

@ -1,122 +0,0 @@
// OpenGL-based 2D primitive buffer. For GLES 1.1.
#ifndef __LAMEBUFFER_H__
#define __LAMEBUFFER_H__
#include "base/basictypes.h"
#include "base/color.h"
class Atlas;
enum {
TEXT_LEFT = 0,
TEXT_BASELINE = 0,
TEXT_TOP = 1,
TEXT_BOTTOM = 2,
TEXT_HCENTER = 4,
TEXT_VCENTER = 8,
TEXT_RIGHT = 16,
};
// Do not inherit from this class.
class LAMEBuffer {
public:
LAMEBuffer();
~LAMEBuffer();
void SetAtlas(const Atlas *_atlas) {
atlas = _atlas;
}
void hLine(int x1, int y, int x2, Color color);
void hLineDarken(int x1, int y, int x2);
void vLine(int x, int y1, int y2, Color color);
void vLineAlpha50(int x, int y1, int y2, Color color);
void rect(int x1, int y1, int x2, int y2, Color color);
void rectFill(int x1, int y1, int x2, int y2, Color color);
void rectRectFill(int x1, int y1, int x2, int y2, Color border, Color fill) {
rectFill(x1,y1,x2,y2,fill);
rect(x1,y1,x2,y2,border);
}
void rectFillFaded(int x1, int y1, int x2, int y2, Color color1, Color color2);
void rectFillDarkFaded(int x1, int y1, int x2, int y2, Color color) {
rectFillFaded(x1,y1,x2,y2,color, darkenColor(color));
}
void rectFillDarken(int x1, int y1, int x2, int y2);
void MeasureImage(int atlas_image, float *w, float *h);
void DrawImage(int atlas_image, float x, float y, Color color = COLOR(0xFFFFFF));
void DrawImageCenter(int atlas_image, float x, float y, Color color = COLOR(0xFFFFFF));
void DrawImageStretch(int atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF));
void DrawTexRect(float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, Color color);
// Results in 18 triangles. Kind of expensive for a button.
void DrawImage4Grid(int atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF), float corner_scale = 1.0);
// This is only 6 triangles, much cheaper.
void DrawImage2GridH(int atlas_image, float x1, float y1, float x2, Color color = COLOR(0xFFFFFF), float scale = 1.0);
void MeasureText(int font, const char *text, float *w, float *h);
void DrawText(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int flags = 0);
void RotateSprite(int atlas_entry, float x, float y, float angle, float scale, Color color);
void drawText(const TCHAR *text, int x, int y, Color color = 0, int font=0);
void drawTextCenter(const TCHAR *text, int x, int y, Color color, int font=0);
void drawTextShadow(const TCHAR *text, int x, int y, Color color=0xffffffff, Color shadowColor=0xFF000000, int font=0);
void drawTextShadowCenter(const TCHAR *text, int x, int y, Color color=0xffffffff, Color shadowColor=0xFF000000, int font=0);
void drawTextContrastCenter(const TCHAR *text, int x, int y, Color color=0xffffffff, Color shadowColor=0xFF000000, int font=0);
void drawTextContrast(const TCHAR *text, int x, int y, Color color=0xffffffff, Color shadowColor=0xFF000000, int font=0);
void SetFontScale(float xs, float ys) {
fontscalex = xs;
fontscaley = ys;
}
// Offset management, for easier hierarchical drawing
void PushOffset(int xoff, int yoff) {
// TODO: Use a stack
xoffset = xoff; yoffset = yoff;
}
void PopOffset(int xoff, int yoff) {
xoffset = 0; yoffset = 0;
}
// Only use in bunches of three. To draw triangles.
inline void V(float x, float y, uint32 color, float u, float v);
// Call these around all Flush calls of drawbuffers. More than one flush call
// is fine.
static void Setup(); // Enables client state.
static void Finish(); // Disables client state
// Draws what we have collected so far, so that we can change blend modes etc.
void Flush();
private:
const Atlas *atlas;
float xoffset, yoffset;
float fontscalex;
float fontscaley;
struct Vertex {
float x, y, z;
uint32 rgba;
float u, v;
};
int vcount;
Vertex *verts;
};
// For regular non blended drawing. No alpha, no alpha test.
extern LAMEBuffer buffer;
// The two blend buffers could be combined using premultiplied alpha.
// But who cares.
// For regular blended drawing. Standard alpha, no alpha test.
extern LAMEBuffer topbuffer;
#endif //__LAMEBUFFER_H__

View file

@ -16,6 +16,7 @@ enum {
ALIGN_VCENTER = 8,
ALIGN_VBASELINE = 32, // text only, possibly not yet working
ALIGN_CENTER = ALIGN_HCENTER | ALIGN_VCENTER,
ALIGN_TOPLEFT = ALIGN_TOP | ALIGN_LEFT,
ALIGN_TOPRIGHT = ALIGN_TOP | ALIGN_RIGHT,
ALIGN_BOTTOMLEFT = ALIGN_BOTTOM | ALIGN_LEFT,
@ -51,16 +52,32 @@ public:
int Count() const { return count_; }
void Flush(const GLSLProgram *program, bool set_blend_state=true);
void Rect(float x, float y, float w, float h, uint32 color, int align = ALIGN_TOPLEFT);
void hLine(float x1, float y, float x2, uint32 color) { Rect(x1, y, x2 - x1, 1, color); }
void vLine(float x, float y1, float y2, uint32 color) { Rect(x, y1, 1, y2 - y1, color); }
void vLineAlpha50(float x, float y1, float y2, uint32 color) { Rect(x, y1, 1, y2 - y1, (color | 0xFF000000) & 0x7F000000); }
void RectOutline(float x, float y, float w, float h, uint32 color, int align = ALIGN_TOPLEFT) {
hLine(x, y, x + w + 1, color);
hLine(x, y + h, x + w + 1, color);
vLine(x, y, y + h + 1, color);
vLine(x + w, y, y + h + 1, color);
}
void RectVGradient(float x, float y, float w, float h, uint32 colorTop, uint32 colorBottom);
void RectVDarkFaded(float x, float y, float w, float h, uint32 colorTop) {
RectVGradient(x, y, w, h, colorTop, darkenColor(colorTop));
}
void MultiVGradient(float x, float y, float w, float h, GradientStop *stops, int numStops);
void RectCenter(float x, float y, float w, float h, uint32 color) {
Rect(x - w/2, y - h/2, w, h, color);
}
void Rect(float x, float y, float w, float h,
float u, float v, float uw, float uh, uint32 color);
void Rect(float x, float y, float w, float h, float u, float v, float uw, float uh, uint32 color);
void V(float x, float y, float z, uint32 color, float u, float v);
void V(float x, float y, uint32 color, float u, float v) {
V(x, y, 0.0f, color, u, v);
@ -85,8 +102,8 @@ public:
void DrawImage2GridH(int atlas_image, float x1, float y1, float x2, Color color = COLOR(0xFFFFFF), float scale = 1.0);
void MeasureText(int font, const char *text, float *w, float *h);
void DrawText(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int flags = 0);
void DrawTextShadow(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int flags = 0);
void DrawText(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
void DrawTextShadow(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
void RotateSprite(int atlas_entry, float x, float y, float angle, float scale, Color color);
void SetFontScale(float xs, float ys) {