Here’s some code if anyone is interested in helping…
I have two apparently competing bits…here’s the texturemappedfont object, and it’s unmodified from the sample except to change the directory of the font files to the current directory.
#ifdef WIN32
#include <windows.h>
#endif
#include "texturemappedfont.h"
#include <GL/glu.h>
TextureMappedFont::TextureMappedFont(const string& textureName, int screenWidth, int screenHeight, float fontSize)
{
m_textureName = textureName;
m_shaderProgram = new GLSLProgram("font.vert", "font.frag");
m_screenWidth = screenWidth;
m_screenHeight = screenHeight;
m_fontSize = fontSize;
}
bool TextureMappedFont::initialize()
{
if (!m_texture.load(m_textureName)) {
std::cerr << "Couldn't load the font texture" << std::endl;
return false;
}
glBindTexture(GL_TEXTURE_2D, m_textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, m_texture.getWidth(),
m_texture.getHeight(), GL_RGB, GL_UNSIGNED_BYTE, m_texture.getImageData());
float vertices [] = {
0.0f, 0.0f,
m_fontSize, 0.0f,
m_fontSize, m_fontSize,
0.0f, m_fontSize
};
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, &vertices[0], GL_STATIC_DRAW);
//Just initialize with something for now, the tex coords are updated
//for each character printed
float texCoords [] = {
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 0.0f
};
glGenBuffers(1, &m_texCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, &texCoords[0], GL_DYNAMIC_DRAW);
if (!m_shaderProgram->initialize()) {
std::cerr << "The shader program could not be initialized" << std::endl;
return false;
}
m_shaderProgram->bindAttrib(0, "a_Vertex");
m_shaderProgram->bindAttrib(1, "a_TexCoord0");
m_shaderProgram->linkProgram();
m_shaderProgram->sendUniform("texture0", 0);
return true;
}
void TextureMappedFont::printString(const string& str, float x, float y)
{
static float modelviewMatrix[16];
static float projectionMatrix[16];
m_shaderProgram->bindShader();
setOrthoMode();
float texCoords[8];
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, m_textureID);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glTranslatef(x, y, 0.0); //Position our text
for(string::size_type i = 0; i < str.size(); ++i)
{
const float oneOverSixteen = 1.0f / 16.0f;
int ch = int(str[i]);
float xPos = float(ch % 16) * oneOverSixteen;
float yPos = float(ch / 16) * oneOverSixteen;
texCoords[0] = xPos;
texCoords[1] = 1.0f - yPos - oneOverSixteen;
texCoords[2] = xPos + oneOverSixteen;
texCoords[3] = 1.0f - yPos - oneOverSixteen;
texCoords[4] = xPos + oneOverSixteen;
texCoords[5] = 1.0f - yPos - 0.001f;
texCoords[6] = xPos;
texCoords[7] = 1.0f - yPos - 0.001f;
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 8, &texCoords[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer((GLint)0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
glVertexAttribPointer((GLint)1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glGetFloatv(GL_MODELVIEW_MATRIX, modelviewMatrix);
glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrix);
m_shaderProgram->sendUniform4x4("modelview_matrix", modelviewMatrix);
m_shaderProgram->sendUniform4x4("projection_matrix", projectionMatrix);
glDrawArrays(GL_QUADS, 0, 4);
glTranslatef(m_fontSize * 0.80f, 0, 0); //Move along a bit for the next character
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
unsetOrthoMode();
}
void TextureMappedFont::setOrthoMode()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, m_screenWidth, 0, m_screenHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void TextureMappedFont::unsetOrthoMode()
{
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
And here’s the pertinent calls in my code.
bool ReactionTime::init(int width, int height)
{
// Init OpenGL
if (!glGenBuffers || !glBindBuffer || !glBufferData || !glDrawRangeElements)
{
std::cerr << "VBOs are not supported by your graphics card" << std::endl;
return false;
}
screenWidth = width;
screenHeight = height;
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.3f, 1.0f);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
currentStage = RESET;
plotArrows(CROSS);
genBuffers();
updateProjection();
// If this code is present, I cannot debug, but my drawn elements do appear if the printstring call is commented out of render
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
m_font = new TextureMappedFont("font.tga", viewport[2], viewport[3], 25.0f);
if (!m_font->initialize()) {
std::cerr << "Could not initialize the font" << std::endl;
return false;
}
//Return success
return true;
}
void ReactionTime::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Load the identity matrix (reset to the default position and orientation)
glLoadIdentity();
updateProjection();
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLE_FAN, m_indices.size(), GL_UNSIGNED_INT, 0);
//the following line causes ONLY the text to be displayed, not my drawn elements, even if it's disabled via if statement...if this line is present, the drawelements above does nothing
m_font->printString("Simple Reaction Time Task", 0, 0);
}
void ReactionTime::genBuffers()
{
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glGenBuffers(MAX_BUFFERS, &m_vbos[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]); //Bind the vertex buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_vertices.size(), &m_vertices[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]); //Bind the index buffer
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), &m_indices[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_colors.size(), &m_colors[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
//Bind the color array, and set the color pointer to point at it
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]);
glColorPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
glVertexPointer(3, GL_FLOAT, 0, 0);
}
void ReactionTime::rebufferData()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]); //Bind the vertex buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_vertices.size(), &m_vertices[0], GL_DYNAMIC_DRAW); //Send the new data to OpenGL
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]); //Bind the index buffer
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), &m_indices[0], GL_DYNAMIC_DRAW); //Send the new data to OpenGL
glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOR_BUFFER]); //Bind the color buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_colors.size(), &m_colors[0], GL_DYNAMIC_DRAW); //Send the data to OpenGL
}
void ReactionTime::updateProjection()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float screenAspect, left, right, bottom, top;
screenAspect = (float) screenWidth / screenHeight;
left = 0;
right = 0;
bottom = -8;
top = 8;
left -= (screenAspect * 8);
right = (screenAspect * 8);
glOrtho(left, right, top, bottom, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
I left out the prepare routine and the plotarrows routine. prepare just decides which symbol gets drawn based on the task logic and calls plotarrows which sets up the vertices and the indices and the colors…
I can only display either text from the texturemappedfont object or my symbology from the GL_TRIANGLE_FAN…
Any help would be greatly appreciated it…I’m sure it’s just some mode that’s getting toggled or switches and clearing everything else when the text is shown, but I don’t know what.