PDA

View Full Version : Clearing integer textures



jonathandup
07-13-2010, 10:08 AM
Hi,
I'm using a texture to store integer indices for a particle system (I'm using unsigned short integers).
I need to clear it before every update (using an fbo). But I can't use glClear, so should I use a specific shader program before the update or switch back to floating point data and use glclear again, or is there perhaps another way ? What's the fastest technique?

Thanks :)

DmitryM
07-13-2010, 10:36 AM
use glClearBuffer*() instead of glClear()

jonathandup
07-13-2010, 10:39 AM
I hadn't seen this function in the specs :o , thanks a lot ^^

jonathandup
07-13-2010, 11:23 AM
Well my application crashes with the ClearBuffer call... Anything wrong with my code ?


glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT4);

GLuint clearcolor[] = {0,0,0,0};
glClearBufferuiv(GL_COLOR, 0, clearcolor);

// texture generation
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA16I,
GRID_WIDTH * GRID_DEPTH_SQRT,
GRID_HEIGHT * GRID_DEPTH_SQRT,
0,
GL_RGBA,
GL_UNSIGNED_SHORT,
0 );



I'm using an Ati 5450 with ubuntu lucid and catalyst 10.6

wien
07-13-2010, 11:56 AM
You'll need a GL3.0 context (or greater) in order to use glClearBuffer. I'm guessing you don't?

jonathandup
07-14-2010, 04:38 AM
I do :) (I'm using the gl3 header)

jonathandup
07-14-2010, 05:55 AM
Okay here's a simple program using the functions I'm having problems with (requires sdl1.3):


#include <string>
#include <iostream>
#include <SDL.h>
#define GL3_PROTOTYPES 1
#include "gl3.h"

#define PROGRAM_NAME "GL3"

#define PROGRAM_WIDTH 400
#define PROGRAM_HEIGHT 300

#define TEXTURE_GRID 0
#define TEXTURE_COUNT 1

// gl resources
GLuint fbo = 0;
GLuint textures[TEXTURE_COUNT]; // textures

void build()
{
glDisable(GL_DEPTH_TEST);
//////////////////////////////////
// textures
glGenTextures(TEXTURE_COUNT, textures);

// spatial grid
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_GRID]);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

glTexImage2D( GL_TEXTURE_2D,
0,
// GL_RGBA32F,
GL_RGBA16UI,
PROGRAM_WIDTH,
PROGRAM_HEIGHT,
0,
GL_RGBA,
// GL_FLOAT,
GL_UNSIGNED_SHORT,
0 ); // no data sent, alloc only

glBindTexture(GL_TEXTURE_2D, 0);
//////////////////////////////////
// fbo + rbo (holds depth buffer ?)
glGenFramebuffers(1, &amp;fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// bind textures to fbo.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[TEXTURE_GRID],0);
glDrawBuffer(GL_COLOR_ATTACHMENT1);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE:
std::cout << "Framebuffer complete." << std::endl;
break;

case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl;
break;

case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl;
break;


case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl;
break;

case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl;
break;

case GL_FRAMEBUFFER_UNSUPPORTED:
std::cout << "[ERROR] Unsupported by FBO implementation." << std::endl;
break;

default:
std::cout << "[ERROR] Unknow error." << std::endl;
break;
}

// release fbo
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

// draw final result
void draw()
{
glClear(GL_COLOR_BUFFER_BIT);

glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glDrawBuffer(GL_COLOR_ATTACHMENT1);
glReadBuffer(GL_COLOR_ATTACHMENT1);
// GLfloat clearcolor[] = {0,0.5,0,0};
GLuint clearcolor[] = {0,1,0,0};
// glClearBufferfv(GL_COLOR, GL_COLOR_ATTACHMENT1, clearcolor);
glClearBufferuiv(GL_COLOR, GL_COLOR_ATTACHMENT1, clearcolor);
// std::cout << glGetError() << "\n";

glBindFramebuffer(GL_FRAMEBUFFER, 0);

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

glBlitFramebuffer( 0,0,PROGRAM_WIDTH,PROGRAM_HEIGHT,
0,0,PROGRAM_WIDTH,PROGRAM_HEIGHT,
GL_COLOR_BUFFER_BIT, GL_LINEAR
);
// std::cout << glGetError() << "\n";
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// std::cout << "\n";
}

void clean()
{
glDeleteFramebuffers(1, &amp;fbo);

glDeleteTextures(TEXTURE_COUNT, textures);
}

/* A simple function that prints a message, the error code returned by SDL,
* and quits the application */
void sdldie(std::string msg)
{
printf("%s: %s\n", msg.c_str(), SDL_GetError());
SDL_Quit();
exit(1);
}

/* Our program's entry point */
int main(int argc, char *argv[])
{
SDL_WindowID mainwindow; /* Our window handle */
SDL_GLContext maincontext; /* Our opengl context handle */

if (SDL_Init(SDL_INIT_VIDEO) < 0) /* Initialize SDL's Video subsystem */
sdldie("Unable to initialize SDL"); /* Or die on error */

/* Request an opengl 3.2 context.
* SDL doesn't have the ability to choose which profile at this time of writing,
* but it should default to the core profile */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);


/* Turn on double buffering with a 24bit Z buffer.
* You may need to change this to 16 or 32 for your system */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

/* Create our window centered resolution */
mainwindow = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
PROGRAM_WIDTH, PROGRAM_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if (!mainwindow) /* Die if creation failed */
sdldie("Unable to create window");


/* Create our opengl context and attach it to our window */
maincontext = SDL_GL_CreateContext(mainwindow);

/* This makes our buffer swap syncronized with the monitor's vertical refresh */
// 0 not , 1 sync'd
SDL_GL_SetSwapInterval(0);

build();

bool loop = true;

while (loop)
{
SDL_Event event;
while (SDL_PollEvent(&amp;event))
{
// check for messages
switch (event.type)
{
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
loop = false;
}
break;

default :
break;
}

}

draw();

/* Swap our back buffer to the front */
SDL_GL_SwapWindow(mainwindow);

/* Wait 1 milliseconds */
SDL_Delay(1);
}

/* Delete our opengl context, destroy our window, and shutdown SDL */
SDL_GL_DeleteContext(maincontext);
SDL_DestroyWindow(mainwindow);
SDL_Quit();

clean();

return 0;
}

The program works when I use floating point format for the texture, but with the integer format I get an error : the frame buffer is incomplete : the texture is not attached to the fbo. But the format is compatible from the specs... Am I missing something ?

kRogue
07-14-2010, 02:02 PM
Before attaching the integer texture buffer, you will need to set its filtering correctly. The GL spec has the default filtering be GL_LINEAR on the magnification and GL_LINEAR_MIPMAP_NEAREST on the minification filter. Set both filters to GL_NEAREST before attaching the integer texture to the FBO.

jonathandup
07-15-2010, 01:51 AM
I've set the mag/minification filters to nearest but I still get the GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT error ...

jonathandup
07-15-2010, 02:08 AM
The format is not GL_RGBA but GL_RGBA_INTEGER!
Finally got it to work! Thanks for your help :)