Draw 2-Dimensional Image 32bit - opengl

I'm trying to draw a buffer of pixels to the screen. When I draw, black is drawn as transparent which is perfect. However, other colours are also drawn transparent. I cannot seem to figure out why.
I draw using:
glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
to draw a 32 bit bmp. However, the bitmap does not show unless I do convert it to 24 bit and use GL_BGR. Am I doing something wrong? Is there a reason black would be transparent?
Right before doing a draw, I do:
void Enable2DDrawing(bool &DrawingEnabled, bool &GLTexture2D, bool &GLRectangleTexture, bool &PointSmooth, float &PointSize)
{
if (!DrawingEnabled)
{
GLTexture2D = glIsEnabled(GL_TEXTURE_2D);
GLRectangleTexture = glIsEnabled(GL_TEXTURE_RECTANGLE);
PointSmooth = glIsEnabled(GL_POINT_SMOOTH);
glGetFloatv(GL_POINT_SIZE, &PointSize);
glDisable(GL_TEXTURE_RECTANGLE);
glDisable(GL_TEXTURE_2D);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glPushMatrix();
glLoadIdentity();
DrawingEnabled = true;
}
}
and right after drawing, I do:
void Disable2DDrawing(bool &DrawingEnabled, bool GLTexture2D, bool GLRectangleTexture, bool PointSmooth, float PointSize)
{
if (DrawingEnabled)
{
glPopMatrix();
if (GLTexture2D) glEnable(GL_TEXTURE_2D);
if (GLRectangleTexture) glEnable(GL_TEXTURE_RECTANGLE);
if (PointSmooth) glDisable(GL_POINT_SMOOTH);
DrawingEnabled = false;
}
}
Then I swap the buffer. I also tried drawing using textures by doing:
GLuint LoadTexture(void* Buffer, int width, int height, GLenum Target)
{
GLuint ID = 0;
glGenTextures(1, &ID);
glBindTexture(Target, ID);
glTexParameteri(Target, GL_TEXTURE_WRAP_S, Target == GL_TEXTURE_2D ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, Target == GL_TEXTURE_2D ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(Target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, Buffer);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
return ID;
}
void DrawTexture(std::uint32_t Target, std::uint32_t ID, float X1, float Y1, float X2, float Y2, int Width, int Height)
{
Width = Target == GL_TEXTURE_RECTANGLE ? Width : 1;
Height = Target == GL_TEXTURE_RECTANGLE ? Height : 1;
glEnable(Target);
glBindTexture(Target, ID);
glBegin(GL_QUADS);
glTexCoord2f(0, Height);
glVertex2f(X1, Y1); //top left
glTexCoord2f(0, 0); //bottom left
glVertex2f(X1, Y2);
glTexCoord2f(Width, 0);
glVertex2f(X2, Y2); //bottom right
glTexCoord2f(Width, Height);
glVertex2f(X2, Y1); //top right
glEnd();
glDisable(Target);
}
But it does not draw the bitmap correctly. It draws a 32-bit bmp like:
http://i.imgur.com/A4pE2Uw.png when it is supposed to be completely white. If I draw each pixel 1 by 1, it works fine. Am I missing something?
What is the best way to draw 32 bit bitmaps and do I have to use glPixelStorei? Does anyone have sample code for drawing a bitmap or a nice explanation on how?

Have you enabled blending?
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

Related

Render fonts with freetype

I made opengl rendering engine, and i can render shapes, 3d shapesand textures. Then i wanted to render fonts. I used freetype library to do this. But i have one serious problem with it. When i render font it looks terrible. First i will explain how i initialized freetype, and loaded font, then how i render textures, so you will be able to see itf there are any mistakes.
I initialize freetype and load font like this:
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Init_FreeType(&library);
FT_New_Face(library, "arial.ttf", 0, &face);
FT_Set_Char_Size(face, 0, 20 * 64, 300, 300);
slot = face->glyph;
FT_Load_Char(face, 'a', FT_LOAD_RENDER);
Then i load it into my texture:
this->tex.LoadFromBuffer(slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows);
The tex object is just texture container which looks like this:
class Texture
{
public:
void LoadFromBuffer(unsigned char* buf, int w, int h);
float sizex, sizey;
GLuint texName;
};
And load from buffer function looks like this:
void Texture::LoadFromBuffer(unsigned char* buf, int w, int h)
{
this->sizex = w;
this->sizey = h;
glGenTextures(1, &this->texName);
glBindTexture(GL_TEXTURE_2D, this->texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(buf);
}
Then texture is created and i render it just normaly with opengl on squad:
void Renderer::Render(Quad& quadv)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, quadv.texture->texName);
glBegin(GL_QUADS);
glColor3f(quadv.color.r, quadv.color.g, quadv.color.b);
glTexCoord2f(0.0, 0.0); glVertex2f(quadv.vertices[0].x, quadv.vertices[0].y);
glTexCoord2f(1.0, 0.0); glVertex2f(quadv.vertices[1].x, quadv.vertices[1].y);
glTexCoord2f(1.0, 1.0); glVertex2f(quadv.vertices[2].x, quadv.vertices[2].y);
glTexCoord2f(0.0, 1.0); glVertex2f(quadv.vertices[3].x, quadv.vertices[3].y);
glEnd();
glDisable(GL_TEXTURE_2D);
}
Quadv is object which contains vertices of quad, but its not important here.
Texture in quadv is the texture with letter a, that i loaded before.
Code looks just normal to me, but when i run it, the texture looks like this:
A letter is triple no matter what size texture is or size of quad.
And whole image is terrible.
I don't recall what is the default PixelMode when using FT.
But it looks to me like you are assuming that the bitmap provided by FT comes as a 32-bit RGBA color, which is probably not the case.
I'm gonna assume it comes as an 8-bit color. Try changing:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
to
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, buf);
We replaced GL_RGB which was the input format to GL_RED such that the tex image function expects 1 component per pixel. FT2 Documentation for further information
The bitmap contains 1 channel per pixel, encoded in a single byte. Since you're using legacy OpenGL, I recommend using the internal texture format GL_ALPHA. Therefore each element of the texture is treated as a single alpha component.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, buf);
Enable Blending to show only the opaque part of the glyphs:
void Renderer::Render(Quad& quadv)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, quadv.texture->texName);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
glColor3f(quadv.color.r, quadv.color.g, quadv.color.b);
glTexCoord2f(0.0, 0.0); glVertex2f(quadv.vertices[0].x, quadv.vertices[0].y);
glTexCoord2f(1.0, 0.0); glVertex2f(quadv.vertices[1].x, quadv.vertices[1].y);
glTexCoord2f(1.0, 1.0); glVertex2f(quadv.vertices[2].x, quadv.vertices[2].y);
glTexCoord2f(0.0, 1.0); glVertex2f(quadv.vertices[3].x, quadv.vertices[3].y);
glEnd();
glDisable(GL_TEXTURE_2D);
}

QOpenGLWidget Texture Mapping results in Black screen

I am trying to render a simple 2d Image with the QOpenGLWidget using a quad as a texture. But no matter what I am trying, I always get a black box.
I have read many tutorials, I have a simple pixelbuffer like this
uchar* m_pData;
which stores my RGB values. This is valid, since I have it tested with glDrawPixles(). I will post the three most important functions considering the OpenGLWidget.
initializeGL() first:
void QGLImageviewer::initializeGL()
{
initializeOpenGLFunctions();
// Clear the color
float r = ((float)m_backColor.darker().red())/255.0f;
float g = ((float)m_backColor.darker().green())/255.0f;
float b = ((float)m_backColor.darker().blue())/255.0f;
glClearColor(r,g,b,1.0f);
// Set shading model.
glShadeModel(GL_SMOOTH);
// Set the viewport
glViewport(0.f, 0.f, m_origW, m_origH);
// Init. Projection Matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, m_origW, m_origH,0.0,1.0,-1.0);
// Init Modelview Matrix
glClearColor(0.f, 0.f, 0.f, 1.f);
// Enable texturing
glEnable(GL_TEXTURE_2D);
// Generate texture ID
glGenTextures(1, &m_textureID);
// Bind texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Generate Texture, and assign pixles to our texture ID
if (m_pData != nullptr)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW, m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)m_pData);
}
else
{
qCritical("Buffer is empty!!");
}
// Unbind texture
glBindTexture(GL_TEXTURE_2D, NULL);
// Check for Error
GLenum error_ = glGetError();
if (error_ != GL_NO_ERROR)
{
qCritical("Error Loading Texture!");
}
}
Then paintGL():
void QGLImageviewer::paintGL()
{
makeCurrent();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Clear Screen And Depth Buffer
glClear(GL_COLOR_BUFFER_BIT);
if (!(m_renderQtImg->isNull()))
{
//QImage image;
int imWidth = m_renderQtImg->width();
int imHeight = m_renderQtImg->height();
// The image has to be resized to fit the widget
if (imWidth != this->size().width() &&
imHeight != this->size().height())
{
imWidth = this->size().width();
imHeight = this->size().height();
}
else
{
//image = *m_renderQtImg;
imWidth = m_origW;
imHeight = m_origH;
}
if (m_textureID != 0)
{
glMatrixMode(GL_MODELVIEW);
// Remove any previous transformations
glLoadIdentity();
glPushMatrix();
// Move to rendering point
glTranslatef(0.f, 0.f, 0.f);
glColor3f(0.0f, 0.0f, 0.5f);
// Set texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(imWidth, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(imWidth, imHeight);
glTexCoord2f(0.f, 1.f); glVertex2f(0.f, imHeight);
glEnd();
//glDisable(GL_TEXTURE_2D);
glPopMatrix();
glFlush();
}
}
}
And last but not least resizeGL():
void QGLImageviewer::resizeGL(int width, int height)
{
makeCurrent();
glViewport(0,0,(GLint)width,(GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(0.0, width, 0.0, height);
glOrtho(0.0, width, 0.0, height, 0.0, 1.0);
}
I am using Qt5.6 and the Microsoft Visual Studio 2015 compiler.
Damn, the problem was on
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData);
My member variables m_orgiW and m_orgiH were initialized to 0. So quite unsurprising that my code did not work.
For the record I will post my running code, the three most important functions of the QOpenGLWidget, hope that it will be useful to somebody with the same issue.
void QGLImageviewer::initializeGL()
{
initializeOpenGLFunctions();
float r = ((float)m_backColor.darker().red())/255.0f;
float g = ((float)m_backColor.darker().green())/255.0f;
float b = ((float)m_backColor.darker().blue())/255.0f;
glClearColor(r,g,b,1.0f);
// Generate texture ID
glGenTextures(1, &m_textureID);
// Bind texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
if (m_pData != nullptr)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData);
}
else
{
qCritical("Buffer is empty!!");
}
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //IMPORTANT FOR NON POWER OF 2 TEXTURES
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Enable texturing Mapping
glEnable(GL_TEXTURE_2D);
// Enable Smooth Shading
glShadeModel(GL_SMOOTH);
// Black Background
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// Depth Buffer Setup
glClearDepth(1.0f);
// Enables Depth Testing
glEnable(GL_DEPTH_TEST);
// Type of depth testing to do
glDepthFunc(GL_LEQUAL);
// Really Nice Perspective Calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Unbind Texture
glBindTexture(GL_TEXTURE_2D, NULL);
}
Now paintGL()
void QGLImageviewer::paintGL()
{
makeCurrent();
// Clear Screen And Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureID);
glBegin(GL_QUADS);
// Drawing the quad with the texture mapped on it
//
// OpenGL 2D Coordinates
// Sticking with the Coordinate Convention mentioned here
glTexCoord2f(1.0f, 0.0f); glVertex2f(m_width, 0.0f); // vertex 1
glTexCoord2f(1.0f, 1.0f); glVertex2f(m_width, m_height); // vertex 2
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, m_height); // vertex 3
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // vertex 4
glEnd();
}
And resizeGL()
void QGLImageviewer::resizeGL(int width, int height)
{
makeCurrent();
m_width = width;
m_height = height;
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping area to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset the projection matrix
glOrtho(0, m_width/ m_zoomFactor, m_height/ m_zoomFactor,0, -1, 1);
}

Texture isn't mapped to quad

I'm using the following to draw text in OpenGL (using SDL)
void renderText(const TTF_Font *font, const SDL_Color color,
const double& x, const double& y, const double& z, const std::string& text) {
bool textured = glIsEnabled(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D);
//test color: black
glColor3f(0,0,0);
SDL_Surface *Message = TTF_RenderText_Blended(const_cast<TTF_Font*>(font), text.c_str(), color);
GLuint Texture = 0;
//Generate an OpenGL 2D texture from the SDL_Surface
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Message->w, Message->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, Message->pixels);
//Draw this texture on a quad with the given xyz coordinates.
glBegin(GL_QUADS);
glTexCoord2d(0, 0); glVertex3d(x, y, z);
glTexCoord2d(1, 0); glVertex3d(x+Message->w, y, z);
glTexCoord2d(1, 1); glVertex3d(x+Message->w, y+Message->h, z);
glTexCoord2d(0, 1); glVertex3d(x, y+Message->h, z);
glEnd();
//Clean up
glDeleteTextures(1, &Texture);
SDL_FreeSurface(Message);
if (!textured)
glDisable(GL_TEXTURE_2D);
}
However, the only thing shown is a rectangle at (x,y) (in this case (10,10)) with the background color set with glColor3f (black in this case). The texture created from the SDL_Surface isn't shown on the quad. The arguments passed to the function are all valid:
font: previously loaded TTF_Font != NULL
color: SDL_Color {255,255,255} (white)
x = 10
y = 10
z = 0
text = "test"
What's wrong here?
glOrtho(0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, -1.0, 10.0);
OpenGL v2.2
SDL v1.2.15
Kubuntu Raring x64
Update: When using ..._Solid instead of ..._Blended, calling glColor3f(1,1,1) and passing SDL_Color {255,255,255} results in some strange stuff:
The quad appears where it should appear, and it shows strange content. What's wrong?
THe problem was that I didn't call glBlendFunc before calling above method. So OpenGL had a wrong blending mode set. After using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);it looks fine.

How to draw transparent rubberband on OpenGL scene

i'm using OpenGL for showing grabbed frames from video camera with texture mapping. There is no problem at all but i have to select some region of the grabbed frame then i have to zoom it, first of all i can't draw a Rubber rectangle it must be transparent when i select the some region of grabbed frame i have to see textured frame transparently could you gimme some piece of code or clue, btw i'm showing grabbed frames like that any suggestion will be good for me...
void GLWidget::initializeGL()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &m_pTextureId);
glBindTexture(GL_TEXTURE_2D, m_pTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void GLWidget::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::setTextureData(BYTE *data, int width, int height)
{
makeCurrent();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (m_isTextured)
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_BGRA_EXT,GL_UNSIGNED_BYTE,data);
else
glTexImage2D(GL_TEXTURE_2D,0,3,width,height,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,0);
glBindTexture(GL_TEXTURE_2D,m_pTextureId);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);glVertex2f(-1.0,-1.0);
glTexCoord2f(0.0,1.0);glVertex2f(-1.0,1.0);
glTexCoord2f(1.0,1.0);glVertex2f(1.0,1.0);
glTexCoord2f(1.0,0.0);glVertex2f(1.0,-1.0);
glEnd();
swapBuffers();
}
I'm passing captured frame data to setTextureData it's working but i dunno does it good way ...
Thanks for reply #genpfault,
i used x1=0, y1=0, x2=1, y2=1 but it's drawing rectangle to all texture area. and draws 1 more rectangle to coordinates x1,y1... . How can i fix it. Btw how can i remove that rectangle ?, There is one more issue if i draw a rectangle then texture again rectangle going invisible ...
Just draw a translucent (alpha < 1.0) rectangle:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(255, 255, 255, 128);
glRectf(x1, y1, x2, y2);
glDisable(GL_BLEND);

Using SDL_ttf with OpenGL

I'm using OpenGL and SDL to create a window in my program.
How do I use SDL_ttf with an OpenGL window?
For example I want to load a font and render some text. I want to draw the text using an SDL OpenGL surface.
Here's how to do it:
Initialize SDL and SDL_ttf, and create a window using SDL_SetVideoMode(). Make sure you pass the SDL_OPENGL flag.
Initialize your OpenGL scene (glViewport(), glMatrixMode() etc.).
Render your text with SDL_ttf using e.g. TTF_RenderUTF8_Blended(). The render functions return an SDL_surface, which you have to convert into an OpenGL texture by passing a pointer to the data (surface->pixels) to OpenGL as well as the format of the data. Like this:
colors = surface->format->BytesPerPixel;
if (colors == 4) { // alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
} else { // no alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels);
Then you can use the texture in OpenGL using glBindTexture() etc. Make sure to call SDL_GL_SwapBuffers() when you're done with drawing.
Based off of: http://content.gpwiki.org/index.php/SDL_ttf:Tutorials:Fonts_in_OpenGL
The code below is an example of how you can render the text on top of finished 3D model you may have built.
#include "SDL.h"
#include "SDL_ttf.h"
/.../
void RenderText(std::string message, SDL_Color color, int x, int y, int size) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, m_Width, 0, m_Height); // m_Width and m_Height is the resolution of window
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
TTF_Font * font = TTF_OpenFont("pathToFont.ttf", size);
SDL_Surface * sFont = TTF_RenderText_Blended(font, message, color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sFont->w, sFont->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, sFont->pixels);
glBegin(GL_QUADS);
{
glTexCoord2f(0,0); glVertex2f(x, y);
glTexCoord2f(1,0); glVertex2f(x + sFont->w, y);
glTexCoord2f(1,1); glVertex2f(x + sFont->w, y + sFont->h);
glTexCoord2f(0,1); glVertex2f(x, y + sFont->h);
}
glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glDeleteTextures(1, &texture);
TTF_CloseFont(font);
SDL_FreeSurface(sFont);
}
/.../
int main() {
/.../ Render 3D stuff here
// Prints out "Hello World" at location (5,10) at font size 12!
SDL_Color color = {255, 0, 0, 0}; // Red
RenderText("Hello World", color, 5, 10, 12);
/.../
return 0;
}