I want to display text on game screen on specific co-ordinate position in OpenGL.
For example a players score "Player Score:" 10 at coordinates (5,5).
How do I do that?
Use a tool called GLFont under ortho view you can output text like
glFontBegin(&font);
glScalef(8.0, 8.0, 8.0);
glTranslatef(30, 30, 0);
glFontTextOut("Test", 5, 5, 0);
glFontEnd();
glFlush();
you can find it here http://students.cs.byu.edu/~bfish/glfontdl.php
i remember there is function under opengl that can put text on screen too.
Check this:
http://www.opengl.org/resources/features/fontsurvey/
EDIT: check this link out too http://mycodelog.com/2010/03/23/printw/
Usage is as simple as calling printf:
printf( "char: %c, decimal: %d, float: %f, string: %s", 'X', 1618, 1.618, "text");
printw(x, y, z, "char: %c, decimal: %d, float: %f, string: %s", 'X', 1618, 1.618, "text");
Related
I call a custom function like this to put a string on the screen:
// Debug: draw a blue line
glColor3f((GLfloat)0, (GLfloat)0, (GLfloat)1);
glBegin(GL_LINES);
glVertex2i(1, 1);
glVertex2i(1, 10);
glEnd();
// Call text renderer.
write_default_bitmap_text((const unsigned char*)"TEST string 1", 100, 100);
write_default_bitmap_text((const unsigned char*)"TEST string 2", 100, 120);
and this is the custom function:
void write_default_bitmap_text(const unsigned char* text,
const int x,
const int y,
const font_x_align x_align)
{
if (x_align == font_x_align::Left) {
glRasterPos2i(x, y);
}
else if (x_align == font_x_align::Center) {
glRasterPos2i(x - glutBitmapLength(default_font, text)/2, y);
}
else {
glRasterPos2i(x - glutBitmapLength(default_font, text), y);
}
glColor3f((GLfloat)1, (GLfloat)0, (GLfloat)0); //XXX debug
glDisable(GL_TEXTURE_2D); //XXX debug
glDisable(GL_LIGHTING); //XXX debug
glutBitmapString(default_font, text);
next_call_font_color = default_font_color;
}
where I hardcoded the text color to be red for debugging. To my surprise I see that the first string uses the blue color for the line just before calling write_default_bitmap_text(), but not red, and only the second string becomes red as intended.
If I place the few lines above for drawing the blue line inside my write_default_bitmap_text() body, then the text does not use the blue color but whatever was used for line drawing before calling write_default_bitmap_text() for the first time.
I have absolutely no idea what happens here.
glRasterPos*() "locks in" the current color/texure-coordinate state (much like glVertex*() does) while setting the raster position, so calling glColor*() after it will only affect the next glRasterPos*() call.
I want to create a string that will be printed on the screen. I will update this string every time values of the variables printed will change. The number of digits in each number can be different and sign of each number may change with time. What I want to be constant is numbers precision. The output I expect is sth like this (each line correspond to the same string, only updated):
X: 453.432 Y: 543.432
X: -5.432 Y: 4.432
X: 43.234 Y: -123.423
Namely, the letters and the dot should always stay in the same place on the screen.
At the moment I use this code for string updates but position of the Y and dots vary if number of digits change. Is there a simple way to implement it?
text = QString("X: %1 Y: %2").arg( QString::number( x(), 'f', 3 ),
QString::number( y(), 'f', 3 ) );
------------------ EDIT ------------------
Following the answer I created a string with constant spacing (constant length actually). It didn't solve my problem fully though.
In the next step I take the string text and using QPainter I paint it onto QImage object. The problem that I encounter here is that though the string length is always the same the width of numbers is different than the width of spaces (' ') and '-' sign painted by QPainter. So when the number of digits changes the positions of dots and 'Y' symbol changes as well.
Here is the code that I use for image creation:
QImage img( 100, 100, QImage::Format_ARGB32_Premultiplied );
img.fill( Qt::transparent );
QPainter painter( &img );
QPen pen;
pen.setColor( Qt::darkBlue );
painter.setPen(pen);
QFont font = painter.font();
font.setBold( true );
font.setPointSize( 10 );
painter.setFont( font );
QString text = QString("X:%1 Y:%2")
.arg( x(), 9, 'f', 3, ' ' )
.arg( y(), 9, 'f', 3, ' ' );
painter.drawText( QPointF(0, 50), text );
painter.end();
You can use this signature of the arg method:
// arg(double a, int fieldWidth, char format, int precision, QChar fillChar)
QString formated = QString("X:%1 Y:%2")
.arg(x(), 9, 'f', 3, ' ')
.arg(y(), 9, 'f', 3, ' ');
For your second problem, I solve it by changing the font family.
font.setFamily("Courier");
These are my results:
Default font:
Courier font:
If I draw a String onto a Graphics (from a mutable image) in a specific position why does the String position moves (on the Y Axis) depending on the simulator skin that is used ?
public void paints(Graphics g, Image background, Image watermark, int width, int height) {
g.drawImage(background, 0, 0);
g.drawImage(watermark, 0, 0);
g.setColor(0xFF0000);
// Upper left corner
g.fillRect(0, 0, 10, 10);
// Lower right corner
g.setColor(0x00FF00);
g.fillRect(width - 10, height - 10, 10, 10);
g.setColor(0xFF0000);
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(220, Font.STYLE_BOLD);
g.setFont(f);
// Draw a string right below the M from Mercedes on the car windscreen (measured in Gimp)
g.drawString("HelloWorld",
(int) (848 ),
(int) (610)
);
}
This is the way I save a screenshot programatically with CodenameOne :
Image screenshot = Image.createImage(photoBase.getWidth(), photoBase.getHeight());
f.revalidate();
f.setVisible(true);
drawing.paintComponent(screenshot.getGraphics(), true);
String imageFile = FileSystemStorage.getInstance().getAppHomePath() + "screenshot.png";
try(OutputStream os = FileSystemStorage.getInstance().openOutputStream(imageFile)) {
ImageIO.getImageIO().save(screenshot, os, ImageIO.FORMAT_PNG, 1);
} catch(IOException err) {
err.printStackTrace();
}
And here is the result with the iPhone 6 skin :
And with the Xoom skin :
Thanks a lot to anyone that could give me hints on how to solve this problem and start the String always at the position nevermind the skin (and device) used !
Regards,
Is the "drawing" component on the screen?
If so it will be sized differently based on the specific device you are running on as each device has different densities/resolutions. So elements from the screen will appear in different positions which is what we want normally.
I am drawing text in an OpenGL context under Windows, with the following helper function, I got ir from http://nehe.gamedev.net/tutorial/bitmap_fonts/17002/ :
GLvoid glPrint(HDC hDC, const char *fmt, ...) //Custom GL "Print" Routine
{
char text[256]; // Holds Our String
va_list ap; // Pointer To List Of Arguments
if (fmt == nullptr) // If There's No Text
return; // Do Nothing
va_start(ap, fmt); // Parses The String For Variables
vsprintf_s(text, fmt, ap); // And Converts Symbols To Actual Numbers
va_end(ap); // Results Are Stored In Text
glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits
glListBase(base - 32); // Sets The Base Character to 32
glCallLists((GLsizei)strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text
glPopAttrib(); // Pops The Display List Bits
}
I position the text by calling
glTranslatef(x, y, z);
glRasterPos2f(0.f, 0.f);
before glPrint, where x, yand zis the point coordinates where I would like to center my text.
This draws my text starting on the bottom-left corner. How can I center this text on its own centroid?
I tried GetTextExtentPoint32 to position my text, as follows
SIZE extent;
GetTextExtentPoint32(hDC, SpinTools::string2wstring(text).c_str(), strlen(text), &extent);
glRasterPos2f(-extent.cx / 2, -extent.cy / 2);
but this is not correct.
I think you idea with GetTextExtentPoint32 was right. But this futnction returns value in screen space, you need to convert it to [-1..1] sapce. You can try this code: glRasterPos2f((float)-extent.cx / (g_width), (float)-extent.cy / (g_height)); g_height and g_width are size of window
self.background = [CCSprite spriteWithFile:#"LetterBrick.png"];
CCLOG(#"background contentSize: (w: %d, h: %d)", self.background.contentSize.width, self.background.contentSize.height);
CCLOG(#"background boundingBox: (x: %d, y: %d, w: %d, h: %d)", self.background.boundingBox.origin.x, self.background.boundingBox.origin.y, self.background.boundingBox.size.width, self.background.boundingBox.size.height);
/**
OUTPUT:
background contentSize: (w: 0, h: 1078984704)
background boundingBox: (x: 0, y: -1069547520, w: 0, h: -1069547520)
*/
So basicly I'm just creating a CCSprite from a file, and printing out the contentsize and the boundingbox. But those values seems a little odd.
Can you help me please? :)
Use floats instead of integer when printing them out