Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::view and FBO's  (Read 2735 times)

0 Members and 1 Guest are viewing this topic.

luminous

  • Newbie
  • *
  • Posts: 8
    • View Profile
sf::view and FBO's
« on: July 29, 2009, 02:25:04 am »
I have been trying to intermingle sfml calls with opengl calls on FBO's and they work so long as the FBO is the same size as the screen. Mostly I want to be able to use sf::string to an FBO of some size other then whatever the screen is set to.  I am guessing that i am not setting up the sf::View correctly but after much experimentation I though it might be worthwhile to ask.

I will note that i am using the GL_TEXTURE_RECTANGLE_ARB extension.

Code: [Select]

class GuiImage
{
private:
GLuint FrameObjectId;
GLuint TextureObjectId;

GLuint Width,Height;

public:
GuiImage(GLuint w, GLuint h) :
 Width(w), Height(h), FrameObjectId(0), TextureObjectId(0)
{
glGenFramebuffersEXT(1,&FrameObjectId);
glGenTextures(1,&TextureObjectId);
glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId);

glTexImage2D(
GL_TEXTURE_RECTANGLE_ARB,
0, GL_RGBA8,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,FrameObjectId  );

glFramebufferTexture2DEXT(
GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId,0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
};

~GuiImage()
{
glDeleteFramebuffersEXT(1,&FrameObjectId);
glDeleteTextures(1,&TextureObjectId);
};

void SetActive( bool active)
{
if(active)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,FrameObjectId  );

glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluOrtho2D(0,Width,Height, 0);
glMatrixMode(GL_MODELVIEW);
glColor4f(1.f,1.f,1.f,1.f);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

}
else
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
};

sf::View GetView( void )
{
//sf::View myview(
// sf::FloatRect(0.f,0.f,Width,Height));
sf::View myview(
sf::Vector2f(Width/2,Height/2),
sf::Vector2f(Width/2,Height/2));
return myview;
};

void Bind( void )
{
glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(err != 0x8CD5 )
std::cout<<"error using fbo! "<<err<<std::endl;
};

GLuint GetWidthi() const
{
return Width;
};

GLuint GetHeighti() const
{
return Height;
};

GLfloat GetWidthf() const
{
return static_cast<GLfloat>(Width);
};

GLfloat GetHeightf() const
{
return static_cast<GLfloat>(Height);
};

};

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::view and FBO's
« Reply #1 on: July 29, 2009, 07:50:39 am »
What happens when it doesn't work? Did you take a look at the sfml2 branch on SVN? The RenderImage class uses FBOs, it may give you some hints.
Laurent Gomila - SFML developer

luminous

  • Newbie
  • *
  • Posts: 8
    • View Profile
sf::view and FBO's
« Reply #2 on: July 29, 2009, 09:09:09 am »
A gave sfml 2.0 another read through just to be sure. I am pretty sure it is the call to glViewport in the RenderWindow.Draw function. the Text will show up distorted ether to tall or to fat and the positions seem to be off. if the fbo is small enough say 100x100  nothing will show on it with
sf::View view(sf::Vector2f(50.f,50.f),sf::Vector2f(50.f,50.f)); however  a view port of sf::View view(sf::Vector2f(400.f,100.f),sf::Vector2f(400.f,400.f)); almost correctly but distorted to be to large..

If i do something to get around sfml setting the matrix up like this.
Code: [Select]

class BadPracticeString : public sf::String
{
public:
BadPracticeString() : sf::String()
{};
void Draw2(sf::RenderTarget &App)
{

Render(App);
};
};

and then setup the matrix/blend mode etc... manually it seems to work correctly with any size FBO.

Might just have to wait for sfml 2.0 maybe =)

*note class named as such so no one gets the idea that that practice is a good idea......

luminous

  • Newbie
  • *
  • Posts: 8
    • View Profile
sf::view and FBO's
« Reply #3 on: August 11, 2009, 11:12:05 am »
ok i have found a work around, its not perfect but I don't have to maintain any changes to sfml or do anything to hackish.

I am using an FBO the same size as the screen, and then using glCopyTexImage2D to get the texture i want to use. its less then efficient but it works =). anyway i suppose i will post the code i used todo this.

Code: [Select]

// GuiImage.h

class GuiImage
{
private:
GLuint TextureObjectId;

static GLuint FrameObjectId;
static GLuint FBOTextureId;
GLuint Width,Height;

public:
GuiImage(sf::RenderWindow &App,GLuint w, GLuint h);

~GuiImage();

void SetActive( bool active);
void Update( sf::RenderWindow &App );
void Bind( void );
};


and

Code: [Select]

// GuiImage.cpp


GLuint GuiImage::FrameObjectId = 0;
GLuint GuiImage::FBOTextureId = 0;

GuiImage::GuiImage(sf::RenderWindow &App,GLuint w, GLuint h) :
  Width(w), Height(h), TextureObjectId(0)
{
glGenTextures(1,&TextureObjectId);

glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId);

glTexImage2D(
GL_TEXTURE_RECTANGLE_ARB,
0, GL_RGBA8,Width,Height,0,GL_RGBA8,GL_UNSIGNED_BYTE,0);

if(FrameObjectId == 0)
{
glGenFramebuffersEXT(1,&FrameObjectId);
glGenTextures(1,&FBOTextureId);

glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
FBOTextureId);

glTexImage2D(
GL_TEXTURE_RECTANGLE_ARB,
0, GL_RGBA8,
App.GetWidth(),App.GetHeight(),
0,GL_RGBA,GL_UNSIGNED_BYTE,0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,FrameObjectId  );

glFramebufferTexture2DEXT(
GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_RECTANGLE_ARB,
FBOTextureId,0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
};
};

GuiImage::~GuiImage()
{
glDeleteTextures(1,&TextureObjectId);
};

void GuiImage::SetActive( bool active )
{
if(active)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,FrameObjectId  );

}
else
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
};

void GuiImage::Update( sf::RenderWindow &App )
{
glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glCopyTexImage2D(
GL_TEXTURE_RECTANGLE_ARB, //target
        0,                         //level
        GL_RGBA8,                  //internal format
        0,
App.GetHeight() - Height,
        Width,
App.GetHeight(),
        0);
glDisable(GL_TEXTURE_RECTANGLE_ARB);
};

void GuiImage::Bind( void )
{
glBindTexture(
GL_TEXTURE_RECTANGLE_ARB,
TextureObjectId);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(err != 0x8CD5 )
std::cout<<"error using fbo! "<<err<<std::endl;
};