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
|
||||
void OpenGLText::DoSetFont(wxString face,int size) {
|
||||
void OpenGLText::DoSetFont(wxString face,int size,bool bold,bool italics) {
|
||||
// No change required
|
||||
if (size == fontSize && face == fontFace) return;
|
||||
if (size == fontSize && face == fontFace && bold == fontBold && italics == fontItalics) return;
|
||||
|
||||
// Set font
|
||||
fontFace = face;
|
||||
fontSize = size;
|
||||
fontBold = bold;
|
||||
fontItalics = italics;
|
||||
font.SetFaceName(fontFace);
|
||||
font.SetPointSize(size);
|
||||
font.SetWeight(bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
|
||||
|
||||
// Delete all old data
|
||||
Reset();
|
||||
|
@ -107,14 +110,35 @@ void OpenGLText::DoSetColour(wxColour col,float alpha) {
|
|||
/////////
|
||||
// Print
|
||||
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
|
||||
int dx=x,dy=y;
|
||||
size_t len = text.Length();
|
||||
OpenGLTextGlyph glyph;
|
||||
lineHeight = 16; // FIXME
|
||||
|
||||
// Set OpenGL
|
||||
// TODO
|
||||
lineHeight = 0;
|
||||
int dx=x,dy=y;
|
||||
|
||||
// Draw string
|
||||
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.Draw(dx,dy);
|
||||
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
|
||||
OpenGLTextGlyph OpenGLText::GetGlyph(int i) {
|
||||
|
@ -216,7 +279,7 @@ OpenGLTextTexture::~OpenGLTextTexture() {
|
|||
|
||||
//////////////////////////
|
||||
// Can fit a glyph in it?
|
||||
bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
||||
bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph &glyph) {
|
||||
// Get size
|
||||
int w = glyph.w;
|
||||
int h = glyph.h;
|
||||
|
@ -225,18 +288,18 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
|||
|
||||
// Can fit in this row?
|
||||
if (x + w < width) {
|
||||
Insert(glyph);
|
||||
x += w;
|
||||
if (y+h > nextY) nextY = y+h;
|
||||
Insert(glyph);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can fit the next row?
|
||||
else {
|
||||
y = nextY;
|
||||
if (y+h > height) return false;
|
||||
nextY = y+h;
|
||||
if (nextY+h > height) return false;
|
||||
x = 0;
|
||||
y = nextY;
|
||||
nextY = y+h;
|
||||
Insert(glyph);
|
||||
return true;
|
||||
}
|
||||
|
@ -245,7 +308,7 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) {
|
|||
|
||||
//////////
|
||||
// Insert
|
||||
void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) {
|
||||
void OpenGLTextTexture::Insert(OpenGLTextGlyph &glyph) {
|
||||
// Glyph data
|
||||
wxString str = wxChar(glyph.value);
|
||||
int w = glyph.w;
|
||||
|
@ -259,17 +322,34 @@ void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) {
|
|||
glyph.tex = tex;
|
||||
|
||||
// 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);
|
||||
|
||||
// Draw text and convert to image
|
||||
dc.SetFont(OpenGLText::GetFont());
|
||||
dc.SetTextForeground(wxColour(255,255,255));
|
||||
dc.DrawText(str,0,0);
|
||||
//bmp.SaveFile(wxString::Format(_T("glyph%i.bmp"),glyph.value),wxBITMAP_TYPE_BMP);
|
||||
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
|
||||
const unsigned char* src = img.GetData();
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,src);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
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.");
|
||||
}
|
||||
|
||||
|
@ -281,9 +361,8 @@ void OpenGLTextGlyph::Draw(int x,int y) {
|
|||
glPushMatrix();
|
||||
glTranslatef((float)x,(float)y,0.0f);
|
||||
|
||||
// Set blend
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
// Set texture
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
// Draw quad
|
||||
glBegin(GL_QUADS);
|
||||
|
@ -301,8 +380,7 @@ void OpenGLTextGlyph::Draw(int x,int y) {
|
|||
glVertex2f(w,0);
|
||||
glEnd();
|
||||
|
||||
// Restore GL state
|
||||
glDisable(GL_BLEND);
|
||||
// Restore matrix
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
|
|
@ -69,12 +69,12 @@ private:
|
|||
int x,y,nextY;
|
||||
int width,height;
|
||||
|
||||
void Insert(OpenGLTextGlyph glyph);
|
||||
void Insert(OpenGLTextGlyph &glyph);
|
||||
|
||||
public:
|
||||
GLuint tex;
|
||||
|
||||
bool TryToInsert(OpenGLTextGlyph glyph);
|
||||
bool TryToInsert(OpenGLTextGlyph &glyph);
|
||||
|
||||
OpenGLTextTexture(int w,int h);
|
||||
~OpenGLTextTexture();
|
||||
|
@ -88,6 +88,8 @@ private:
|
|||
float r,g,b,a;
|
||||
int lineHeight;
|
||||
int fontSize;
|
||||
bool fontBold;
|
||||
bool fontItalics;
|
||||
wxString fontFace;
|
||||
wxFont font;
|
||||
|
||||
|
@ -104,13 +106,16 @@ private:
|
|||
void Reset();
|
||||
|
||||
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 DoPrint(wxString text,int x,int y);
|
||||
void DrawString(wxString text,int x,int y);
|
||||
void DoGetExtent(wxString text,int &w,int &h);
|
||||
|
||||
public:
|
||||
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 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
|
||||
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
|
||||
// Just check for it and call it manually instead
|
||||
if (event.Leaving()) {
|
||||
OnMouseLeave(event);
|
||||
event.Skip(true);
|
||||
return;
|
||||
|
|
|
@ -501,34 +501,24 @@ void VideoDisplayVisual::DrawOverlay() {
|
|||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
// Setup text
|
||||
OpenGLText::SetFont(_T("Verdana"),10);
|
||||
OpenGLText::Print(mouseText,x,y);
|
||||
int tw,th;
|
||||
OpenGLText::SetFont(_T("Verdana"),12,true);
|
||||
OpenGLText::SetColour(wxColour(255,255,255));
|
||||
OpenGLText::GetExtent(mouseText,tw,th);
|
||||
|
||||
//// Setup text
|
||||
//wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana"));
|
||||
//dc.SetFont(font);
|
||||
//int tw,th;
|
||||
//parent->GetTextExtent(mouseText,&tw,&th,NULL,NULL,&font);
|
||||
// Calculate draw position
|
||||
bool left = x > w/2;
|
||||
bool bottom = y < h/2;
|
||||
|
||||
//// Inversion
|
||||
//bool left = x > w/2;
|
||||
//bool bottom = y < h/2;
|
||||
// Text draw coords
|
||||
int dx = x,dy = y;
|
||||
if (left) dx -= tw + 4;
|
||||
else dx += 4;
|
||||
if (bottom) dy += 3;
|
||||
else dy -= th + 3;
|
||||
|
||||
//// Text draw coords
|
||||
//int dx = x,dy = y;
|
||||
//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);
|
||||
// Draw text
|
||||
OpenGLText::Print(mouseText,dx,dy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue