forked from mia/Aegisub
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:
parent
f1c9a1695d
commit
dbd64d935e
4 changed files with 166 additions and 19 deletions
|
@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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]));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue