This is a question for OpenGL ES on the iPhone, but the functionality should all be the same in the end - pretty much I am drawing a dialog box, and having each letter rendered individually every frame is way way too expensive. I want to draw all the letters into a framebuffer, have that generate a texture once, and then only draw that generated texture.
I’ve gotten nothing but a white box so far, unfortunately. I’m probably doing something wrong in binding the texture and setting the min filter, but I’m not sure. I’m not getting any help on StackOverflow, so I thought I’d ask around here too.
I’ve tried to convert it mostly to Java for you guys, although I haven’t made the GL calls object oriented - I assume you’ll be able to understand what I’m doing regardless. Also GLuint and all that can just be interpreted as their Java counterparts (int, float, etc.). Any calls to Globals or EAGLView are pretty straightforward and can more or less be ignored. I already know that most of this code works (it is duplicated from other working pieces) - the only new bit here is dynamically generating a texture and using a framebuffer.
//Declare instance variables.
GLuint texture;
GLuint textureFrameBuffer;
//Generate the texture and framebuffer.
glGetError();
//Generate the texture that we will draw to (saves us a lot of processor).
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Use OpenGL ES to generate a name for the texture.
// Pass by reference so that our texture variable gets set.
glGenTextures(1, &texture);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, texture);
// Specify a 2D texture image, providing a pointer to the image data in memory.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
//Create a frame buffer to draw to. This will allow us to directly edit the texture.
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
System.out.println("Error on framebuffer init. glError: " + err);
}
//Draw a big string into the framebuffer.
glGetError();
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
//Bind our frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
//Clear out the texture.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Draw the letters to the frame buffer. (calls glDrawArrays a bunch of times, binds various textures, etc.) Does everything in 2D.
renderDialog(displayString, fontAtlas, fontSpriteName);
//Unbind the frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
System.out.println("Error on string creation. glError: " + err);
}
//Draw it.
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glGetError();
//Draw the text.
EAGLView.enable2D();
//Push the matrix so we can keep it as it was previously.
glPushMatrix();
//Store the coordinates/dimensions from the rectangle.
float x = 0;
float y = Globals.getPlayableHeight() - dialogRect.size.height;
float w = Globals getPlayableWidth();
float h = dialogRect.size.height;
// Set up an array of values to use as the sprite vertices.
GLfloat vertices[] =
{
x, y,
x, y+h,
x+w, y+h,
x+w, y
};
// Set up an array of values for the texture coordinates.
GLfloat texcoords[] =
{
0, 0,
0, h / 128,
w / 512, h / 128,
w / 512, 0
};
//Render the vertices by pointing to the arrays.
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
// Set the texture parameters to use a linear filter when minifying.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Allow transparency and blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enable 2D textures.
glEnable(GL_TEXTURE_2D);
//Bind this texture.
EAGLView.bindTexture(texture);
//Finally draw the arrays.
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Restore the model view matrix to prevent contamination.
glPopMatrix();
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
System.out.println("Error on draw. glError: ", err);
}
Any help would be thoroughly appreciated.