4

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

DiddiZ
  • 625
  • 8
  • 17

2 Answers2

1

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"

Tim
  • 35,413
  • 11
  • 95
  • 121
  • getWidth/getHeight are texture dimensions from 0 to 1, but I'll try 1 – DiddiZ May 07 '12 at 18:05
  • In that case you've probably got the right thing already, I assumed this was the texture dimension in pixels. – Tim May 07 '12 at 18:14
  • That (whith another change) seems to solve the positiong issue, but now the texture looks a bit down sampled ... – DiddiZ May 07 '12 at 18:51
0

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)

TheWhiteLlama
  • 1,276
  • 1
  • 18
  • 31
  • I really need to render to smaller textures. Otherwise text caching wouldn't make any sense. – DiddiZ May 11 '12 at 16:33