opengl - framebuffer纹理剪切小于我设置呢? [英] opengl - framebuffer texture clipped smaller than I set it?

查看:143
本文介绍了opengl - framebuffer纹理剪切小于我设置呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用opengl ES 2.0
我使用链接到纹理的帧缓冲区编译屏幕渲染(一些简单的元球),然后我将该纹理渲染到主后台缓冲区。

I'm using opengl ES 2.0 I'm using a framebuffer linked to a texture to compile an offscreen render (of some simplistic metaballs), and then I'm rendering that texture to the main back buffer.

除了纹理出现剪辑外,一切看起来都很棒。它不是全窗口尺寸(在一个轴上短约128个像素)。以下是屏幕截图: http://tinypic.com/r/9telwg/7

Everything is looking great except that the texture appears clipped, ie. it is not the full window dimensions (short of about 128 pixels on one axis). Here's a screenshot: http://tinypic.com/r/9telwg/7

任何想法会导致什么?我阅读了此处以设置glViewport到纹理的大小,但是给我一个不同的宽高比,因为纹理metaballsTexture是正方形(1024x1024)和我的窗口是768x1024。它也仍然有点剪辑,因为它似乎我不能得到足够大的帧缓冲区,即使纹理大于我的窗口大小。下面是我的代码。我准备好时,在渲染期间调用PrepareToAddMetaballs(),然后连续调用AddMetaball,现在渲染到我的offfreeen FBO,然后FinishedAddingMetaballs,当我完成后,然后调用Render()显示与FBO链接的屏幕外纹理

Any ideas what could cause this? I read here to set glViewport to the size of the texture, but that gives me a different aspect ratio since the texture metaballsTexture is square (1024x1024) and my window is 768x1024. It also still remains a bit clipped, as it seems I can't get the frame buffer to be big enough, even though the texture is bigger than my window size. Below is my code. I call PrepareToAddMetaballs() during the render when I'm ready, then successive calls to AddMetaball, now rendered onto my offscreeen FBO, then FinishedAddingMetaballs when I'm done, and later call Render() to display the offscreen texture linked to the FBO onto the main backbuffer.

#include "Metaballs.h"
#include "s3e.h"
#include "IwGL.h"
#include "Render.h"
#include "vsml.h"
#include <vector>
#include <string>
#include <iostream>
#include "1013Maths.h"

#define GL_RGBA8 0x8058

MetaBalls::MetaBalls() : metaballsTexture(NULL), metaballsShader(NULL) {
    glGenFramebuffers(1, &myFBO);

    metaballTexture[0] = NULL;
    metaballTexture[1] = NULL;
    metaballTexture[2] = NULL;
    CRender::Instance()->CreateTexture("WaterCanvas.png", &metaballsTexture);
    CRender::Instance()->CreateTexture("metaball.pvr", &metaballTexture[0]);
    CRender::Instance()->CreateTexture("metaball-1.png", &metaballTexture[1]);
    CRender::Instance()->CreateTexture("metaball-2.png", &metaballTexture[2]);
    CRender::Instance()->CreateShader("Shaders/metaballs.fs", "Shaders/metaballs.vs", &metaballsShader);

    glBindFramebuffer(GL_FRAMEBUFFER, myFBO);
    // Attach texture to frame buffer
    glBindTexture(GL_TEXTURE_2D, metaballsTexture->m_id);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, metaballsTexture->m_id, 0);
    glClearColor(1,1,1,0);
    glClear(GL_COLOR_BUFFER_BIT);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::string error = "Metaballs framebuffer incomplete";
        std::cerr << error << std::endl;
        throw error;
    }

    float w = PTM_DOWNSCALE(float(metaballsTexture->GetWidth()));
    float h = PTM_DOWNSCALE(float(metaballsTexture->GetHeight()));

    CRender::Instance()->BuildQuad(
        tVertex( b2Vec3(0,0,0), b2Vec2(0,1) ),
        tVertex( b2Vec3(w,0,0), b2Vec2(1,1) ),
        tVertex( b2Vec3(w,h,0), b2Vec2(1,0) ),
        tVertex( b2Vec3(0,h,0), b2Vec2(0,0) ),
        buffer);

}

MetaBalls::~MetaBalls() {
    CRender::Instance()->ReleaseShader(metaballsShader);
    CRender::Instance()->ReleaseTexture(metaballsTexture);
    CRender::Instance()->ReleaseTexture(metaballTexture[0]);
    CRender::Instance()->ReleaseTexture(metaballTexture[1]);
    CRender::Instance()->ReleaseTexture(metaballTexture[2]);
    glDeleteFramebuffers(1, &myFBO);
}

void MetaBalls::PrepareToAddMetaballs(b2Vec3& paintColour) {

    // bind render to texture
    glBindFramebuffer(GL_FRAMEBUFFER, myFBO);
    // Set our viewport so our texture isn't clipped (appears stretched and clipped)
    // glViewport(0, 0, metaballsTexture->GetWidth(), metaballsTexture->GetHeight());
    glClearColor(paintColour.x, paintColour.y, paintColour.z, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

}

void MetaBalls::FinishedAddingMetaballs() {
    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
    // CRender::Instance()->SetWindowViewport();
}

void MetaBalls::AddMetaball(float x, float y, uint size) {

    // render the metaball texture to larger texture
    VSML::setIdentityMatrix(pTransform);
    pTransform[12] = PTM_DOWNSCALE(x);
    pTransform[13] = PTM_DOWNSCALE(y+4); // the +4 is for a bit of overlap with land
    float oldview[16];
    float identity[16];
    VSML::setIdentityMatrix(identity);
    memcpy(oldview, CRender::Instance()->GetViewMatrix(), sizeof(float)*16);
    memcpy(CRender::Instance()->GetViewMatrix(),identity, sizeof(float)*16);
    CRender::Instance()->DrawSprite(metaballTexture[size], pTransform, 1.0f, true);
    memcpy(CRender::Instance()->GetViewMatrix(),oldview, sizeof(float)*16);
}

void MetaBalls::Render() {

    VSML::setIdentityMatrix(pTransform);
    pTransform[12] = PTM_DOWNSCALE(-128);
    pTransform[13] = PTM_DOWNSCALE(-256);

    // render our metaballs texture using alpha test shader
    CRender::Instance()->BindShader(metaballsShader);
    CRender::Instance()->BindTexture(0, metaballsTexture);

    CRender::Instance()->SetMatrix(metaballsShader, "view", CRender::Instance()->GetViewMatrix());
    CRender::Instance()->SetMatrix(metaballsShader, "world", pTransform);
    CRender::Instance()->SetMatrix(metaballsShader, "proj", CRender::Instance()->GetProjMatrix());

    CRender::Instance()->SetBlending(true);
    CRender::Instance()->DrawPrimitives(buffer);
    CRender::Instance()->SetBlending(false);

}

============ ========

====================

Aha!得到它了。我没有找到这个例子在任何地方,但我通过调整透视矩阵固定。它在工作时设置为1024x768,但是窗口大小为768x1024,投影矩阵也改变,以及视口。通过手动设置每个1024x768(我选择使用常量),metaballs正确离屏正确的宽高比。他们的1024x1024纹理被渲染为一个广告牌与那个宽高比漂亮和清晰。完成后,我将其还原到应用程序的其余部分使用。以下是工作代码:

Aha! Got it. I haven't found this example anywhere, but I fixed it by adjusting the perspective matrix. It was set to 1024x768 when it was working, but with a window size of 768x1024, the projection matrix was changing, as well as the viewport. By setting each to 1024x768 manually (I chose to use constants), the metaballs are rendered correctly offscreen with proper aspect ratio. Their 1024x1024 texture is rendered as a billboard with that aspect ratio nice and sharp. After I'm done I restore them to what the rest of the application uses. Below is the working code:

#include "Metaballs.h"
#include "s3e.h"
#include "IwGL.h"
#include "Render.h"
#include "vsml.h"
#include <vector>
#include <string>
#include <iostream>
#include "1013Maths.h"

MetaBalls::MetaBalls() : metaballsTexture(NULL), metaballsShader(NULL) {

    glGenFramebuffers(1, &myFBO);

    metaballTexture[0] = NULL;
    metaballTexture[1] = NULL;
    metaballTexture[2] = NULL;
    CRender::Instance()->CreateTexture("WaterCanvas.png", &metaballsTexture);
    CRender::Instance()->CreateTexture("metaball.pvr", &metaballTexture[0]);
    CRender::Instance()->CreateTexture("metaball-1.png", &metaballTexture[1]);
    CRender::Instance()->CreateTexture("metaball-2.png", &metaballTexture[2]);
    CRender::Instance()->CreateShader("Shaders/metaballs.fs", "Shaders/metaballs.vs", &metaballsShader);

    glBindFramebuffer(GL_FRAMEBUFFER, myFBO);

    // Attach texture to frame buffer
    glBindTexture(GL_TEXTURE_2D, metaballsTexture->m_id);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, metaballsTexture->m_id, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::string error = "Metaballs framebuffer incomplete";
        std::cerr << error << std::endl;
        throw error;
    }

    float w = PTM_DOWNSCALE(float(metaballsTexture->m_width));
    float h = PTM_DOWNSCALE(float(metaballsTexture->m_height));

    CRender::Instance()->BuildQuad(
        tVertex( b2Vec3(0,0,0), b2Vec2(0,1) ),
        tVertex( b2Vec3(w,0,0), b2Vec2(1,1) ),
        tVertex( b2Vec3(w,h,0), b2Vec2(1,0) ),
        tVertex( b2Vec3(0,h,0), b2Vec2(0,0) ),
        buffer);

    // return to default state
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

MetaBalls::~MetaBalls() {
    CRender::Instance()->ReleaseShader(metaballsShader);
    CRender::Instance()->ReleaseTexture(metaballsTexture);
    CRender::Instance()->ReleaseTexture(metaballTexture[0]);
    CRender::Instance()->ReleaseTexture(metaballTexture[1]);
    CRender::Instance()->ReleaseTexture(metaballTexture[2]);
    glDeleteFramebuffers(1, &myFBO);
}

void MetaBalls::PrepareToAddMetaballs(b2Vec3& paintColour) {

    // bind render to texture
    glBindFramebuffer(GL_FRAMEBUFFER, myFBO);

    // Set orthographic projection
    cfloat w = SCREEN_WIDTH / PTM_RATIO;
    cfloat h = SCREEN_HEIGHT / PTM_RATIO;
    VSML::ortho(-w, 0, -h, 0, 0.0f, -1.0f, CRender::Instance()->m_Proj);

    // Set our viewport so our texture isn't clipped
    glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    glClearColor(paintColour.x, paintColour.y, paintColour.z, 0.1f);
    glClear(GL_COLOR_BUFFER_BIT);

}

void MetaBalls::FinishedAddingMetaballs() {
    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
    CRender::Instance()->SetWindowViewport();
}

void MetaBalls::AddMetaball(float x, float y, uint size) {

    // render the metaball texture to larger texture
    VSML::setIdentityMatrix(pTransform);
    pTransform[12] = PTM_DOWNSCALE(x);
    pTransform[13] = PTM_DOWNSCALE(y);
    float oldview[16];
    float identity[16];
    VSML::setIdentityMatrix(identity);
    memcpy(oldview, CRender::Instance()->GetViewMatrix(), sizeof(float)*16);
    memcpy(CRender::Instance()->GetViewMatrix(),identity, sizeof(float)*16);
    CRender::Instance()->DrawSprite(metaballTexture[size], pTransform, 1.0f, true);
    memcpy(CRender::Instance()->GetViewMatrix(),oldview, sizeof(float)*16);
}

void MetaBalls::Render() {

    VSML::setIdentityMatrix(pTransform);
    pTransform[12] = PTM_DOWNSCALE(0);
    pTransform[13] = PTM_DOWNSCALE(-256);

    // render our metaballs texture using alpha test shader
    CRender::Instance()->BindShader(metaballsShader);
    CRender::Instance()->BindTexture(0, metaballsTexture);

    CRender::Instance()->SetMatrix(metaballsShader, "view", CRender::Instance()->GetViewMatrix());
    CRender::Instance()->SetMatrix(metaballsShader, "world", pTransform);
    CRender::Instance()->SetMatrix(metaballsShader, "proj", CRender::Instance()->GetProjMatrix());

    CRender::Instance()->SetBlending(true);
    CRender::Instance()->DrawPrimitives(buffer);
    CRender::Instance()->SetBlending(false);

}


推荐答案

根据纹理的大小设置视口?我没有找到任何视图端口设置您的代码...

Are you setting your viewport according to the texture's size? I didnt find any view port setting on your code...

这篇关于opengl - framebuffer纹理剪切小于我设置呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆