Images are almost fully reimplemented.

Font sizing is pretty much fixed.
Just need to re-initialize textures with the renderer.
This commit is contained in:
Aloshi 2012-08-29 16:52:25 -05:00
parent cdb63c4a4f
commit 07d8046a3e
8 changed files with 177 additions and 104 deletions

View file

@ -19,6 +19,8 @@ void Font::initLibrary()
Font::Font(std::string path, int size) Font::Font(std::string path, int size)
{ {
mMaxGlyphHeight = 0;
if(FT_New_Face(sLibrary, path.c_str(), 0, &face)) if(FT_New_Face(sLibrary, path.c_str(), 0, &face))
{ {
std::cout << "Error creating font face! (path: " << path.c_str() << "\n"; std::cout << "Error creating font face! (path: " << path.c_str() << "\n";
@ -49,10 +51,9 @@ void Font::buildAtlas()
h = std::max(h, g->bitmap.rows); h = std::max(h, g->bitmap.rows);
}*/ }*/
//GLES requires a power of two //the max size (GL_MAX_TEXTURE_SIZE) is like 3300
//the max size (GL_MAX_TEXTURE_SIZE) is pretty small too, like 3300, so just force it
w = 2048; w = 2048;
h = 2048; h = 512;
textureWidth = w; textureWidth = w;
textureHeight = h; textureHeight = h;
@ -99,23 +100,29 @@ void Font::buildAtlas()
{ {
x = 0; x = 0;
y += maxHeight; y += maxHeight;
std::cout << "looping to next row, maxHeight: " << maxHeight << std::endl;
maxHeight = 0; maxHeight = 0;
} }
if(g->bitmap.rows > maxHeight) if(g->bitmap.rows > maxHeight)
maxHeight = g->bitmap.rows; maxHeight = g->bitmap.rows;
glTexSubImage2D(GL_TEXTURE_2D, 0, x, 0, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
charData[i].texX = x; charData[i].texX = x;
charData[i].texY = 0; charData[i].texY = y;
charData[i].texW = g->bitmap.width; charData[i].texW = g->bitmap.width;
charData[i].texH = g->bitmap.rows; charData[i].texH = g->bitmap.rows;
charData[i].advX = g->metrics.horiAdvance >> 6; charData[i].advX = g->metrics.horiAdvance >> 6;
charData[i].advY = g->advance.y >> 6; charData[i].advY = g->advance.y >> 6;
charData[i].bearingY = g->metrics.horiBearingY >> 6; charData[i].bearingY = g->metrics.horiBearingY >> 6;
if(charData[i].texH > mMaxGlyphHeight)
mMaxGlyphHeight = charData[i].texH;
x += g->bitmap.width; x += g->bitmap.width;
} }
@ -138,6 +145,8 @@ Font::~Font()
//openGL reads these in the order they are in memory //openGL reads these in the order they are in memory
//if I use an array, it will be 4 x values then 4 y values //if I use an array, it will be 4 x values then 4 y values
//it'll read XX, XX, YY instead of XY, XY, XY //it'll read XX, XX, YY instead of XY, XY, XY
//...
//that was the thinking at the time and honestly an array would have been smarter wow I'm dumb
struct point { struct point {
GLfloat pos0x; GLfloat pos0x;
GLfloat pos0y; GLfloat pos0y;
@ -162,8 +171,11 @@ struct tex {
void Font::drawText(std::string text, int startx, int starty, int color) void Font::drawText(std::string text, int startx, int starty, int color)
{ {
starty += mMaxGlyphHeight;
//padding (another 0.5% is added to the bottom through the sizeText function)
starty += Renderer::getScreenHeight() * 0.005;
starty += (face->height / face->units_per_EM) << 6; //(face->height / face->units_per_EM) << 6;
int pointCount = text.length() * 2; int pointCount = text.length() * 2;
point* points = new point[pointCount]; point* points = new point[pointCount];
@ -241,8 +253,6 @@ void Font::drawText(std::string text, int startx, int starty, int color)
} }
void Font::sizeText(std::string text, int* w, int* h) void Font::sizeText(std::string text, int* w, int* h)
{
if(w != NULL)
{ {
int cwidth = 0; int cwidth = 0;
for(unsigned int i = 0; i < text.length(); i++) for(unsigned int i = 0; i < text.length(); i++)
@ -250,9 +260,10 @@ void Font::sizeText(std::string text, int* w, int* h)
cwidth += charData[(int)text[i]].advX; cwidth += charData[(int)text[i]].advX;
} }
if(w != NULL)
*w = cwidth; *w = cwidth;
}
if(h != NULL) if(h != NULL)
*h = (face->height / face->units_per_EM) << 6; *h = mMaxGlyphHeight + Renderer::getScreenWidth() * 0.01;
} }

View file

@ -46,6 +46,7 @@ private:
int textureWidth; int textureWidth;
int textureHeight; int textureHeight;
int mMaxGlyphHeight;
}; };
#endif #endif

View file

@ -6,8 +6,11 @@
namespace Renderer { namespace Renderer {
bool loadedFonts = false; bool loadedFonts = false;
unsigned int getScreenWidth() { return 1680; } //defined and set in Renderer_init_rpi.cpp
unsigned int getScreenHeight() { return 1050; } extern unsigned int display_width;
extern unsigned int display_height;
unsigned int getScreenWidth() { return display_width; }
unsigned int getScreenHeight() { return display_height; }
void setColor4bArray(GLubyte* array, int color) void setColor4bArray(GLubyte* array, int color)
{ {
@ -52,25 +55,29 @@ namespace Renderer {
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
} }
Font* defaultFont = NULL;
Font* fonts[3] = {NULL, NULL, NULL};
void loadFonts() void loadFonts()
{ {
std::cout << "loading fonts\n"; std::cout << "loading fonts\n";
if(defaultFont != NULL) unsigned int fontSizes[] = {10, 12, 22};
delete defaultFont; for(unsigned int i = 0; i < 3; i++)
{
defaultFont = new Font("LinLibertine_R.ttf", 12); fonts[i] = new Font("LinLibertine_R.ttf", fontSizes[i]);
}
loadedFonts = true; loadedFonts = true;
} }
void unloadFonts() void unloadFonts()
{ {
if(defaultFont) for(unsigned int i = 0; i < 3; i++)
{ {
delete defaultFont; delete fonts[i];
defaultFont = NULL; fonts[i] = NULL;
} }
loadedFonts = false; loadedFonts = false;
@ -78,7 +85,10 @@ namespace Renderer {
Font* getFont(FontSize size) Font* getFont(FontSize size)
{ {
return defaultFont; if(!loadedFonts)
loadFonts();
return fonts[size];
} }
@ -88,7 +98,7 @@ namespace Renderer {
loadFonts(); loadFonts();
int h; int h;
getFont(size)->sizeText("", NULL, &h); getFont(size)->sizeText("HEIGHT", NULL, &h);
return h; return h;
} }

View file

@ -15,7 +15,10 @@ namespace Renderer
static EGL_DISPMANX_WINDOW_T nativewindow; static EGL_DISPMANX_WINDOW_T nativewindow;
bool createSurface() unsigned int display_width = 0;
unsigned int display_height = 0;
bool createSurface() //unsigned int display_width, unsigned int display_height)
{ {
std::cout << "Creating surface...\n"; std::cout << "Creating surface...\n";
@ -83,10 +86,8 @@ namespace Renderer
if(!display_width || !display_height)
unsigned int display_width; {
unsigned int display_height;
bool success = graphics_get_display_size(0, &display_width, &display_height); //0 = LCD bool success = graphics_get_display_size(0, &display_width, &display_height); //0 = LCD
if(success < 0) if(success < 0)
@ -94,6 +95,7 @@ namespace Renderer
std::cerr << "Error getting display size!\n"; std::cerr << "Error getting display size!\n";
return false; return false;
} }
}
std::cout << "Display size is " << display_width << "x" << display_height << "\n"; std::cout << "Display size is " << display_width << "x" << display_height << "\n";
@ -139,7 +141,7 @@ namespace Renderer
void swapBuffers() void swapBuffers()
{ {
eglSwapBuffers(display, surface); eglSwapBuffers(display, surface);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void destroySurface() void destroySurface()
@ -154,15 +156,21 @@ namespace Renderer
bool init(int w, int h) bool init(int w, int h)
{ {
bcm_host_init(); bcm_host_init();
bool surface = createSurface();
if(!surface) if(w)
display_width = w;
if(h)
display_height = h;
bool createdSurface = createSurface();
if(!createdSurface)
return false; return false;
Font::initLibrary(); Font::initLibrary();
glViewport(0, 0, 1680, 1050); glViewport(0, 0, display_width, display_height);
glOrthof(0, 1680, 1050, 0, -1.0, 1.0); glOrthof(0, display_width, display_height, 0, -1.0, 1.0);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
return true; return true;

View file

@ -26,7 +26,6 @@ GuiGameList::GuiGameList(bool useDetail)
mScreenshot = new GuiImage(Renderer::getScreenWidth() * sInfoWidth * 0.5, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * sInfoWidth * 0.7); mScreenshot = new GuiImage(Renderer::getScreenWidth() * sInfoWidth * 0.5, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * sInfoWidth * 0.7);
mScreenshot->setOrigin(0.5, 0.0); mScreenshot->setOrigin(0.5, 0.0);
mScreenshot->setAlpha(true); //slower, but requested
addChild(mScreenshot); addChild(mScreenshot);
}else{ }else{
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2); mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
@ -96,7 +95,7 @@ void GuiGameList::onRender()
ss << FRAMERATE; ss << FRAMERATE;
std::string fps; std::string fps;
ss >> fps; ss >> fps;
Renderer::drawText(fps, 0, 0, 0x00FF00); Renderer::drawText(fps, 100, 0, 0x00FF00);
#endif #endif
//header //header

View file

@ -5,7 +5,7 @@
int GuiImage::getWidth() { return mWidth; } int GuiImage::getWidth() { return mWidth; }
int GuiImage::getHeight() { return mHeight; } int GuiImage::getHeight() { return mHeight; }
GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int maxWidth, unsigned int maxHeight, bool resizeExact) GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool resizeExact)
{ {
mTextureID = 0; mTextureID = 0;
@ -21,8 +21,8 @@ GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int maxW
mTiled = false; mTiled = false;
mMaxWidth = maxWidth; mResizeWidth = resizeWidth;
mMaxHeight = maxHeight; mResizeHeight = resizeHeight;
mResizeExact = resizeExact; mResizeExact = resizeExact;
mUseAlpha = false; mUseAlpha = false;
@ -115,9 +115,6 @@ void GuiImage::loadImage(std::string path)
//force power of two for testing
//width = 512; height = 512;
//now for the openGL texture stuff //now for the openGL texture stuff
glGenTextures(1, &mTextureID); glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID); glBindTexture(GL_TEXTURE_2D, mTextureID);
@ -135,6 +132,36 @@ void GuiImage::loadImage(std::string path)
//free the memory from that pointer //free the memory from that pointer
delete[] imageRGBA; delete[] imageRGBA;
//a simple way to resize: lie about our real texture size!
//(we don't resize tiled images)
if(!mTiled)
{
float resizeScaleX = 0, resizeScaleY = 0;
if(mResizeExact)
{
if(mResizeWidth)
resizeScaleX = (float)mResizeWidth / mWidth;
if(mResizeHeight)
resizeScaleY = (float)mResizeHeight / mHeight;
}else{
if(mResizeWidth && mWidth > mResizeWidth)
resizeScaleX = (float)mResizeWidth / mWidth;
if(mResizeHeight && mHeight > mResizeHeight)
resizeScaleY = (float)mResizeHeight / mHeight;
}
if(resizeScaleX && !resizeScaleY)
resizeScaleY = resizeScaleX;
if(resizeScaleY && !resizeScaleX)
resizeScaleX = resizeScaleY;
if(resizeScaleX)
mWidth *= resizeScaleX;
if(resizeScaleY)
mHeight *= resizeScaleY;
}
std::cout << "Image load successful, w: " << mWidth << " h: " << mHeight << " texID: " << mTextureID << "\n"; std::cout << "Image load successful, w: " << mWidth << " h: " << mHeight << " texID: " << mTextureID << "\n";
} }
@ -184,19 +211,36 @@ void GuiImage::setAlpha(bool useAlpha)
void GuiImage::onRender() void GuiImage::onRender()
{ {
if(mTextureID) if(mTextureID)
{
if(mTiled)
{
for(unsigned int x = 0; x < (unsigned int)((float)mResizeWidth/mWidth + 1.5); x++)
{
for(unsigned int y = 0; y < (unsigned int)((float)mResizeHeight/mHeight + 1.5); y++)
{
drawImage(mOffsetX + x*mWidth, mOffsetY + y*mHeight);
}
}
}else{
drawImage(mOffsetX, mOffsetY);
}
}
}
void GuiImage::drawImage(int posX, int posY)
{ {
glBindTexture(GL_TEXTURE_2D, mTextureID); glBindTexture(GL_TEXTURE_2D, mTextureID);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
GLfloat points[12]; GLfloat points[12];
points[0] = mOffsetX - (mWidth * mOriginX); points[1] = mOffsetY - (mHeight * mOriginY); points[0] = posX - (mWidth * mOriginX); points[1] = posY - (mHeight * mOriginY);
points[2] = mOffsetX - (mWidth * mOriginX); points[3] = mOffsetY + (mHeight * (1 - mOriginY)); points[2] = posX - (mWidth * mOriginX); points[3] = posY + (mHeight * (1 - mOriginY));
points[4] = mOffsetX + (mWidth * (1 - mOriginX)); points[5] = mOffsetY - (mHeight * mOriginY); points[4] = posX + (mWidth * (1 - mOriginX)); points[5] = posY - (mHeight * mOriginY);
points[6] = mOffsetX + (mWidth * (1 - mOriginX)); points[7] = mOffsetY - (mHeight * mOriginY); points[6] = posX + (mWidth * (1 - mOriginX)); points[7] = posY - (mHeight * mOriginY);
points[8] = mOffsetX - (mWidth * mOriginX); points[9] = mOffsetY + (mHeight * (1 - mOriginY)); points[8] = posX - (mWidth * mOriginX); points[9] = posY + (mHeight * (1 - mOriginY));
points[10] = mOffsetX + (mWidth * (1 -mOriginX)); points[11] = mOffsetY + (mHeight * (1 - mOriginY)); points[10] = posX + (mWidth * (1 -mOriginX)); points[11] = posY + (mHeight * (1 - mOriginY));
//std::cout << "x: " << points[0] << " y: " << points[1] << " to x: " << points[10] << " y: " << points[11] << std::endl; //std::cout << "x: " << points[0] << " y: " << points[1] << " to x: " << points[10] << " y: " << points[11] << std::endl;
//std::cout << "(w: " << mWidth << " h: " << mHeight << ")" << std::endl; //std::cout << "(w: " << mWidth << " h: " << mHeight << ")" << std::endl;
@ -211,8 +255,6 @@ void GuiImage::onRender()
texs[10] = 1; texs[11] = 0; texs[10] = 1; texs[11] = 0;
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@ -225,5 +267,5 @@ void GuiImage::onRender()
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} glDisable(GL_BLEND);
} }

View file

@ -23,11 +23,12 @@ public:
void onRender(); void onRender();
private: private:
int mMaxWidth, mMaxHeight; unsigned int mResizeWidth, mResizeHeight;
float mOriginX, mOriginY; float mOriginX, mOriginY;
bool mResizeExact, mTiled, mUseAlpha; bool mResizeExact, mTiled, mUseAlpha;
void loadImage(std::string path); void loadImage(std::string path);
void drawImage(int x, int y);
void unloadImage(); void unloadImage();
std::string mPath; std::string mPath;

View file

@ -32,8 +32,8 @@ int main(int argc, char* argv[])
SDL_Surface* sdlScreen = SDL_SetVideoMode(1, 1, 0, SDL_SWSURFACE); SDL_Surface* sdlScreen = SDL_SetVideoMode(1, 1, 0, SDL_SWSURFACE);
std::cout << "Fake SDL window is " << sdlScreen->w << "x" << sdlScreen->h << "\n"; std::cout << "Fake SDL window is " << sdlScreen->w << "x" << sdlScreen->h << "\n";
int width = 0; unsigned int width = 0;
int height = 0; unsigned int height = 0;
if(argc > 1) if(argc > 1)
{ {
for(int i = 1; i < argc; i++) for(int i = 1; i < argc; i++)
@ -56,7 +56,8 @@ int main(int argc, char* argv[])
} }
} }
if(!Renderer::init(width, height)) bool renderInit = Renderer::init(width, height);
if(!renderInit)
{ {
std::cerr << "Error initializing renderer!\n"; std::cerr << "Error initializing renderer!\n";
return 1; return 1;