FBO questions

Started by
22 comments, last by _the_phantom_ 18 years, 6 months ago
Quote:Original post by MARS_999
I went back to using glCopyTexImage2D and it works fine, but kicker is when I use glCopyTexSubImage2D instead of glCopyTexImage2D I see the same results as I do when I am using FBO's? What gives...


Without seeing how[/b[ you are doing it it is just impossible to tell whats wrong, you've given basically NO infomation...
Advertisement
Quote:Original post by phantom
Quote:Original post by MARS_999
I went back to using glCopyTexImage2D and it works fine, but kicker is when I use glCopyTexSubImage2D instead of glCopyTexImage2D I see the same results as I do when I am using FBO's? What gives...


Without seeing how[/b[ you are doing it it is just impossible to tell whats wrong, you've given basically NO infomation...



reflection
void CTerrain::RenderReflection(float move_y){	const double plane[4] = {0.0f, 1.0f, 0.0f, 0.0f};	waterReflection.BindBuffer();	glViewport(0, 0, mapData.waterTextureSizeWidth, mapData.waterTextureSizeHeight);	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);    glLoadIdentity();	   	g_Camera.LookAt();		glPushMatrix();	glTranslatef(0.0f, -move_y + mapData.waterHeight + .1f, 0.0f);	glScalef(1.0, -1.0, 1.0);    glEnable(GL_CLIP_PLANE0);    glClipPlane(GL_CLIP_PLANE0, plane);    		DrawTerrainVBO(0.0f, true);    glDisable(GL_CLIP_PLANE0);	glPopMatrix();	waterReflection.unBindBuffer();	//glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFLECTION]);	//glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, mapData.waterTextureSizeWidth, mapData.waterTextureSizeHeight, 0);}


refraction
void CTerrain::RenderRefractionAndDepth(float move_y){	const double plane[4] = {0.0f, -1.0f, 0.0f, 0.0f}; 	waterRefraction.BindBuffer();        waterDepth.BindBuffer();	glViewport(0, 0, mapData.waterTextureSizeWidth, mapData.waterTextureSizeHeight);	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	glLoadIdentity();	g_Camera.LookAt();	glPushMatrix();	glTranslatef(0.0f, -move_y + mapData.waterHeight + .1f, 0.0f);    glEnable(GL_CLIP_PLANE0);    glClipPlane(GL_CLIP_PLANE0, plane);		DrawTerrainVBO(0.0f, true);	    glDisable(GL_CLIP_PLANE0);	glPopMatrix();		waterRefraction.unBindBuffer();        waterDepth.unBindBuffer();	//glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFRACTION]);	//glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, mapData.waterTextureSizeWidth, mapData.waterTextureSizeHeight, 0);		//render depth to texture    //glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_DEPTHMAP]);	//glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, 0, 0, mapData.waterTextureSizeWidth, mapData.waterTextureSizeHeight, 0);	}


here is the texture binding function
void CTerrain::SetupTexturesWater(void){	glActiveTextureARB(GL_TEXTURE0_ARB);	waterReflection.RenderTexture();	//glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFLECTION]);		glActiveTextureARB(GL_TEXTURE1_ARB);	waterRefraction.RenderTexture();	//glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFRACTION]);	glActiveTextureARB(GL_TEXTURE2_ARB);	glBindTexture(GL_TEXTURE_2D, textureObject[WATER_NORMALMAP]);	glActiveTextureARB(GL_TEXTURE3_ARB);	glBindTexture(GL_TEXTURE_2D, textureObject[WATER_DUDVMAP]);	glActiveTextureARB(GL_TEXTURE4_ARB);	waterDepth.RenderTexture();	//glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_DEPTHMAP]);}


FBO class

#include "main.h"FBO::FBO(){	fb = 0;	depth_rb = 0;	texture = 0;	texture_target = 0;	texWidth = 0;	texHeight = 0;	filterMode = 0;	texInternalFormat = 0;	texFormat = 0;	depthTexture = false;}FBO::~FBO(){	glDeleteRenderbuffersEXT(1, &depth_rb);    glDeleteTextures(1, &texture);    glDeleteFramebuffersEXT(1, &fb);}void FBO::SetupFBO(unsigned int textureTarget, unsigned int tex_Width, unsigned int tex_Height, unsigned int filter_Mode, 		unsigned int tex_InternalFormat, unsigned int tex_Format, bool depth_Texture){	texture_target = textureTarget;	texWidth = tex_Width;	texHeight = tex_Height;	filterMode = filter_Mode;	texInternalFormat = tex_InternalFormat;	texFormat = tex_Format;	depthTexture = depth_Texture;}void FBO::Init(void){	glGenFramebuffersEXT(1, &fb);    glGenRenderbuffersEXT(1, &depth_rb);	glGenTextures(1, &texture);	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);	glBindTexture(texture_target, texture);		// init texture	glTexParameterf(texture_target, GL_TEXTURE_MIN_FILTER, filterMode);     glTexParameterf(texture_target, GL_TEXTURE_MAG_FILTER, filterMode);    glTexParameterf(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    glTexParameterf(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);	if(texture_target == GL_TEXTURE_3D)		glTexParameterf(texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);	glTexImage2D(texture_target, 0, texInternalFormat, texWidth, texHeight, 0, texFormat, GL_FLOAT, NULL);	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texture_target, texture, 0);	// initialize depth renderbuffer    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);}void FBO::BindBuffer(void){	glBindTexture(texture_target, 0);	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);	if(depthTexture)	{		glDrawBuffer(GL_NONE);        glReadBuffer(GL_NONE);	}}void FBO::unBindBuffer(void){	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);}void FBO::RenderTexture(void){	glBindTexture(texture_target, texture);}

Right, now you've finally posted the code I can tell you what you've done wrong [smile]

In your refraction function you do the following;
waterRefraction.BindBuffer();waterDepth.BindBuffer();


This firstly binds the FBO represented by the waterRefraction object as the target buffer and then replaces it with the FBO represened by the waterDepth FBO.

What you infact want is either ONE FBO which can be rendered to in either colour only and colour and depth mode OR you need to change your FBO class so you can share textures between FBO contexts.

See how much easier it is if you just post source to start with [smile]
Quote:Original post by phantom
Right, now you've finally posted the code I can tell you what you've done wrong [smile]

In your refraction function you do the following;
waterRefraction.BindBuffer();waterDepth.BindBuffer();


This firstly binds the FBO represented by the waterRefraction object as the target buffer and then replaces it with the FBO represened by the waterDepth FBO.

What you infact want is either ONE FBO which can be rendered to in either colour only and colour and depth mode OR you need to change your FBO class so you can share textures between FBO contexts.

See how much easier it is if you just post source to start with [smile]



Well I need a depth texture and color. So how do I go about that? Use RGBA? and use alpha channel as detpth? Unless I am not understanding FBOs, you can only render to one texture at a time? So what is the correct way to go about rendering both in one pass?
nope, you can infact render upto 5 textures at a time on current hardware; 4 colour and one depth.

You can bind a depth texture to the depth attachment of an FBO and you bind a colour texture to a colour attachment, thus the depth infomation ends up in the depth texture and the colour infomation ends up in the colour texture [smile]
Well here is my improved code for the FBO class and the rendering code hasn't changed and still doesnt' work.

#include "main.h"FBO::FBO(){	fb = 0;	depth_rb = 0;	colortextures[0] = 0;	colortextures[1] = 0;	colortextures[2] = 0;	colortextures[3] = 0;	depthtexture = 0;	texture_target = 0;	texWidth = 0;	texHeight = 0;	filterMode = 0;	texInternalFormat = 0;	texFormat = 0;	depthTexturing = false;}FBO::~FBO(){	glDeleteRenderbuffersEXT(1, &depth_rb);    for(int x = 0; x < 4; x++)	{        if(glIsTexture(colortextures[x]))            glDeleteTextures(1, &colortextures[x]);	}	glDeleteTextures(1, &depthtexture);    glDeleteFramebuffersEXT(1, &fb);}void FBO::SetupFBO(unsigned int textureTarget, unsigned int tex_Width, unsigned int tex_Height, unsigned int filter_Mode, 		unsigned int tex_InternalFormat, unsigned int tex_Format, bool depth_Texturing){	texture_target = textureTarget;	texWidth = tex_Width;	texHeight = tex_Height;	filterMode = filter_Mode;	texInternalFormat = tex_InternalFormat;	texFormat = tex_Format;	depthTexturing = depth_Texturing;}void FBO::Init(void){	glGenFramebuffersEXT(1, &fb);    glGenRenderbuffersEXT(1, &depth_rb);	glGenTextures(1, &colortextures[0]);	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);	glBindTexture(texture_target, colortextures[0]);//need to make this so you can use up to 4 color textures		// init texture	glTexParameterf(texture_target, GL_TEXTURE_MIN_FILTER, filterMode);     glTexParameterf(texture_target, GL_TEXTURE_MAG_FILTER, filterMode);    glTexParameterf(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    glTexParameterf(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);	if(texture_target == GL_TEXTURE_3D)		glTexParameterf(texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);	glTexImage2D(texture_target, 0, texInternalFormat, texWidth, texHeight, 0, texFormat, GL_FLOAT, NULL);	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texture_target, colortextures[0], 0);	// initialize depth renderbuffer    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, texture_target, depthtexture, 0);}void FBO::BindBuffer(void){	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);		glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);    glReadBuffer(GL_NONE);}void FBO::unBindBuffer(void){	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);}void FBO::RenderColorTexture(void){	glBindTexture(texture_target, colortextures[0]);}void FBO::RenderDepthTexture(void){	glBindTexture(texture_target, depthtexture);}


you must have made SOME changes to your drawing code, otherwise it still makes no sense..

also, you dont swap back to GL_BACK once you unbind and there is no good reason to set the glReadBuffer() to none, at least not without setting it back at some point.

Oh, on a coding note:
1) you might want to lookup initalisers so you can improve your constructor
2) you are probably better off doing the setup work in the constructors as well (RAII and all that)
3) Having the FBO object own the texture objects just strikes me as bad mojo, personally I'd rework the whole class so that it just takes texture object IDs and binds them to attachment points, it'll be MUCH easier to work with in the long run...
Quote:Original post by phantom
you must have made SOME changes to your drawing code, otherwise it still makes no sense..

also, you dont swap back to GL_BACK once you unbind and there is no good reason to set the glReadBuffer() to none, at least not without setting it back at some point.

Oh, on a coding note:
1) you might want to lookup initalisers so you can improve your constructor
2) you are probably better off doing the setup work in the constructors as well (RAII and all that)
3) Having the FBO object own the texture objects just strikes me as bad mojo, personally I'd rework the whole class so that it just takes texture object IDs and binds them to attachment points, it'll be MUCH easier to work with in the long run...



argh Here is what I have for now. I will look into the coding notes later as for now I just want the FBO's working... ;) I haven't changed any drawing code other than the FBO class and moved the depth texture into the Init() of the FBO class to render to the depthtexture and colortexture.

#include "main.h"FBO::FBO(){	fb = 0;	depth_rb = 0;	colortextures[0] = 0;	colortextures[1] = 0;	colortextures[2] = 0;	colortextures[3] = 0;	depthtexture = 0;	texture_target = 0;	texWidth = 0;	texHeight = 0;	texInternalFormat = 0;	texFormat = 0;	numColorTextures = 0;	filterMode = 0.0f;}FBO::~FBO(){	glDeleteRenderbuffersEXT(1, &depth_rb);    for(unsigned int x = 0; x < numColorTextures; x++)	{        if(glIsTexture(colortextures[x]))            glDeleteTextures(1, &colortextures[x]);	}	glDeleteTextures(1, &depthtexture);    glDeleteFramebuffersEXT(1, &fb);}void FBO::SetupFBO(unsigned int textureTarget, unsigned int tex_Width, unsigned int tex_Height, float filter_Mode, 		unsigned int tex_InternalFormat, unsigned int tex_Format, unsigned int num_ColorTextures){	texture_target = textureTarget;	texWidth = tex_Width;	texHeight = tex_Height;	filterMode = filter_Mode;	texInternalFormat = tex_InternalFormat;	texFormat = tex_Format;	if(num_ColorTextures >= 4)        numColorTextures = 3;	else 		numColorTextures = num_ColorTextures;}void FBO::Init(void){	glGenFramebuffersEXT(1, &fb);    glGenRenderbuffersEXT(1, &depth_rb);	glGenTextures(numColorTextures, colortextures);	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);	for(unsigned int x = 0; x < numColorTextures; x++)	{        glBindTexture(texture_target, colortextures[x]);        glTexParameterf(texture_target, GL_TEXTURE_MIN_FILTER, filterMode);         glTexParameterf(texture_target, GL_TEXTURE_MAG_FILTER, filterMode);        glTexParameterf(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);        glTexParameterf(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);        if(texture_target == GL_TEXTURE_3D)            glTexParameterf(texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);        		glTexImage2D(texture_target, 0, texInternalFormat, texWidth, texHeight, 0, texFormat, GL_FLOAT, NULL);		if(x == 0)            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texture_target, colortextures[x], 0);		else if(x == 1)            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, texture_target, colortextures[x], 0);		else if(x == 2)            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, texture_target, colortextures[x], 0);		else if(x == 3)            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, texture_target, colortextures[x], 0);	}	    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, texture_target, depthtexture, 0);}void FBO::BindBuffer(void){	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);}void FBO::unBindBuffer(void){	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);}void FBO::RenderColorTexture(unsigned int texID){	glBindTexture(texture_target, colortextures[texID]);}void FBO::RenderDepthTexture(void){	glBindTexture(texture_target, depthtexture);}

BTW I am looking at the examples on the oss.sgi.com page for FBO's and don't see one for what I am trying to do...
Forget it I got it working!! WOOT!!
Quote:Original post by phantom
a framebuffer object is an object which holds multiples colour buffer targets, as well as optional depth and stencil targets (currently).

A render buffer is a logical buffer which you can attach to a framebuffer object to render into.

If you want to render to a texture you must attach the texture to colour or depth attachment point of the framebuffer object.

Infomation, as always, is in the spec as well as NV's GDC2005 PDF's linked from the Forum FAQ


I don't quite understand the Render Buffer/FBO part. could you please do a little bit more explaining as to what they are?
TIA

This topic is closed to new replies.

Advertisement