Hi, thanks guys, I was still struggling a bit with the OpenGL calls (like which exact funcs were needed) but it's working!
https://i.imgur.com/Mm8TY0C.png
For now, I'm drawing straight to the backbuffer. The steps I've done, (unless I've done something wrong or missed something), are this:
1. glGenFramebuffers (make a single test fbo)
2. glBindFramebuffer (binds the new fbo to the GL_READ_FRAMEBUFFER)
3. glFramebufferTexture2D (attaches a texture object (which I already had uploaded outside of the function) to the new fbo)
4. iterate through the string, using glBlitFramebuffer... the Src being the READ fbo, and the Dst being the backbuffer (which I guess it is, by default?)
5. glBindFramebuffer 0 to unbind it
6. glDeleteFramebuffers on my fbo in cleanup
Here it is, keep in mind I'm doing EVERYTHING (init and cleanup) inside this function, which I know is dumb, I'll fix that =)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
void GameEngine::_Write(const char* text, GLuint x, GLuint y)
{
// Do this only once, in Init
/////////////////////////////////////////////////////////
// Create framebuffer
GLuint tempFbo = 0;
glGenFramebuffers(1, &tempFbo);
/////////////////////////////////////////////////////////
// Do this only before the first _Write() call
/////////////////////////////////////////////////////////
// Bind framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFbo);
/////////////////////////////////////////////////////////
// Attach the font texture to the framebuffer
// TODO: Hard-coded font texture (_textures[1])
glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
_textures[1], 0);
// Draw every letter in the passed-in string
for(int i = 0; text[i] != 0; ++i)
{
// Get character
unsigned char char_value = text[i] - 33;
// Get proper position to draw at
// TODO: Screen size (480) hard-coded
SDL_Point pos;
pos.x = x;
pos.y = 480 - y;
// Note: Flip vertically for OpenGL
// Draw character
_DrawTextCharacter(1, char_value, pos, i);
}
// Do this only after the last _Write() call
/////////////////////////////////////////////////////////
// Unbind framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
/////////////////////////////////////////////////////////
// Do this only once, in Cleanup
/////////////////////////////////////////////////////////
// Delete framebuffer
glDeleteFramebuffers(1, &tempFbo);
/////////////////////////////////////////////////////////
}
| |
And here is my _DrawTextCharacter function... this one's not too important but maybe someone who finds this thread might want to use it for reference
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
void GameEngine::_DrawTextCharacter(GLuint tex, GLuint sprite, SDL_Point& pos, GLuint i)
{
// TODO: Hard-coded values for dimensions of character
GLint sprite_w = 8;
GLint sprite_h = 16;
// TODO: Retrieve texture dimensions from OpenGL
// Store my own values instead?
GLint texture_w;
GLint texture_h;
// Retrieve the dimensions of the texture
glBindTexture(GL_TEXTURE_2D, _textures[tex]);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_h);
glBindTexture(GL_TEXTURE_2D, 0);
// Get rows, cols, and total indices in sprite sheet
GLint num_rows = texture_h / sprite_h;
GLint num_cols = texture_w / sprite_w;
GLint total_rects = num_rows * num_cols;
// Safety clamp for passed-in character value
sprite %= total_rects;
// Assign rect data
SDL_Rect src, dst;
src.x = ((sprite % num_cols) * sprite_w);
src.w = ((sprite % num_cols) * sprite_w) + sprite_w;
src.y = texture_h - ((sprite / num_cols) * sprite_h) - sprite_h;
src.h = texture_h - ((sprite / num_cols) * sprite_h);
dst.x = (i * sprite_w) + pos.x;
dst.w = (i * sprite_w) + pos.x + sprite_w;
dst.y = pos.y - sprite_h;
dst.h = pos.y;
// Note: "w" and "h" are used as "x1" and "y1" values
// Note: Intentional vertical flip on Y-axis
// Draw character
glBlitFramebuffer(
src.x, src.y,
src.w, src.h,
dst.x, dst.y,
dst.w, dst.h,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
| |
So I have a couple more questions:
1. First, aside from not yet splitting up the Gen/Bind/Unbind/Delete parts into external functions, have I done anything glaringly wrong, dangerous, wasteful, etc? For example, in DrawTextCharacter, is retrieving the already-uploaded texture dimensions with glGetTexLevelParameteriv a stupid idea, and I should manually save that kind of thing, or is retrieving it from OpenGL just dandy?
2. Do I need to un-attach the texture object from my FBO before unbinding and deleting the FBO, or does that not really matter? (I assume if I were to attach another texture on the same channel, the old one gets overwritten anyway yeah?)
Thanks again