|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
fkrauthan Junior JLI'ler
Alter: 33 Anmeldedatum: 10.04.2005 Beiträge: 96 Wohnort: Germering Medaillen: Keine
|
Verfasst am: 25.01.2008, 14:18 Titel: OpenGL und ttf Problem |
|
|
Hallo ich habe mir folgende Klasse zusammen geschrieben. Das Problem ist sie zeigt keinen Schriftzug an.
TextManager2D.h
CPP: | #ifndef TEXTMANAGER2D_H_
#define TEXTMANAGER2D_H_
#ifdef WIN32
#include <SDL.h>
#include <SDL_opengl.h>
#else
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#endif
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
#include <freetype/fttrigon.h>
#include <map>
#include <string>
#include <vector>
#include "../Singleton.h"
#define g_pTextManager2D CTextManager2D::Get()
using namespace std;
struct font_data {
float h;
GLuint * textures;
GLuint list_base;
};
class CTextManager2D : public TSingelton<CTextManager2D> {
public:
CTextManager2D();
~CTextManager2D();
bool Init();
int AddFont(char* cFontName, int iSize);
void DelFont(int iFontID);
void RenderText(int iFontID, char* cText, float x, float y, SDL_Color color);
void fRenderText(int iFontID, float x, float y, SDL_Color color, char* cText, ...);
protected:
void CleanUpALL();
void make_dlist(FT_Face face, char ch, GLuint list_base, GLuint* tex_base);
FT_Library m_ftLibrary;
map<int,font_data> m_mFontList;
inline int next_p2 (int a) {
int rval=1;
while(rval<a) rval*=2;
return rval;
}
inline void pushScreenCoordinateMatrix() {
glPushAttrib(GL_TRANSFORM_BIT);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3]);
glPopAttrib();
}
inline void pop_projection_matrix() {
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
};
#endif /*TEXTMANAGER2D_H_*/
|
Und die TextManager2D.cpp
CPP: | #include "TextManager2D.h"
CTextManager2D::CTextManager2D() {
}
CTextManager2D::~CTextManager2D() {
CleanUpALL();
FT_Done_FreeType(m_ftLibrary);
}
void CTextManager2D::CleanUpALL() {
}
bool CTextManager2D::Init() {
if(FT_Init_FreeType(&m_ftLibrary)!=0)
return false;
return true;
}
void CTextManager2D::make_dlist(FT_Face face, char ch, GLuint list_base, GLuint* tex_base) {
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT))
return;
FT_Glyph glyph;
if(FT_Get_Glyph(face->glyph, &glyph))
return;
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
FT_Bitmap& bitmap=bitmap_glyph->bitmap;
int width = next_p2(bitmap.width);
int height = next_p2(bitmap.rows);
GLubyte* expanded_data = new GLubyte[2 * width * height];
for(int j=0; j <height;j++) {
for(int i=0; i < width; i++){
expanded_data[2*(i+j*width)]= expanded_data[2*(i+j*width)+1] = (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
}
}
glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
delete [] expanded_data;
glNewList(list_base+ch,GL_COMPILE);
glBindTexture(GL_TEXTURE_2D,tex_base[ch]);
glTranslatef(bitmap_glyph->left,0,0);
glPushMatrix();
glTranslatef(0,bitmap_glyph->top-bitmap.rows,0);
float x=(float)bitmap.width / (float)width, y=(float)bitmap.rows / (float)height;
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2f(0,bitmap.rows);
glTexCoord2d(0,y); glVertex2f(0,0);
glTexCoord2d(x,y); glVertex2f(bitmap.width,0);
glTexCoord2d(x,0); glVertex2f(bitmap.width,bitmap.rows);
glEnd();
glPopMatrix();
glTranslatef(face->glyph->advance.x >> 6 ,0,0);
glEndList();
}
int CTextManager2D::AddFont(char* cFontName, int iSize) {
FT_Face face;
if(FT_New_Face(m_ftLibrary, cFontName, 0, &face)) return -1;
FT_Set_Char_Size(face, iSize << 6, iSize << 6, 96, 96);
font_data font;
font.list_base=glGenLists(128);
glGenTextures(128, font.textures);
font.h=iSize;
for(unsigned char i=0;i<128;i++) make_dlist(face,i,font.list_base,font.textures);
FT_Done_Face(face);
m_mFontList[m_mFontList.size()] = font;
return m_mFontList.size()-1;
}
void CTextManager2D::DelFont(int iFontID) {
}
void CTextManager2D::RenderText(int iFontID, char* cText, float x, float y, SDL_Color color) {
map<int,font_data>::iterator result;
result = m_mFontList.find(iFontID);
if(result==m_mFontList.end())
return;
pushScreenCoordinateMatrix();
font_data* tmpFont = &result->second;
GLuint font=tmpFont->list_base;
float h=tmpFont->h/0.63f;
const char *start_line=cText;
vector<string> lines;
const char *c = cText;
for(;*c;c++) {
if(*c=='\n') {
string line;
for(const char *n=start_line;n<c;n++) line.append(1,*n);
lines.push_back(line);
start_line=c+1;
}
}
if(start_line) {
string line;// = start_line;
for(const char *n=start_line;n<c;n++) line.append(1,*n);
lines.push_back(line);
}
glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glListBase(font);
float modelview_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);
for(unsigned int i=0;i<lines.size();i++) {
glPushMatrix();
glLoadIdentity();
glTranslatef(x,y-h*i,0);
glMultMatrixf(modelview_matrix);
glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str());
glPopMatrix();
}
glPopAttrib();
pop_projection_matrix();
}
|
Kampfhund: code durch cpp-Tags ersetzt. _________________
"Die Codeschleuder" das Spieleprogrammierer Magazin |
|
Nach oben |
|
|
Deviloper Junior JLI'ler
Anmeldedatum: 31.05.2006 Beiträge: 77
Medaillen: Keine
|
Verfasst am: 25.01.2008, 14:42 Titel: |
|
|
* Kommentare hinzufügen
* Überlegen wo ein unsigned angebracht wäre
* Überlegen wo alles ein const vergessen wurde
* CPP: | if (a == false) return true;
return false; |
kann man reduzieren (bool'sches algebra)
* Exceptions angucken
* Referenzen angucken
* std::size_t != unsigned int
* ++a ist meist a++ vorzuziehen
Und so weiter. Räume bitte deine Klasse einmal auf und optimier die mal ein wenig! Kommentare erleichtern uns dann, dir deinen Fehler zu nennen. Hab keine Lust das durchn Compiler zu jagen und das ganze zu Debuggen. Das ist deine Aufgabe! |
|
Nach oben |
|
|
fkrauthan Junior JLI'ler
Alter: 33 Anmeldedatum: 10.04.2005 Beiträge: 96 Wohnort: Germering Medaillen: Keine
|
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 25.01.2008, 15:48 Titel: |
|
|
bei ++c wird c erst erhöht und dann zurückgegeben. Bei c++ wird c zurückgegeben und dann erhöht.
Wenn man Objekte hat, die einen ++ Operator haben, muss man bei c++ eine temporäre Kopie anlegen, das Original erhöhen und die Kopie zurückgeben. Bei ++c braucht man keine Kopie, da man das Original zurückgeben kann.
Also ist c++ langsamer als ++c. Obwohl das bei sowas einfachen wie int oder float wahrscheinlich wegoptimiert werden kann. Aber wo du kein C++ brauchst, kann man ruhig immer ++c benutzen, das wird wohl niemals schlechter sein.
(c++ bezieht sich hier niemals auf die verwendete Programmiersprache ) _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
fkrauthan Junior JLI'ler
Alter: 33 Anmeldedatum: 10.04.2005 Beiträge: 96 Wohnort: Germering Medaillen: Keine
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|