2

I need your help again. I wanna use Frame Buffer Object bigger than the Screen size. When I do it as below FBO size 1024 x 1024 is cut off from the top in resolution 1024 x 768. I couldn't find the solution on my own - that's why I'm asking.

First part of code is the way I create FBO, I do the rendering between activate, and deactivate. Later I use texture.

What am I doing wrong?

What is the fastest way to clear Frame Buffer Object for reuse?

public FrameBufferObject(int width, int height) {
    this.width = width;
    this.height = height;
    texture = glGenTextures();
    frameBufferObject = GL30.glGenFramebuffers();
    activate();
    glBindTexture(GL_TEXTURE_2D, texture);
    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_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_BYTE, BufferUtils.createByteBuffer(4 * width * height));
    GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    deactivate();
}

public void activate() {
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObject);
}

public void deactivate();
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
}

OpenGL settings:

private static void initializeOpenGL() {
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_MULTISAMPLE);
    glEnable(GL_BLEND);
    glEnable(GL_SCISSOR_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0, 0, 0, 0);
}
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Przemek
  • 25
  • 4

1 Answers1

1

You need to call glViewport() with the FBO dimensions after binding it, and before starting to render. Note that the viewport dimensions are global state, not per-framebuffer state, so you also have to set them back when you render to the default framebuffer again.

With the numbers you use in the question (you obviously wouldn't want to use hardcoded numbers in real code):

public void activate() {
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObject);
    glViewport(0, 0, 1024, 1024);
}

public void deactivate();
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
    glViewport(0, 0, 1024, 768);
}
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Thank You for your answer. I already tried that but then everything gets strecht. Well I have to fix that. Thank You again. – Przemek Feb 11 '15 at 09:23
  • Well, you can't have content that you originally rendered into a 1024x768 surface fill a 1024x1024 surface without getting stretched. If you're using a projection matrix, you'll probably have to adjust that too, since it often includes the aspect ratio of the surface. – Reto Koradi Feb 11 '15 at 15:02
  • Well It doesn't work. Something else need to be wrong as well. FBO is still cut off from the top. I also using glScissors and I set it like glViewport before rendering. No difference. What else can be wrong here? I've added OpenGL settings to first post. – Przemek Feb 13 '15 at 00:10
  • You certainly need to update the projection matrix (`glOrtho()` call). – Reto Koradi Feb 13 '15 at 00:17
  • Thank You for your help. I think that better solution will be to use 4 separated FBO's - I could do some optimalization that way. Not everything have to be rendered if part will be off screen. – Przemek Feb 13 '15 at 13:53