Hello!
I read in the tutorial SFML has many useful funcitons, to handle Fonts. I want to use SFML 2.1's Font feature to display font in 3D space on an opengl GL_QUADS.
I read many topic, but somehow I just couldn't find exactly the same issue.
So, I get to this point, I want to display only one character now.
#include <math.h>
#include <stdlib.h>
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif
#include <iostream>
#include <SFML\Graphics\Font.hpp>
#define PI 3.1415926535
//--------------------------------------------------------
// 3D Vektor
//--------------------------------------------------------
struct Vector
{
float x, y, z;
Vector( )
{
x = y = z = 0;
}
Vector(float x0, float y0, float z0 = 0)
{
x = x0;
y = y0;
z = z0;
}
Vector operator*(float a)
{
return Vector(x * a, y * a, z * a);
}
Vector operator*(double a)
{
return Vector(x * a, y * a, z * a);
}
Vector operator*(int a)
{
return Vector(x * a, y * a, z * a);
}
Vector operator+(const Vector& v)
{
return Vector(x + v.x, y + v.y, z + v.z);
}
Vector operator-(const Vector& v)
{
return Vector(x - v.x, y - v.y, z - v.z);
}
float operator*(const Vector& v) // dot product
{
return (x * v.x + y * v.y + z * v.z);
}
Vector operator%(const Vector& v) // cross product
{
return Vector(y*v.z-z*v.y, z*v.x - x*v.z, x*v.y - y*v.x);
}
float Length()
{
return sqrt(x * x + y * y + z * z);
}
void Norm() // Normalizált
{
float l= Length();
x/=l;
y/=l;
z/=l;
}
};
const int screenWidth = 600; // alkalmazás ablak felbontása
const int screenHeight = 600;
class String3D;
class Scene
{
public:
String3D *Szoveg3D;
String3D *Szoveg3D1;
void render();
};
Scene scene;
class Camera
{
public:
Vector position;
Vector center;
Vector lookUp;
Camera( Vector p = *new Vector(3, 8, -14),//Vector p = *new Vector(0, 6, -15),
Vector c = *new Vector(-5, 0, 15),
Vector l = *new Vector(0, 5, 0))
: position(p), center(c), lookUp(l) { }
};
Camera camera;
sf::Font Global_Font;
GLuint TilesID;
class String3D {
public:
//string szoveg;
sf::Font& fontom;
GLuint FontTextureID;
Vector k;
String3D(sf::Font& Fontocska, Vector K): fontom(Fontocska),k(K) {}
void render()
{
glEnable(GL_TEXTURE_2D);
//glPushMatrix();
//glBindTexture(GL_TEXTURE_2D, FontTextureID);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
sf::Glyph glif = fontom.getGlyph(108,12,false);
//int lineHeight = fontom.getLineSpacing(12);
sf::IntRect negyszog = glif.bounds;
Vector x(negyszog.width,0,0);
//x= x*1;
Vector y(0,negyszog.height,0);
//y= y*1;
Vector n(0,-3,-5);//=(camera.center-camera.position)*-1;
//Vector x=negyszog;
GLfloat diffuuz[] = { 1, 1, 1, 1 };
GLfloat spekularis[] = { 1, 1, 1, 1 };
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuuz);
glMaterialfv(GL_FRONT, GL_SPECULAR, spekularis);
glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
glBegin(GL_QUADS);
glNormal3f(n.x,n.y,n.z);
glTexCoord2d(1,1);
glVertex3f(k.x ,k.y ,k.z);
glNormal3f(n.x,n.y,n.z);
glTexCoord2d(0,1);
glVertex3f(k.x+x.x ,k.y+x.y ,k.z+x.z);
glNormal3f(n.x,n.y,n.z);
glTexCoord2d(0,0);
glVertex3f(k.x+x.x+y.x ,k.y+x.y+y.y ,k.z+x.z+y.z);
glNormal3f(n.x,n.y,n.z);
glTexCoord2d(1,0);
glVertex3f(k.x+y.x ,k.y+y.y ,k.z+y.z);
glEnd();
//glDisable(GL_TEXTURE_2D);
//glPopMatrix();
}
};
void Scene::render(){
if(Szoveg3D)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TilesID);
Szoveg3D->render();
glDisable(GL_TEXTURE_2D);
}
if(Szoveg3D1){
glEnable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, Szoveg3D1->fontom.getTexture(12).m_texture);
sf::Texture::bind(&(Szoveg3D1->fontom.getTexture(12)));
Szoveg3D1->render();
glDisable(GL_TEXTURE_2D);
}
}
//const sf::Texture* fontpixelek;
const int TilesWidth=4 , TilesHeight=4;
unsigned char padlokep[TilesWidth * TilesHeight][3] =
{
{110,90,90},{200,200,000},{200,200,000},{110,90,90},
{200,200,000},{140,80, 20},{140,80, 20},{200,200,000},
{200,200,000},{140,80, 20},{140,80, 20},{200,200,000},
{110,90,90},{200,200,000},{200,200,000},{110,90,90}
};
void onInitialization( )
{
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, screenWidth, screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(100,screenWidth/screenHeight,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glShadeModel( GL_SMOOTH );
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat lightColor[] = {1, 1, 1, 1.0};
GLfloat light_position[] = { 5, 10, -10, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
gluLookAt(camera.position.x, camera.position.y, camera.position.z,
camera.center.x, camera.center.y, camera.center.z,
camera.lookUp.x, camera.lookUp.y, camera.lookUp.z);
if (!Global_Font.loadFromFile("arial.ttf"))
{
std::cout<<"Nem sikerült kiolvasni a Font-ot!!!";
}
//fontpixelek=&(&Global_Font)->getTexture(12);
//sf::Texture::bind(&(&Global_Font)->getTexture(12));
if(&Global_Font) {
glEnable(GL_TEXTURE_2D);
scene.Szoveg3D = new String3D( Global_Font,*new Vector(-5,2,-3));
scene.Szoveg3D1 = new String3D( Global_Font,*new Vector(5,2,-3));
/*sf::Image image =fontpixelek.copyToImage();
glGenTextures(1, &(scene.Szoveg3D->FontTextureID));
glBindTexture(GL_TEXTURE_2D, scene.Szoveg3D->FontTextureID);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);*/
}
//glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &TilesID);
glBindTexture(GL_TEXTURE_2D, TilesID);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TilesWidth, TilesHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, padlokep);
//glDisable(GL_TEXTURE_2D);
}
void onDisplay( )
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camera.position.x, camera.position.y, camera.position.z,
camera.center.x , camera.center.y , camera.center.z ,
camera.lookUp.x , camera.lookUp.y , camera.lookUp.z );
GLfloat light_position[] = { 5, 11, -10, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
scene.render();
glutSwapBuffers();
}
float szog = 1.83*PI;
Vector d ( camera.center.x - camera.position.x,0,camera.center.z - camera.position.z);
void onKeyboard(unsigned char key, int x, int y)
{
if (key == 'i') {
Vector elore=camera.center-camera.position;
elore.y=0;
elore= elore*0.03;
camera.position = camera.position + elore;
camera.center = camera.center + elore;
glutPostRedisplay( );
}
if (key == 'k') {
Vector elore=camera.center-camera.position;
elore.y=0;
elore= elore*0.03;
camera.position = camera.position - elore;
camera.center = camera.center - elore;
glutPostRedisplay( );
}
if (key == 'j') {
szog += PI/20;
if (szog > 2*PI)
szog = 0;
camera.center.x = camera.position.x + d.Length()*sin(szog);
camera.center.z = camera.position.z + d.Length()*cos(szog);
glutPostRedisplay( );
}
if (key == 'l') {
szog -= PI/20;
if (szog < 0)
szog = 2*PI;
camera.center.x = camera.position.x + d.Length()*sin(szog);
camera.center.z = camera.position.z + d.Length()*cos(szog);
glutPostRedisplay( );
}
}
void onMouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT && state == GLUT_DOWN)
glutPostRedisplay( );
}
void onIdle( )
{
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv); // GLUT inicializalasa
glutInitWindowSize(screenWidth, screenHeight); // Alkalmazas ablak kezdeti merete 600x600 pixel
glutInitWindowPosition(20, 20); // Az elozo alkalmazas ablakhoz kepest hol tunik fel
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); // 8 bites R,G,B,A + dupla buffer + melyseg buffer
glutCreateWindow("String Textura"); // Alkalmazas ablak megszuletik es megjelenik a kepernyon
glMatrixMode(GL_MODELVIEW); // A MODELVIEW transzformaciot egysegmatrixra inicializaljuk
glLoadIdentity();
glMatrixMode(GL_PROJECTION); // A PROJECTION transzformaciot egysegmatrixra inicializaljuk
glLoadIdentity();
onInitialization(); // Az altalad irt inicializalast lefuttatjuk
glutDisplayFunc(onDisplay); // Esemenykezelok regisztralasa
glutMouseFunc(onMouse);
glutIdleFunc(onIdle);
glutKeyboardFunc(onKeyboard);
glutMainLoop(); // Esemenykezelo hurok
return 0;
}
Now I see one QUAD with the right texture, that I created and binded in Opengl and a white(blank) QUAD(that I tried to creat throught SFML). But somehow I can't make it works with SFML. :S
I appreciate any help!
Marci