DiddiZ
DiddiZ

Reputation: 655

OpenGL Render to texture Coordinates

I want to be able to render to a texture (for shaders, fonts), but I've got a problem a problem to position the quad properly (the framebuffer itself does what it should do). The resulting (copied) texture shows in most cases the upper left corder, the rest gets cropped. That's worser for rectangular textures, nearly no effect for square textures (so I happen to not recognize this behaviour for days)

Example code:

    public Texture copy(final Texture tex) {
    final int tempTex = glGenTextures();
    Draw.bindTexture(tempTex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.getImageWidth(), tex.getImageHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, (ByteBuffer)null);

    // Adjust projection matrix
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glViewport(0, 0, tex.getImageWidth(), tex.getImageHeight());

    // Change blendmode to ignore the transparent background
    Draw.blendingMode(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    // Prepare fbo, add the texture as backend and clear it
    final int fbo = glGenFramebuffers();
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tempTex, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Finally draw
    Draw.bindTexture(tex.getId());
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0, 0);
        glVertex2f(-1, -1);
        glTexCoord2f(1, 0);
        glVertex2f(1, -1);
        glTexCoord2f(1, 1);
        glVertex2f(1, 1);
        glTexCoord2f(0, 1);
        glVertex2f(-1, 1);
    }
    glEnd();

    // Unbind framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Reset projection matrix
    glViewport(0, 0, 1920, 1080); // TODO Don't hardcode
    glPopMatrix();

    return new Texture(tempTex, tex.getImageWidth(), tex.getImageHeight());
}

Example image:

enter image description here

The uppers are the original images as rendered, below the copied version

What am I doing wrong?


Update: Now it seems like the texture gets downsampled

enter image description here

Upvotes: 4

Views: 1285

Answers (2)

TheWhiteLlama
TheWhiteLlama

Reputation: 1286

The best way is, to use a ortho-projection-matrix which is sized like your display is (1920x1080). You texture has to be a 2 pow sized texture, so you would have to make it 2048x2048. If you now render the result onto a rect of the texture (not fit to the whole texture), then you are able to render it with the same matrix back on the screen. (pixel correct)

Upvotes: 0

Tim
Tim

Reputation: 35943

You shouldn't be passing the actual texture width and height into the texcoords. Texture coordinates range from 0 (bottom & left) to 1 (top & right). You don't hardcode the actual texture dimensions into the texture coordinate.

Try replacing your getWidth/getHeight in the texcoord functions with "1"

Upvotes: 1

Related Questions