Almost working gl text code (seemingly uploads and retrieves glyphs fine, but only rendering white rectangles, and there are many things that could be causing that)

Originally committed to SVN as r1071.
This commit is contained in:
Rodrigo Braz Monteiro 2007-04-13 03:52:25 +00:00
parent f1c9a1695d
commit dbd64d935e
4 changed files with 166 additions and 19 deletions

View File

@ -37,6 +37,7 @@
///////////
// Headers
#include "gl_text.h"
#include "utils.h"
///////////////////
@ -79,6 +80,17 @@ OpenGLText* OpenGLText::GetInstance() {
////////////
// Set font
void OpenGLText::DoSetFont(wxString face,int size) {
// No change required
if (size == fontSize && face == fontFace) return;
// Set font
fontFace = face;
fontSize = size;
font.SetFaceName(fontFace);
font.SetPointSize(size);
// Delete all old data
Reset();
}
@ -95,6 +107,33 @@ void OpenGLText::DoSetColour(wxColour col,float alpha) {
/////////
// Print
void OpenGLText::DoPrint(wxString text,int x,int y) {
// Variables
int dx=x,dy=y;
size_t len = text.Length();
OpenGLTextGlyph glyph;
lineHeight = 16; // FIXME
// Set OpenGL
// TODO
// Draw string
for (size_t i=0;i<len;i++) {
// Get current character
int curChar = text[i];
// Handle carriage returns
if (curChar == '\n') {
dx = x;
dy += lineHeight;
}
// Handle normal glyphs
else {
glyph = GetGlyph(curChar);
glyph.Draw(dx,dy);
dx += glyph.w;
}
}
}
@ -116,11 +155,8 @@ OpenGLTextGlyph OpenGLText::GetGlyph(int i) {
OpenGLTextGlyph OpenGLText::CreateGlyph(int n) {
// Create glyph
OpenGLTextGlyph glyph;
glyph.x = 0;
glyph.y = 0;
glyph.w = 16;
glyph.h = 16;
glyph.tex = 0;
glyph.value = n;
glyph.GetMetrics();
// Insert into some texture
bool ok = false;
@ -146,9 +182,25 @@ OpenGLTextGlyph OpenGLText::CreateGlyph(int n) {
///////////////////////
// Texture constructor
OpenGLTextTexture::OpenGLTextTexture(int w,int h) {
width = w;
height = h;
// Properties
x = y = 0;
width = SmallestPowerOf2(w);
height = SmallestPowerOf2(h);
tex = 0;
// Generate and bind
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
// Texture parameters
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
// Allocate texture
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,width,height,0,GL_ALPHA,GL_UNSIGNED_BYTE,NULL);
if (glGetError()) throw _T("Could not allocate Text Texture");
}
@ -156,6 +208,7 @@ OpenGLTextTexture::OpenGLTextTexture(int w,int h) {
// Texture destructor
OpenGLTextTexture::~OpenGLTextTexture() {
if (tex) {
glDeleteTextures(1,&tex);
tex = 0;
}
}
@ -167,6 +220,8 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
// Get size
int w = glyph.w;
int h = glyph.h;
if (w > width) return false;
if (y+h > height) return false;
// Can fit in this row?
if (x + w < width) {
@ -178,21 +233,95 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
// Can fit the next row?
else {
if (w < width) {
y = nextY;
nextY = y+h;
x = 0;
Insert(glyph);
return true;
}
y = nextY;
if (y+h > height) return false;
nextY = y+h;
x = 0;
Insert(glyph);
return true;
}
// Can't fit
return false;
}
//////////
// Insert
void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) {
// Glyph data
wxString str = wxChar(glyph.value);
int w = glyph.w;
int h = glyph.h;
// Fill glyph structure
glyph.x1 = float(x)/width;
glyph.y1 = float(y)/height;
glyph.x2 = float(x+w)/width;
glyph.y2 = float(y+h)/height;
glyph.tex = tex;
// Create bitmap and bind it to a DC
wxBitmap bmp(w,h,24);
wxMemoryDC dc(bmp);
// Draw text and convert to image
dc.SetFont(OpenGLText::GetFont());
dc.DrawText(str,0,0);
wxImage img = bmp.ConvertToImage();
// Upload image to video memory
const unsigned char* src = img.GetData();
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,src);
if (glGetError()) throw _T("Error uploading glyph data to video memory.");
}
////////////////
// Draw a glyph
void OpenGLTextGlyph::Draw(int x,int y) {
// Store matrix and translate
glPushMatrix();
glTranslatef((float)x,(float)y,0.0f);
// Set blend
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// Draw quad
glBegin(GL_QUADS);
// Top-left
glTexCoord2f(x1,y1);
glVertex2f(0,0);
// Bottom-left
glTexCoord2f(x1,y2);
glVertex2f(0,h);
// Bottom-right
glTexCoord2f(x2,y2);
glVertex2f(w,h);
// Top-right
glTexCoord2f(x2,y1);
glVertex2f(w,0);
glEnd();
// Restore GL state
glDisable(GL_BLEND);
glPopMatrix();
}
/////////////////////
// Get glyph metrics
wxBitmap *OpenGLTextGlyph::tempBmp = NULL;
void OpenGLTextGlyph::GetMetrics() {
// Glyph data
wxCoord desc,lead;
wxString str = wxChar(value);
// Create bitmap, if needed
if (!tempBmp) tempBmp = new wxBitmap(16,16,24);
// Get text extents
{
wxMemoryDC dc(*tempBmp);
dc.SetFont(OpenGLText::GetFont());
dc.GetTextExtent(str,&w,&h,&desc,&lead);
}
}

View File

@ -46,10 +46,17 @@
/////////////////////
// Glyph information
class OpenGLTextGlyph {
private:
static wxBitmap *tempBmp;
public:
int value;
int tex;
float x,y;
float x1,y1,x2,y2;
int w,h;
void GetMetrics();
void Draw(int x,int y);
};
typedef std::map<int,OpenGLTextGlyph> glyphMap;
@ -79,6 +86,11 @@ public:
class OpenGLText {
private:
float r,g,b,a;
int lineHeight;
int fontSize;
wxString fontFace;
wxFont font;
static OpenGLText* instance;
glyphMap glyphs;
@ -97,6 +109,7 @@ private:
void DoPrint(wxString text,int x,int y);
public:
static wxFont GetFont() { return GetInstance()->font; }
static void SetFont(wxString face,int size) { GetInstance()->DoSetFont(face,size); }
static void SetColour(wxColour col,float alpha=1.0f) { GetInstance()->DoSetColour(col,alpha); }
static void Print(wxString text,int x,int y) { GetInstance()->DoPrint(text,x,y); }

View File

@ -517,7 +517,7 @@ GLuint VideoContext::GetFrameAsTexture(int n) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if (glGetError() != 0) throw _T("Error setting wrap_t texture parameter.");
// Load image data into texture
// Allocate texture
int height = frame.h;
if (frame.format == FORMAT_YV12) height = height * 3 / 2;
int tw = SmallestPowerOf2(MAX(frame.pitch[0]/frame.GetBpp(0),frame.pitch[1]+frame.pitch[2]));

View File

@ -54,6 +54,7 @@
#include "subs_edit_box.h"
#include "export_visible_lines.h"
#include "utils.h"
#include "gl_text.h"
///////////////
@ -499,6 +500,10 @@ void VideoDisplayVisual::DrawOverlay() {
glEnd();
glDisable(GL_COLOR_LOGIC_OP);
// Setup text
OpenGLText::SetFont(_T("Verdana"),10);
OpenGLText::Print(mouseText,x,y);
//// Setup text
//wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana"));
//dc.SetFont(font);