0
\$\begingroup\$

I am having trouble rendering to a texture and then mapping that texture to a quad. I am using OpenGL 2.0. I am using code from the wiki. The class scene_t has a texture called _out_tex, which is the texture that game_window_t will map to a quad filling the entire screen:

Code in main.c:

game_window_t gwin;
gwin.w = 800;
gwin.h = 600;
gwin.title = (char *) "2D Lighting";
gfx::create_window(&gwin);

math::poly2d poly;
poly.add_vertex(math::vec2f(400.0f, 0.0f));
poly.add_vertex(math::vec2f(0.0f,   600.0f));
poly.add_vertex(math::vec2f(800.0f, 600.0f));

gfx::object_t o;
o.set_color(math::vec4f(1.0f, 1.0f, 1.0f, 1.0f));
o.shape = &poly;

if(scene.set_parent_window(&gwin) < 0)
{
    printf("Error setting parent window\n");
    goto panic;
}

scene.add_object(&o);

scene.render();
gwin.put_scene(&scene);
gfx::flip(&gwin);

Code in scene.cpp:

char scene_t::set_parent_window(game_window_t *win)
{
    _parent_win = win;
    _w = win->w;
    _h = win->h;

     //RGBA8 2D texture, 24 bit depth texture, 256x256
   glGenTextures(1, &_out_tex);
   glBindTexture(GL_TEXTURE_2D, _out_tex);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   //NULL means reserve texture memory, but texels are undefined
   //**** Tell OpenGL to reserve level 0
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _w, _h, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
   //You must reserve memory for other mipmaps levels as well either by making a series of calls to
   //glTexImage2D or use glGenerateMipmapEXT(GL_TEXTURE_2D).
   //Here, we'll use :
   glGenerateMipmapEXT(GL_TEXTURE_2D);
   //-------------------------
   glGenFramebuffersEXT(1, &_fbuf);
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbuf);
   //Attach 2D texture to this FBO
   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _out_tex, 0);
   //-------------------------
   glGenRenderbuffersEXT(1, &_depth_rb);
   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _depth_rb);
   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, _w, _h);
   //-------------------------
   //Attach depth buffer to FBO
   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, _depth_rb);
   //-------------------------
   //Does the GPU support current FBO configuration?
   GLenum status;
   status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

   if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
   {
        printf("Error setting up framebuffer\n"); return -1;
   }

    return 0;
}

void scene_t::render()
{
    // render to texture
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbuf);
    glViewport(0, 0, _w, _h);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    for(int i = 0; i < _objects.size(); i++)
    {
        _objects[i]->render();
    }

    return;
}

Code in game_window.cpp:

char game_window_t::put_scene(scene_t *s)
{
    // if(s->_parent_win != this) { printf("SCENE DOES NOT BELONG TO WINDOW\n"); return -1; }

    // begin texture mapping
    glBindFramebuffer(GL_FRAMEBUFFER_EXT | GL_FRAMEBUFFER, 0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, s->_out_tex);

    printf("tex: %u\n", s->_out_tex);

    // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glViewport(0, 0, 800, 600);
    glBegin(GL_QUADS);
    glNormal3d(0.0f, 0.0f, 1.0f);
        glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);    // top left
        glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 600.0f);     // bottom left
        glTexCoord2f(1.0f, 1.0f); glVertex2f(800.0f, 600.0f);    // bottom right
        glTexCoord2f(1.0f, 0.0f); glVertex2f(800.0f, 0.0f);   // top right
    glEnd();

    printf("put!\n");
}

object_t::render() just renders a triangle strip with the vertices of its shape polygon.

I don't understand why the texture (or whatever is rendered in game_window_t::put_scene()) is just black. Any help would be greatly appreciated. I am aware that I am using a somewhat deprecated and outdated version of OGL, but I don't need the functionality of 3+ as far as I am concerned.

Thank you!

\$\endgroup\$
1
\$\begingroup\$

You aren't passing any data to glTexImage2D -- the last parameter, per the docs, "Specifies a pointer to the image data in memory." (see: https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml)

Since your target (first param) is GL_TEXTURE_2D, relevant info from link:

If target is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE or one of the GL_TEXTURE_CUBE_MAP targets, data is read from data as a sequence of signed or unsigned bytes, shorts, or longs, or single-precision floating-point values, depending on type. These values are grouped into sets of one, two, three, or four values, depending on format, to form elements. Each data byte is treated as eight 1-bit elements, with bit ordering determined by GL_UNPACK_LSB_FIRST

Try giving that function a small set of data and see if it works. From https://open.gl/textures, the following should give you a black and white checker board pattern.

float pixels[] = {
    0.0f, 0.0f, 0.0f, 1.0f,   1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f, 1.0f
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _w, _h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

NB: I did have to alter the above slightly to fit into what you have, but the general idea is the same.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.