Я использую opengl ES 2.0. Я использую кадровый буфер, связанный с текстурой, для компиляции закадрового рендера (некоторых упрощенных метаболлов), а затем я рендеринг этой текстуры в основной задний буфер.
Все выглядит отлично, за исключением того, что текстура выглядит обрезанной, т.е.это не полные размеры окна (если не считать около 128 пикселей на одной оси).Вот скриншот: http://tinypic.com/r/9telwg/7
Есть идеи, что может вызвать это?Я прочитал здесь , чтобы установить glViewport на размер текстуры, но это дает мне другое соотношение сторон, так как текстура metaballsTexture имеет квадратную форму (1024x1024), а мое окно - 768x1024.Это также все еще остается немного обрезанным, поскольку кажется, что я не могу сделать буфер кадров достаточно большим, даже если текстура больше моего размера окна.Ниже мой код.Я вызываю PrepareToAddMetaballs () во время рендеринга, когда я готов, затем последовательные вызовы AddMetaball, которые теперь отображаются на моем внешнем FBO, затем FinishedAddingMetaballs, когда я закончил, и позже вызываю Render (), чтобы отобразить текстуру за кадром, связанную с FBO.на основной буфер.
#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);
}
===========================
РЕДАКТИРОВАТЬ
Ага!Понял.Я нигде не нашел этот пример, но я исправил его, настроив матрицу перспективы.Он был установлен на 1024x768, когда он работал, но с размером окна 768x1024, матрица проекции изменялась, как и область просмотра.Если вручную установить для каждого значения 1024x768 (я выбрал использование констант), метаболы отображаются правильно за кадром с правильным соотношением сторон.Их текстура 1024x1024 визуализируется как рекламный щит с таким хорошим соотношением сторон.После того, как я это сделаю, я восстановлю их до того, что использует остальная часть приложения.Ниже приведен рабочий код:
#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);
}