mirror of https://github.com/odrling/Aegisub
Completed (although it could still use some new features) OpenGL Text drawing code, and fully re-implemented video mouse coordinates.
Originally committed to SVN as r1072.
This commit is contained in:
parent
dbd64d935e
commit
51cd2f5ced
|
@ -79,15 +79,18 @@ OpenGLText* OpenGLText::GetInstance() {
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
// Set font
|
// Set font
|
||||||
void OpenGLText::DoSetFont(wxString face,int size) {
|
void OpenGLText::DoSetFont(wxString face,int size,bool bold,bool italics) {
|
||||||
// No change required
|
// No change required
|
||||||
if (size == fontSize && face == fontFace) return;
|
if (size == fontSize && face == fontFace && bold == fontBold && italics == fontItalics) return;
|
||||||
|
|
||||||
// Set font
|
// Set font
|
||||||
fontFace = face;
|
fontFace = face;
|
||||||
fontSize = size;
|
fontSize = size;
|
||||||
|
fontBold = bold;
|
||||||
|
fontItalics = italics;
|
||||||
font.SetFaceName(fontFace);
|
font.SetFaceName(fontFace);
|
||||||
font.SetPointSize(size);
|
font.SetPointSize(size);
|
||||||
|
font.SetWeight(bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
|
||||||
|
|
||||||
// Delete all old data
|
// Delete all old data
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -107,14 +110,35 @@ void OpenGLText::DoSetColour(wxColour col,float alpha) {
|
||||||
/////////
|
/////////
|
||||||
// Print
|
// Print
|
||||||
void OpenGLText::DoPrint(wxString text,int x,int y) {
|
void OpenGLText::DoPrint(wxString text,int x,int y) {
|
||||||
|
// Set OpenGL
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
// Draw border
|
||||||
|
glColor4f(0.0f,0.0f,0.0f,1.0f);
|
||||||
|
DrawString(text,x-1,y);
|
||||||
|
DrawString(text,x+1,y);
|
||||||
|
DrawString(text,x,y-1);
|
||||||
|
DrawString(text,x,y+1);
|
||||||
|
|
||||||
|
// Draw primary string
|
||||||
|
glColor4f(r,g,b,a);
|
||||||
|
DrawString(text,x,y);
|
||||||
|
|
||||||
|
// Disable blend
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// Draw a string
|
||||||
|
void OpenGLText::DrawString(wxString text,int x,int y) {
|
||||||
// Variables
|
// Variables
|
||||||
int dx=x,dy=y;
|
|
||||||
size_t len = text.Length();
|
size_t len = text.Length();
|
||||||
OpenGLTextGlyph glyph;
|
OpenGLTextGlyph glyph;
|
||||||
lineHeight = 16; // FIXME
|
lineHeight = 0;
|
||||||
|
int dx=x,dy=y;
|
||||||
// Set OpenGL
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// Draw string
|
// Draw string
|
||||||
for (size_t i=0;i<len;i++) {
|
for (size_t i=0;i<len;i++) {
|
||||||
|
@ -132,11 +156,50 @@ void OpenGLText::DoPrint(wxString text,int x,int y) {
|
||||||
glyph = GetGlyph(curChar);
|
glyph = GetGlyph(curChar);
|
||||||
glyph.Draw(dx,dy);
|
glyph.Draw(dx,dy);
|
||||||
dx += glyph.w;
|
dx += glyph.w;
|
||||||
|
if (glyph.h > lineHeight) lineHeight = glyph.h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Calculate text extent
|
||||||
|
void OpenGLText::DoGetExtent(wxString text,int &w,int &h) {
|
||||||
|
// Variables
|
||||||
|
size_t len = text.Length();
|
||||||
|
OpenGLTextGlyph glyph;
|
||||||
|
lineHeight = 0;
|
||||||
|
int dx=0,dy=0;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
|
||||||
|
// Simulate drawing of string
|
||||||
|
for (size_t i=0;i<len;i++) {
|
||||||
|
// Get current character
|
||||||
|
int curChar = text[i];
|
||||||
|
|
||||||
|
// Handle carriage returns
|
||||||
|
if (curChar == '\n') {
|
||||||
|
if (dx > w) w = dx;
|
||||||
|
dx = 0;
|
||||||
|
dy += lineHeight;
|
||||||
|
lineHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle normal glyphs
|
||||||
|
else {
|
||||||
|
glyph = GetGlyph(curChar);
|
||||||
|
dx += glyph.w;
|
||||||
|
if (glyph.h > lineHeight) lineHeight = glyph.h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return results
|
||||||
|
if (dx > w) w = dx;
|
||||||
|
h = dy+lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Get a glyph
|
// Get a glyph
|
||||||
OpenGLTextGlyph OpenGLText::GetGlyph(int i) {
|
OpenGLTextGlyph OpenGLText::GetGlyph(int i) {
|
||||||
|
@ -216,7 +279,7 @@ OpenGLTextTexture::~OpenGLTextTexture() {
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// Can fit a glyph in it?
|
// Can fit a glyph in it?
|
||||||
bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph &glyph) {
|
||||||
// Get size
|
// Get size
|
||||||
int w = glyph.w;
|
int w = glyph.w;
|
||||||
int h = glyph.h;
|
int h = glyph.h;
|
||||||
|
@ -225,18 +288,18 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
||||||
|
|
||||||
// Can fit in this row?
|
// Can fit in this row?
|
||||||
if (x + w < width) {
|
if (x + w < width) {
|
||||||
|
Insert(glyph);
|
||||||
x += w;
|
x += w;
|
||||||
if (y+h > nextY) nextY = y+h;
|
if (y+h > nextY) nextY = y+h;
|
||||||
Insert(glyph);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can fit the next row?
|
// Can fit the next row?
|
||||||
else {
|
else {
|
||||||
y = nextY;
|
if (nextY+h > height) return false;
|
||||||
if (y+h > height) return false;
|
|
||||||
nextY = y+h;
|
|
||||||
x = 0;
|
x = 0;
|
||||||
|
y = nextY;
|
||||||
|
nextY = y+h;
|
||||||
Insert(glyph);
|
Insert(glyph);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +308,7 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// Insert
|
// Insert
|
||||||
void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) {
|
void OpenGLTextTexture::Insert(OpenGLTextGlyph &glyph) {
|
||||||
// Glyph data
|
// Glyph data
|
||||||
wxString str = wxChar(glyph.value);
|
wxString str = wxChar(glyph.value);
|
||||||
int w = glyph.w;
|
int w = glyph.w;
|
||||||
|
@ -259,17 +322,34 @@ void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) {
|
||||||
glyph.tex = tex;
|
glyph.tex = tex;
|
||||||
|
|
||||||
// Create bitmap and bind it to a DC
|
// Create bitmap and bind it to a DC
|
||||||
wxBitmap bmp(w,h,24);
|
wxBitmap bmp(((w+1)/2)*2,((h+1)/2)*2,24);
|
||||||
wxMemoryDC dc(bmp);
|
wxMemoryDC dc(bmp);
|
||||||
|
|
||||||
// Draw text and convert to image
|
// Draw text and convert to image
|
||||||
dc.SetFont(OpenGLText::GetFont());
|
dc.SetFont(OpenGLText::GetFont());
|
||||||
|
dc.SetTextForeground(wxColour(255,255,255));
|
||||||
dc.DrawText(str,0,0);
|
dc.DrawText(str,0,0);
|
||||||
|
//bmp.SaveFile(wxString::Format(_T("glyph%i.bmp"),glyph.value),wxBITMAP_TYPE_BMP);
|
||||||
wxImage img = bmp.ConvertToImage();
|
wxImage img = bmp.ConvertToImage();
|
||||||
|
|
||||||
|
// Convert to alpha
|
||||||
|
int imgw = img.GetWidth();
|
||||||
|
int imgh = img.GetHeight();
|
||||||
|
size_t len = imgw*imgh;
|
||||||
|
const unsigned char *src = img.GetData();
|
||||||
|
const unsigned char *read = src;
|
||||||
|
unsigned char *alpha = new unsigned char[len*2];
|
||||||
|
unsigned char *write = alpha;
|
||||||
|
for (size_t i=0;i<len;i++) {
|
||||||
|
*write++ = 255;
|
||||||
|
*write++ = *read++;
|
||||||
|
read += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Upload image to video memory
|
// Upload image to video memory
|
||||||
const unsigned char* src = img.GetData();
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,src);
|
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,imgw,imgh,GL_LUMINANCE_ALPHA,GL_UNSIGNED_BYTE,alpha);
|
||||||
|
delete[] alpha;
|
||||||
if (glGetError()) throw _T("Error uploading glyph data to video memory.");
|
if (glGetError()) throw _T("Error uploading glyph data to video memory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,9 +361,8 @@ void OpenGLTextGlyph::Draw(int x,int y) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef((float)x,(float)y,0.0f);
|
glTranslatef((float)x,(float)y,0.0f);
|
||||||
|
|
||||||
// Set blend
|
// Set texture
|
||||||
glEnable(GL_BLEND);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
// Draw quad
|
// Draw quad
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
@ -301,8 +380,7 @@ void OpenGLTextGlyph::Draw(int x,int y) {
|
||||||
glVertex2f(w,0);
|
glVertex2f(w,0);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
// Restore GL state
|
// Restore matrix
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,12 +69,12 @@ private:
|
||||||
int x,y,nextY;
|
int x,y,nextY;
|
||||||
int width,height;
|
int width,height;
|
||||||
|
|
||||||
void Insert(OpenGLTextGlyph glyph);
|
void Insert(OpenGLTextGlyph &glyph);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
|
|
||||||
bool TryToInsert(OpenGLTextGlyph glyph);
|
bool TryToInsert(OpenGLTextGlyph &glyph);
|
||||||
|
|
||||||
OpenGLTextTexture(int w,int h);
|
OpenGLTextTexture(int w,int h);
|
||||||
~OpenGLTextTexture();
|
~OpenGLTextTexture();
|
||||||
|
@ -88,6 +88,8 @@ private:
|
||||||
float r,g,b,a;
|
float r,g,b,a;
|
||||||
int lineHeight;
|
int lineHeight;
|
||||||
int fontSize;
|
int fontSize;
|
||||||
|
bool fontBold;
|
||||||
|
bool fontItalics;
|
||||||
wxString fontFace;
|
wxString fontFace;
|
||||||
wxFont font;
|
wxFont font;
|
||||||
|
|
||||||
|
@ -104,13 +106,16 @@ private:
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
static OpenGLText* GetInstance();
|
static OpenGLText* GetInstance();
|
||||||
void DoSetFont(wxString face,int size);
|
void DoSetFont(wxString face,int size,bool bold,bool italics);
|
||||||
void DoSetColour(wxColour col,float alpha);
|
void DoSetColour(wxColour col,float alpha);
|
||||||
void DoPrint(wxString text,int x,int y);
|
void DoPrint(wxString text,int x,int y);
|
||||||
|
void DrawString(wxString text,int x,int y);
|
||||||
|
void DoGetExtent(wxString text,int &w,int &h);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static wxFont GetFont() { return GetInstance()->font; }
|
static wxFont GetFont() { return GetInstance()->font; }
|
||||||
static void SetFont(wxString face,int size) { GetInstance()->DoSetFont(face,size); }
|
static void SetFont(wxString face=_T("Verdana"),int size=10,bool bold=true,bool italics=false) { GetInstance()->DoSetFont(face,size,bold,italics); }
|
||||||
static void SetColour(wxColour col,float alpha=1.0f) { GetInstance()->DoSetColour(col,alpha); }
|
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); }
|
static void Print(wxString text,int x,int y) { GetInstance()->DoPrint(text,x,y); }
|
||||||
|
static void GetExtent(wxString text,int &w,int &h) { GetInstance()->DoGetExtent(text,w,h); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -345,9 +345,12 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
|
||||||
// Disable when playing
|
// Disable when playing
|
||||||
if (VideoContext::Get()->IsPlaying()) return;
|
if (VideoContext::Get()->IsPlaying()) return;
|
||||||
|
|
||||||
if (event.Leaving()) {
|
// Set mode, for whatever reason this is needed
|
||||||
|
visual->SetMode(visual->mode);
|
||||||
|
|
||||||
// OnMouseLeave isn't called as long as we have an OnMouseEvent
|
// OnMouseLeave isn't called as long as we have an OnMouseEvent
|
||||||
// Just check for it and call it manually instead
|
// Just check for it and call it manually instead
|
||||||
|
if (event.Leaving()) {
|
||||||
OnMouseLeave(event);
|
OnMouseLeave(event);
|
||||||
event.Skip(true);
|
event.Skip(true);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -501,34 +501,24 @@ void VideoDisplayVisual::DrawOverlay() {
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
|
||||||
// Setup text
|
// Setup text
|
||||||
OpenGLText::SetFont(_T("Verdana"),10);
|
int tw,th;
|
||||||
OpenGLText::Print(mouseText,x,y);
|
OpenGLText::SetFont(_T("Verdana"),12,true);
|
||||||
|
OpenGLText::SetColour(wxColour(255,255,255));
|
||||||
|
OpenGLText::GetExtent(mouseText,tw,th);
|
||||||
|
|
||||||
//// Setup text
|
// Calculate draw position
|
||||||
//wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana"));
|
bool left = x > w/2;
|
||||||
//dc.SetFont(font);
|
bool bottom = y < h/2;
|
||||||
//int tw,th;
|
|
||||||
//parent->GetTextExtent(mouseText,&tw,&th,NULL,NULL,&font);
|
|
||||||
|
|
||||||
//// Inversion
|
// Text draw coords
|
||||||
//bool left = x > w/2;
|
int dx = x,dy = y;
|
||||||
//bool bottom = y < h/2;
|
if (left) dx -= tw + 4;
|
||||||
|
else dx += 4;
|
||||||
|
if (bottom) dy += 3;
|
||||||
|
else dy -= th + 3;
|
||||||
|
|
||||||
//// Text draw coords
|
// Draw text
|
||||||
//int dx = x,dy = y;
|
OpenGLText::Print(mouseText,dx,dy);
|
||||||
//if (left) dx -= tw + 4;
|
|
||||||
//else dx += 4;
|
|
||||||
//if (bottom) dy += 3;
|
|
||||||
//else dy -= th + 3;
|
|
||||||
|
|
||||||
//// Draw text
|
|
||||||
//dc.SetTextForeground(wxColour(64,64,64));
|
|
||||||
//dc.DrawText(mouseText,dx+1,dy-1);
|
|
||||||
//dc.DrawText(mouseText,dx+1,dy+1);
|
|
||||||
//dc.DrawText(mouseText,dx-1,dy-1);
|
|
||||||
//dc.DrawText(mouseText,dx-1,dy+1);
|
|
||||||
//dc.SetTextForeground(colour[2]);
|
|
||||||
//dc.DrawText(mouseText,dx,dy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue