Create text textures only once

parent d40e5496
......@@ -22,11 +22,23 @@
#include <cmath>
#include <string>
#include <vector>
#include <SDL_ttf.h>
#include <SDL_opengl.h>
class Text
{
private:
/** OpenGL textures containing the text */
std::vector<GLuint> textures;
/** Width of each text */
std::vector<int> width;
/** Height of each text */
std::vector<int> height;
/** Index of the next text, that should be rendered */
int nextText;
public:
Text()
{
......@@ -45,6 +57,9 @@ public:
~Text()
{
// We assume that std::vector is just an array ...
glDeleteTextures(textures.size(), &textures[0]);
instances--;
if (instances == 0) {
......@@ -53,6 +68,34 @@ public:
}
}
void addText(const char* text)
{
if (!font)
return;
// Draw string
SDL_Color black = {0, 0, 0, 255};
SDL_Surface* surf = TTF_RenderText_Blended(font, text, black);
if (surf) {
GLuint texture;
/* Tell GL about our new texture */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, surf->pixels);
width.push_back(surf->w);
height.push_back(surf->h);
textures.push_back(texture);
/* Clean up */
SDL_FreeSurface(surf);
}
}
void startTextMode()
{
// Enable 2D mode
......@@ -70,68 +113,60 @@ public:
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
nextText = 0;
}
void showText(const char* text, SDL_Rect &location)
/**
* @return True there are more textures
*/
bool showNextText(SDL_Rect &location)
{
if (!font)
return;
// Draw string
SDL_Color black = {0, 0, 0, 255};
SDL_Surface* surf = TTF_RenderText_Blended(font, text, black);
if (surf) {
unsigned int texture;
/* Tell GL about our new texture */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, surf->pixels);
/* GL_NEAREST looks horrible, if scaled... */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* prepare to render our texture */
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glColor3f(1.0f, 1.0f, 1.0f);
/* Draw a quad at location */
glBegin(GL_QUADS);
/* Recall that the origin is in the lower-left corner
That is why the TexCoords specify different corners
than the Vertex coords seem to. */
glTexCoord2f(0.0f, 1.0f);
glVertex2f(location.x, location.y - surf->h);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(location.x + surf->w, location.y - surf->h);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(location.x + surf->w, location.y);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(location.x, location.y);
glEnd();
/* Bad things happen if we delete the texture before it finishes */
glFinish();
/* return the deltas in the unused w,h part of the rect */
location.w = surf->w;
location.h = surf->h;
/* Clean up */
SDL_FreeSurface(surf);
glDeleteTextures(1, &texture);
}
return false;
if (nextText >= textures.size())
// No more textures to show
return false;
/* GL_NEAREST looks horrible, if scaled... */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* prepare to render our texture */
glBindTexture(GL_TEXTURE_2D, textures[nextText]);
/* Draw a quad at location */
glBegin(GL_QUADS);
/* Recall that the origin is in the lower-left corner
That is why the TexCoords specify different corners
than the Vertex coords seem to. */
glTexCoord2f(0.0f, 1.0f);
glVertex2f(location.x, location.y - height[nextText]);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(location.x + width[nextText], location.y - height[nextText]);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(location.x + width[nextText], location.y);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(location.x, location.y);
glEnd();
/* return the deltas in the unused w,h part of the rect */
location.w = width[nextText];
location.h = height[nextText];
nextText++;
return nextText < textures.size();
}
void endTextMode()
{
// Disable 2D mode
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
......
......@@ -50,6 +50,21 @@ Visualization::Visualization(int windowWidth, int windowHeight, const char* wind
initCUDA();
#ifdef USESDLTTF
text = new Text();
text->addText("Keys:");
#ifdef ASAGI
text->addText(" 1-7: Select scenario");
#else // ASAGI
text->addText(" 1-3: Select scenario");
#endif // ASAGI
text->addText(" Space: Pause/Resume");
text->addText(" ->: Next frame (when paused)");
text->addText(" r: Restart scenario");
text->addText(" +/-: Scale wave height");
text->addText("Mouse:");
text->addText(" Left button: rotate");
text->addText(" Right button: move");
text->addText(" Middle button: reset camera");
text->addText(" Wheel: zoom in/out");
#endif // USESDLTTF
// Load camera and shaders
......@@ -141,31 +156,8 @@ void Visualization::renderDisplay() {
#ifdef USESDLTTF
text->startTextMode();
SDL_Rect location = {5, windowHeight-5, 0, 0};
text->showText("Keys:", location);
location.y -= location.h;
#ifdef ASAGI
text->showText(" 1-7: Select scenario", location);
#else // ASAGI
text->showText(" 1-3: Select scenario", location);
#endif // ASAGI
location.y -= location.h;
text->showText(" Space: Pause/Resume", location);
location.y -= location.h;
text->showText(" ->: Next frame (when paused)", location);
location.y -= location.h;
text->showText(" r: Restart scenario", location);
location.y -= location.h;
text->showText(" +/-: Scale wave height", location);
location.y -= location.h;
text->showText("Mouse:", location);
location.y -= location.h;
text->showText(" Left button: rotate", location);
location.y -= location.h;
text->showText(" Right button: move", location);
location.y -= location.h;
text->showText(" Middle button: reset camera", location);
location.y -= location.h;
text->showText(" Wheel: zoom in/out", location);
while (text->showNextText(location))
location.y -= location.h;
text->endTextMode();
#endif // USESDLTTF
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment