Reputation: 1092
In OpenGL I'd like to use some charcter literals like "\t" or "\n". However, they are completely igonre when displaying the text. How should I do it?
char buffer[100];
sprintf(buffer, "First float is: %f.\n\tThe second one is: %f", 2.225,3.141592);
glCallLists(strlen(buffer), GL_UNSIGNED_BYTE, buffer);
// This will display all the text on the same line and ignoring the "\t"
Example (I'm working in a big project. I tried to copy below the basic structure of the opengl drawing routines):
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
int centreX = 100;
int centreY = 200;
GLvoid Print(const char *fmt)
{
char text[256];
if (fmt == NULL)
return;
sprintf(buffer,fmt);
glListBase(256);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
}
void DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0f,1.0f,0.5f);
glRasterPos2i((GLint)centreX, (GLint)centreY);
Print("First float is: %f.\n\tThe second one is: %f", 2.225,3.141592);
}
void main()
{
while (true)
{
DrawScene();
}
}
Upvotes: 0
Views: 382
Reputation: 8587
datenwolf is 100% right. Character literals like '\t' or '\n' have not been implemented by the OpenGL/GLUT developers.
Fonts in OpenGL/GLUT tend to be of bitmap type, usually 8x8 to 16x16 pixels in dimension and are drawn to the screen using x and y coordinates like any other bitmap.
Instead you will have to calculate x y positions to simulate '\t' or '\n' by yourself in your code.
Useful link http://www.codersource.net/2011/01/27/displaying-text-opengl-tutorial-5/
GLUT bitmap & stroke font Demo code:
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <GL/glut.h>
void bitmap_output(int x, int y, char *string, void *font){
int len, i;
glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}
void stroke_output(GLfloat x, GLfloat y, char *format,...){
va_list args;
char buffer[200], *p;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glPushMatrix();
glTranslatef(x, y, 0);
glScalef(0.005, 0.005, 0.005);
for (p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopMatrix();
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT);
bitmap_output(40, 35, "This is written in a GLUT bitmap font.",
GLUT_BITMAP_TIMES_ROMAN_24);
bitmap_output(30, 210, "More bitmap text is a fixed 9 by 15 font.",
GLUT_BITMAP_9_BY_15);
bitmap_output(70, 240, " Helvetica is yet another bitmap font.",
GLUT_BITMAP_HELVETICA_18);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(40.0, 1.0, 0.1, 20.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
gluLookAt(0.0, 0.0, 4.0, /* eye is at (0,0,30) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in postivie Y direction */
glPushMatrix();
glTranslatef(0, 0, -4);
glRotatef(50, 0, 1, 0);
stroke_output(-2.5, 1.1, " This is written in a");
stroke_output(-2.5, 0, " GLUT stroke font.");
stroke_output(-2.5, -1.1, "using 3D perspective.");
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
}
void reshape(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -h, 0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(465, 250);
glutCreateWindow("GLUT bitmap & stroke font example");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0, 0, 0);
glLineWidth(3.0);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
A starwars scroller to demo fonts:
// *********************************************************************
// * o p e n g l / G L U T s t a r w a r s s c r o l l e r *
// *********************************************************************
#include <windows.h>
#include <string.h>
#include <GL\glut.h>
#include <iostream.h>
#define MAX_LINES_OF_STARWARS_QUOTES 32
#define MAX_CHARACTERS_IN_A_LINE 80
GLfloat UpwardsScrollVelocity = -10.0;
float view=20.0;
char starWarsQuotes[MAX_LINES_OF_STARWARS_QUOTES][MAX_CHARACTERS_IN_A_LINE]; // up to 32 lines of quotes 80 characters wide
int numberOfstarWarsQuotes=0,i,ic=0;
//*********************************************
//* glutIdleFunc(timeTick); *
//*********************************************
void timeTick(void){
if (UpwardsScrollVelocity< -600) view-=0.000011;
if(view < 0) {view=20; UpwardsScrollVelocity = -10.0;}
UpwardsScrollVelocity -= 0.015;
glutPostRedisplay();
}
//*********************************************
//* RenderToDisplay() *
//*********************************************
void RenderToDisplay(){
int l,lenghOfstarWarsQuotes, i;
glTranslatef(0.0, -100, UpwardsScrollVelocity);
glRotatef(-20, 1.0, 0.0, 0.0);
glScalef(0.1, 0.1, 0.1);
for( l=0;l<numberOfstarWarsQuotes;l++){
lenghOfstarWarsQuotes = (int)strlen(starWarsQuotes[l]);
glPushMatrix();
glTranslatef(-(lenghOfstarWarsQuotes*37), -(l*200), 0.0);
for (i = 0; i < lenghOfstarWarsQuotes; i++) {
glColor3f((UpwardsScrollVelocity/10)+300+(l*10),(UpwardsScrollVelocity/10)+300+(l*10),0.0);
glutStrokeCharacter(GLUT_STROKE_ROMAN, starWarsQuotes[l][i]);
}
glPopMatrix();
}
}
//*********************************************
//* glutDisplayFunc(myDisplayFunction); *
//*********************************************
void myDisplayFunction(void){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 30.0, 100.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
RenderToDisplay();
glutSwapBuffers();
}
//*********************************************
//* glutReshapeFunc(reshape); *
//*********************************************
void reshape(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1.0, 1.0, 3200);
glMatrixMode(GL_MODELVIEW);
}
//*********************************************
//* int main() *
//*********************************************
int main(){
strcpy(starWarsQuotes[0],"S t a r w a r s q u o t e s ");
strcpy(starWarsQuotes[1],"Character literals test : \t \n \r \0 ......");
strcpy(starWarsQuotes[2],"I’m Luke Skywalker, I’m here to rescue you.");
strcpy(starWarsQuotes[3],"Luke, I am your father!");
strcpy(starWarsQuotes[4],"Obi-Wan has taught you well");
strcpy(starWarsQuotes[5],"The force is strong with this one");
strcpy(starWarsQuotes[6],"I find your lack of faith disturbing");
strcpy(starWarsQuotes[7],"Great, kid. Don’t get cocky");
numberOfstarWarsQuotes=8;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 400);
glutCreateWindow("StarWars scroller");
glClearColor(0.0, 0.0, 0.0, 1.0);
glLineWidth(3);
glutDisplayFunc(myDisplayFunction);
glutReshapeFunc(reshape);
glutIdleFunc(timeTick);
glutMainLoop();
return 0;
}
Upvotes: 3
Reputation: 162309
First and foremost: OpenGL does not know what "text" is!
The Method you're using relies on Display Lists. For each character code a display list is created. These lists consist of the commands that draw a single letter and apply a transformation to the next letter position. Control characters like newline, tab and so on however depend on the position of the screen, i.e. the drawing state that comes before and after. But at the time the display lists are compiled it is not known what you're going to do with them.
What you want is a proper text layout engine (like Pango) that knows how to position text. Also you don't want to use Display Lists (they've been outdated for well over 15 years) and to draw text glyphs want to use something like freetype-gl.
Upvotes: 4