PDA

View Full Version : Read in an integer texture in fragment shader?



Gomu.Wang
05-28-2010, 12:33 AM
Hi everyone~

I've have an integer texture(internal format is GL_RGBA32I,format is GL_RGBA_INTEGER and type is GL_INT),

now I have a fragment shader wanna read data from this integer texture and output as an user-defined fragment data.

Here is the shader code:



varying out ivec4 FragOut;
uniform isampler2D Tex1;

void main(void) {
ivec4 texel = ivec4(texture2D(Tex1,gl_TexCoord[0].st));
//gl_FragColor = texel;

FragOut = texel;
}


I used isampler2D, but cannot get right data output. What's happening? :confused:

Thank you~

Gomu.Wang
05-28-2010, 12:43 AM
For more clear, past OpenGL codes here. The function is simple:
Two integer textures, one(fboTex) for FBO rendering and another(imageTex) for data input.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#include <windows.h>
#include <GL/glut.h>

#include <textfile.h>

#include <iostream>

typedef unsigned char BYTE;

GLhandleARB VertexShader, FragShader, Program;
GLint vertCompiled, fragCompiled;
GLint linked;

int installShaders(const GLcharARB* V_shader, const GLcharARB* F_shader)
{
VertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER);
FragShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);

glShaderSourceARB(VertexShader, 1, &amp;V_shader, NULL);
glShaderSourceARB(FragShader, 1, &amp;F_shader, NULL);

glCompileShader(VertexShader);
glGetObjectParameterivARB(VertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &amp;vertCompiled);

glCompileShader(FragShader);
glGetObjectParameterivARB(FragShader, GL_OBJECT_COMPILE_STATUS_ARB, &amp;fragCompiled);

if(!vertCompiled || !fragCompiled)
{
std::cout<<"shader compile error!"<<std::endl;
return 0;
}

Program = glCreateProgramObjectARB();
glAttachObjectARB(Program, VertexShader);
glAttachObjectARB(Program, FragShader);

glBindFragDataLocationEXT(Program, 0, "FragOut");

glLinkProgram(Program);
glGetObjectParameterivARB(Program, GL_OBJECT_LINK_STATUS_ARB, &amp;linked);

if(!linked)
{
std::cout<<"shader link error!"<<std::endl;
return 0;
}

return 1;
}

int main(int argc, char **argv) {
const GLchar* V_shader = textFileRead("VS.vertex");
const GLchar* F_shader = textFileRead("FS.frag");

// &amp;#36825;&amp;#37324;&amp;#22768;&amp;#26126;&amp;#32441;&amp;#29702;&amp;# 30340;&amp;#22823;&amp;#23567;&amp;#20026;&amp;#65306;teSize;&amp;#327 80;&amp;#25968;&amp;#32452;&amp;#30340;&amp;#22823;&amp;#23567;&amp;#23601 ;&amp;#24517;&amp;#39035;&amp;#26159;texSize*texSize*4
int texSize = 4;

int i;

int result[4*texSize*texSize];

int* data = (int*)malloc(4*2*2*sizeof(int));

data[0] = 3;
data[1] = 3;
data[2] = 1;
data[3] = 214;

data[4] = 1;
data[5] = 0;
data[6] = 1;
data[7] = 2;

data[8] = 1;
data[9] = 1;
data[10] = 1;
data[11] = 2;

data[12] = 0;
data[13] = 1;
data[14] = 1;
data[15] = 2;


// Initialize OpenGL
//glutInit (&amp;argc, argv);
glutCreateWindow("TEST1");
glewInit();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,texSize,0.0,texSize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,texSize,texSize);

// create a FBO
GLuint fb;
glGenFramebuffersEXT(1,&amp;fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fb);

// the first texture, used for FBO
GLuint fboTex, imageTex;
glGenTextures (1, &amp;fboTex);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB,fboTex);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGBA32I ,
texSize,texSize,0,GL_RGBA_INTEGER,GL_INT,0);
glTexImage2D(

// the second texture, used for texture looking up
glGenTextures (1, &amp;imageTex);
glBindTexture(GL_TEXTURE_2D,imageTex);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32I,
2,2,0,GL_RGBA_INTEGER,GL_INT,data);


//create render buffer
GLuint rboId;
glGenRenderbuffersEXT(1, &amp;rboId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texSize, texSize);

//bind render buffer and texture buffer to FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_CO LOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_ARB,fboTe x,0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ ATTACHMENT,GL_RENDERBUFFER,rboId);

// install shaders
if(installShaders(V_shader, F_shader))
{
glUseProgramObjectARB(Program);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, imageTex);
glUniform1i(glGetUniformLocation(Program, "Tex1"), 0);
}

glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glClearColor(0.7, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, fboTex);
glColor4f(0.1,0.1,0.1,0.1);
glBegin(GL_POINTS);
glTexCoord2i(0,0);
glVertex2i(0,0);
glTexCoord2i(1,0);
glVertex2i(1,0);
glTexCoord2i(1,1);
glVertex2i(1,1);
glTexCoord2i(0,1);
glVertex2i(0,1);
glEnd();


// read back data and print
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, texSize, texSize,GL_RGBA_INTEGER,GL_INT,result);

for (i=0; i<texSize*texSize*4; i++)
printf("%d\n",result[i]);


free(data);
glDeleteFramebuffersEXT (1,&amp;fb);
glDeleteTextures(1,&amp;fboTex);

return 0;
}

Gomu.Wang
05-28-2010, 03:18 AM
Problem solved. Post here to remind beginners:

To read integer texture data, we must add:

#extension GL_EXT_gpu_shader4 : require

at the beginning of shaders.