Jump to content

  • Log In with Google      Sign In   
  • Create Account


Render to framebuffer doesn't work


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 Juliean   GDNet+   -  Reputation: 2329

Like
0Likes
Like

Posted 24 December 2013 - 06:20 AM

Hello,

 

I'm having slight troubles rendering to a framebuffer object. At first I thought it was something with my shaders, since the scene showed only black, but once I comment out the command for binding the framebuffer and render directly to the backbuffer, there is at least some output. I have searched high and low for tutorials and explanations, but so far I couldn't see any real difference to how I'm doing it. Let me show you the code I'm using:

 

EDIT: Nevermind, I've been displaying the result of the wrong render stage, which didn't include the sky yet, and had a multiplication order issue so nothing else was shown, now it seems to work.

FrameBuffer::FrameBuffer(void)
{
	GL_CHECK(glGenFramebuffers(1, &m_frameBuffer));

	GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer));

	// TODO: evaluate the attachements properly
	GLenum enums[1] = { GL_COLOR_ATTACHMENT0 };
	glDrawBuffers(1, enums);

	GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}

FrameBuffer::~FrameBuffer(void)
{
	GL_CHECK(glDeleteFramebuffers(1, &m_frameBuffer));
}

bool FrameBuffer::IsComplete(void) const
{
	GLenum value;
	GL_CHECK(value = glCheckFramebufferStatus(GL_FRAMEBUFFER));
	return value == GL_FRAMEBUFFER_COMPLETE;
}

void FrameBuffer::UnbindTexture(unsigned int slot) const
{
	GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + slot, GL_TEXTURE_2D, 0, 0));
}

void FrameBuffer::Bind(void) const
{
	GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer));
}

void FrameBuffer::Unbind(void) const
{
	GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}

This is the framebuffer-object wrapper class. It has methods for binding, unbinding, and binding a texture attachement to nullptr if needed. Here is how it is used to bind a texture:

m_pFrameBuffer->Bind();
if(pTexture)
	pTexture->GetAclTexture().BindTarget(index);
else
	m_pFrameBuffer->UnbindTexture(index);
m_pFrameBuffer->Unbind();

This is in my stage class, when a texture is bound as a target. The BindTarget-method looks like this:

void Texture::BindTarget(unsigned int slot) const
{
	ACL_ASSERT(m_isRenderTarget);
	GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + slot, GL_TEXTURE_2D, m_texture, 0));
}

Also, if it is important, here is how the texture is created:

Texture::Texture(unsigned int width, unsigned int height, int format, bool bIsRenderTarget) : m_texture(0), m_format(format),
	m_vSize(width, height), m_frameBuffer(0), m_isRenderTarget(bIsRenderTarget)
{
	GL_CHECK(glGenTextures(1, &m_texture));
	GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_texture));
	GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, format, m_vSize.x, m_vSize.y, 0, formatToDataFormat(format), formatToType(format), nullptr));
}

The formats returned by the helper functions for the texture in question is GL_RGB and GL_UNSIGNED_BYTE.

 

I'm also using a depth-attachement, though depth testing is currently disabled:

// depth buffer creation
DepthBuffer::DepthBuffer(int width, int height): m_depthBuffer(0), 
	m_vSize(width, height)
{
	GL_CHECK(glGenRenderbuffers(1, &m_depthBuffer));

	GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer));

	GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height));
}
//... and attachement
void DepthBuffer::Bind(void) const
{
	GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer));
}

Attachement in the stage works similar:

if(pZBuffer)
{
	m_pFrameBuffer->Bind();
	pZBuffer->GetBuffer().Bind();
	m_pFrameBuffer->Unbind();
}

Usage while rendering then happens by executing a BindRenderTargets-command class:

class BindRenderTargets :
	public render::State<BindRenderTargets>
{
public:

	BindRenderTargets(const ogl::FrameBuffer* pBuffer) : pBuffer(pBuffer) {}

	void Execute(const ogl::Context& context) const
	{
		if(pBuffer)
		{
			pBuffer->Bind();
#ifdef _DEBUG
			ACL_ASSERT(pBuffer->IsComplete());
#endif
		}
		else
			context.UnbindFramebuffer();
	};

	private:

		const ogl::FrameBuffer* pBuffer;
};

which simply binds the frame buffer, and checks to see if it is complete, which appears to be true.

 

Also, in case it helps, here is the shader that is being used (should render a sky-sphere):

uniform InstanceV
{
	mat4 mWorld;
};

uniform StageV
{
	mat4 mViewProj;
	vec3 vCameraPos;
};

layout(location = 0) in vec3 invPos;
layout(location = 1) in vec2 invTex0;

#define outvPos gl_Position
layout(location = 0) out vec2 outvTex0;

void main()
{

	outvPos = vec4(invPos, 1.0f);

	mat4 mModWorld = mWorld;
	mModWorld[3].xyz = vCameraPos;

	outvPos = (outvPos*(mModWorld* mViewProj)).xyww;
	outvPos.z *= 0.99999f;

	outvTex0 = invTex0;

}

// frag_begin

layout(location = 0) in vec2 invTex0;

layout(location = 0) out vec4 outvColor;

uniform sampler2D Material;

void main()
{
	outvColor = pow(texture(Material, invTex0),vec4(2.2))*12.5;
	outvColor = 1.0f;
}

Now if I just skip the render target command execution, and therefore always draw to the backbuffer, I see both the GUI, plus the content of what should go into the framebuffers target textures. If I bind the framebuffer, I only see the gui (so it is certain that its not a problem of rendering only in the framebuffer), but the texture to which the framebuffer should render, stays black. There is certainly no error in the gui, since with the DX11 or DX9 render implementation it shows just as expected.

 

Does anybode see something strange or something the is missing?


Edited by Juliean, 24 December 2013 - 10:58 AM.


Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS