PDA

View Full Version : [GLSL] Texture2D in fragment shader



GloWondub
04-09-2010, 06:08 AM
Hello
I have posted before a simmillar post about the same topic.
But it was too unclear so i've write a new programm to explicitly show mhow my implementation problem.

I'm cuyrrentluy coding depth peeling, in order to doing that i have to transfer texture into my fragment shader.

so i 've worte a programm how is doint only that :

1. Initialize openGL context (SDL)
2. initialize glew
3. Create and compile myFragment shader
4. initialize and fill a texutre with data
5. get the location of my texture in the shader

loop(

a. activate shader
b. transfer tex to shader
c. draw
d. desactivate shader
e. swap buffer

)

that's what my programm do....but one things.
Anything i'm triyng to do with the texture in the shader ALWAYS give me a 0.

here i try to colorize all pixels with a ugly white (R=100, g=100, b=100, a=100), but i get it all dark.

i've tried with different fonctions ( like TexelFetch, or TextureSize) and always gettin 0.

Here is my code ( not so long, please take the time to look at it).


#include <stdio.h>

#include <stdlib.h>

#include <string.h>



#include <SDL/SDL.h>



#include <GL/glew.h>





/* dimensions de la fenetre */

#define W 256

#define H 256





void transferToTexture (GLubyte* data, GLuint texID, int width,int height);
void texRGBASpeDisplay(GLuint tex,int width, int height);
void ShutDown(int);
void createTexParam();
void printProgramInfoLog(GLuint obj);
void printShaderInfoLog(GLuint obj);
void checkGLErrors (const char *label);
void initTex(GLuint tex,int width, int height);

GLuint initGLSL(void);

struct struct_textureParameters {
GLenum texTarget;
GLenum texInternalFormat;
GLenum texFormat;
GLenum dataFormat;
char* shader_source;
}textureParameters;





int main(void)

{

int loop = 1; /* booleen du 'main loop' */

SDL_Event ev; /* structure d'evenement(s) SDL */

GLuint program; /* notre program */
GLuint texture;
GLuint texLoc;

int use_shaders = 0;/* booleen indiquant si l'on utilise les shaders */
int width = W;
int height = H;



/* initialisation de la SDL en mode OpenGL */

if(SDL_Init(SDL_INIT_VIDEO) < 0)

exit(EXIT_FAILURE);

if(SDL_SetVideoMode(width, height, 32, SDL_OPENGL) == NULL)

ShutDown(EXIT_FAILURE);



/* nom de la fenetre */

SDL_WM_SetCaption("GLSL Shaders", NULL);



/* initialisation de glew */

glewInit();

createTexParam();
glEnable( textureParameters.texTarget);
initTex(texture,width,height);





/* chargement de notre program */

program=initGLSL();
if(program == 0)

ShutDown(EXIT_FAILURE);
// Get location of the texture samplers for future use

GLubyte * data;
data=(GLubyte*)malloc(width*height*4*sizeof(GLubyt e));
int i;
for(i=0;i<(width*height*4);i++)
{
data[i]=100;
}
transferToTexture (data, texture, width, height);
texRGBASpeDisplay(texture,width, height);

glUseProgram(program);
texLoc = glGetUniformLocation(program, "tex");
printf("loc : %u",texLoc);
glUseProgram(0);








/* boucle d'affichage principale */

while(loop)

{

/* recuperation d'un evenement */

SDL_WaitEvent(&amp;ev);



/* analyse */

if(ev.type == SDL_QUIT)

loop = 0;

else if(ev.type == SDL_KEYDOWN)

use_shaders = !use_shaders;



glClear(GL_COLOR_BUFFER_BIT);



/* on active notre program */

if(use_shaders)
{

glUseProgram(program);
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureParameters.texTarget,texture) ;
glUniform1i(texLoc,1);
glBindTexture(textureParameters.texTarget,0);
}





/* a partir de la, tous les rendus qui seront effectues seront

affectes par le program */



glBegin(GL_TRIANGLES);

glColor3f(1.0, 0.0, 0.0); glVertex2f(0.9, -0.9);

glColor3f(0.0, 1.0, 0.0); glVertex2f(-0.9, -0.9);

glColor3f(0.0, 0.0, 1.0); glVertex2f(0.0, 0.9);

glEnd();



/* on desactive */

if(use_shaders)

glUseProgram(0);



/* on flip les tampons */

glFlush();

SDL_GL_SwapBuffers();

}



ShutDown(EXIT_SUCCESS);



return EXIT_SUCCESS;

}


void createTexParam(){
textureParameters.texTarget = GL_TEXTURE_2D;
textureParameters.texInternalFormat = GL_RGBA8;
textureParameters.texFormat = GL_RGBA;
textureParameters.dataFormat = GL_UNSIGNED_BYTE;
textureParameters.shader_source = \
// "#version 130 \n"
"uniform sampler2D tex;" \
"void main(void) { " \
//" gl_FragColor = texelFetch(tex, ivec2(2,2),0);"
"gl_FragColor = texture2D(tex, gl_FragCoord.xy);"\
"}";
}





void ShutDown(int code)

{

SDL_Quit();

exit(code);

}
void transferToTexture (GLubyte* data, GLuint texID,int width,int height) {
// version (a): HW-accelerated on NVIDIA
glBindTexture(textureParameters.texTarget, texID);
glTexImage2D(textureParameters.texTarget,0,texture Parameters.texInternalFormat,width,height,0,textur eParameters.texFormat,textureParameters.dataFormat ,data);
}
GLuint initGLSL(void) {
GLuint program;
GLuint fragmentShader;
// create program object
program = glCreateProgram();
// create shader object (fragment shader)
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER_ARB);
// set source for shader
const GLchar* source = textureParameters.shader_source;
glShaderSource(fragmentShader, 1, &amp;source, NULL);
// compile shader
glCompileShader(fragmentShader);
// check for errors
printShaderInfoLog(fragmentShader);
// attach shader to program
glAttachShader (program, fragmentShader);
// link into full program, use fixed function vertex pipeline
glLinkProgram(program);
// check for errors
printProgramInfoLog(program);
checkGLErrors("render(2)");
return program;
}

void texRGBASpeDisplay(GLuint tex,int width, int height)
{
int i;
GLubyte* data;
data = malloc(width*height*4*sizeof(GLubyte));
//printf("BEGIN_RESULTS ONLY_FIRST COLOR %s \n",name);
glBindTexture(textureParameters.texTarget, tex);
//glReadBuffer(attachmentpoints[readTex]);
//glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, textureParameters.texInternalFormat, 0,0,texSize,texSize,0);
glGetTexImage(textureParameters.texTarget, 0,textureParameters.texFormat,textureParameters.da taFormat, data);
printf("DISP\n");
for (i=0; i<(width*height*4); i+=4)
{
printf("row =%u :",(i/4)/width);
printf("column =%u :",(i/4)%width);
printf("r:%i",data[i]);
printf("g:%i",data[i+1]);
printf("b:%i",data[i+2]);
printf("a:%i\n",data[i+3]);
}
free(data);
glBindTexture(textureParameters.texTarget, 0 );
}

void printProgramInfoLog(GLuint obj) {
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLength);
if (infologLength > 1) {
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(obj, infologLength, &amp;charsWritten, infoLog);
printf(infoLog);
printf("\n");
free(infoLog);
}
}
void printShaderInfoLog(GLuint obj) {
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLength);
if (infologLength > 1) {
infoLog = (char *)malloc(infologLength);
glGetShaderInfoLog(obj, infologLength, &amp;charsWritten, infoLog);
printf(infoLog);
printf("\n");
free(infoLog);
}
}

void checkGLErrors (const char *label) {
GLenum errCode;
const GLubyte *errStr;

if ((errCode = glGetError()) != GL_NO_ERROR) {
errStr = gluErrorString(errCode);
printf("OpenGL ERROR: ");
printf((char*)errStr);
printf("(Label: ");
printf(label);
printf(")\n.");
}
}
void initTex(GLuint tex,int width, int height)
{
glGenTextures(1, &amp;tex);

glBindTexture(textureParameters.texTarget, tex);

glTexParameterf(textureParameters.texTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterf(textureParameters.texTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexParameterf(textureParameters.texTarget, GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glTexParameterf(textureParameters.texTarget, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(textureParameters.texTarget, 0, textureParameters.texInternalFormat, W, H, 0, textureParameters.texFormat, textureParameters.dataFormat, NULL);
}



Excpet texture, all shader stuff are good (i can manually fill my pixels with : "gl_FragColor = ec4(100,100,100,100);"\)

And my texture contain really the values i want to ( i check with a RGBASpeDisplay fonction )

My code is also free of Shader compilation error, or OpenGL error.

So here is a archive with code+makefile if anyone want to easily try it.
codeArchive (http://fex.insa-lyon.fr/get?k=kDnL68Uelvp1vBFyMj)

i've wasted for now one week on this problem. the only way i've found to make it worked is to copy my GL_TEXTURE_2D in a GL_TEXTURE_RECTANGLE_ARB ( i can give the code if you want ), but it's unoptimized because of GPU->CPU->GPU copy.

help !

overlay
04-09-2010, 07:12 AM
texture coordinates in a 2D texture are between 0 and 1.
You have to divide gl_FragCoord.x by the width of the texture (or screen, there should be the same value) and divide gl_FragCoord.x by the height of the texture.

You have to pass width and height as uniform variables.

vec2 tcoord=vec2(gl_FragCoord.x/width,gl_FragCoord.y);

"gl_FragColor = texture2D(tex, tcoord);"\

GloWondub
04-09-2010, 07:47 AM
so i try this :

"gl_FragColor = texture2D(tex, vec2(0.5,0.5));"\

and this

"gl_FragColor = texture2D(tex, vec2(0,0));"\

and nothing change

the problem is not here. but i will modify this.

GloWondub
04-12-2010, 04:10 AM
Here is a modify code.

I've some problem with binding textures like some people say in other forum.
I've modify it but, nothing change.

Here is my new code (see shader+binding close to unform1i)

and an archive
codeArchive (http://fex.insa-lyon.fr/get?k=uYG8euzHcdn7uzDs2J5)



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

/* dimensions de la fenetre */
#define W 256
#define H 256

void transferToTexture (GLubyte* data, GLuint texID, int width,int height);
void texRGBASpeDisplay(GLuint tex,int width, int height);
void ShutDown(int);
void createTexParam();
void printProgramInfoLog(GLuint obj);
void printShaderInfoLog(GLuint obj);
void checkGLErrors (const char *label);
void initTex(GLuint tex,int width, int height);
GLuint initGLSL(void);

struct struct_textureParameters {
GLenum texTarget;
GLenum texInternalFormat;
GLenum texFormat;
GLenum dataFormat;
char* shader_source;
}textureParameters;

int main(void)
{
int loop = 1; /* booleen du 'main loop' */
SDL_Event ev; /* structure d'evenement(s) SDL */
GLuint program; /* notre program */
GLuint texture;
GLuint texLoc;

int use_shaders = 0;/* booleen indiquant si l'on utilise les shaders */
int width = W;
int height = H;
GLuint widthLoc;
GLuint heightLoc;

/* initialisation de la SDL en mode OpenGL */
if(SDL_Init(SDL_INIT_VIDEO) < 0)
exit(EXIT_FAILURE);

if(SDL_SetVideoMode(width, height, 32, SDL_OPENGL) == NULL)
ShutDown(EXIT_FAILURE);

/* nom de la fenetre */
SDL_WM_SetCaption("GLSL Shaders", NULL);

/* initialisation de glew */
glewInit();

createTexParam();
glEnable( textureParameters.texTarget);
initTex(texture,width,height);

/* chargement de notre program */
program=initGLSL();
if(program == 0)

ShutDown(EXIT_FAILURE);
// Get location of the texture samplers for future use

GLubyte * data;
data=(GLubyte*)malloc(width*height*4*sizeof(GLubyt e));
int i;
for(i=0;i<(width*height*4);i++)
{
data[i]=100;
}
transferToTexture (data, texture, width, height);
//texRGBASpeDisplay(texture,width, height);

glUseProgram(program);
texLoc = glGetUniformLocation(program, "tex");
widthLoc = glGetUniformLocation(program, "width");
heightLoc = glGetUniformLocation(program, "height");
printf("loc : %u",texLoc);
printf("loc : %u",widthLoc);
printf("loc : %u",heightLoc);
glUseProgram(0);

/* boucle d'affichage principale */
while(loop)
{

/* recuperation d'un evenement */
SDL_WaitEvent(&amp;ev);

/* analyse */
if(ev.type == SDL_QUIT)
loop = 0;
else if(ev.type == SDL_KEYDOWN)
use_shaders = !use_shaders;

glClear(GL_COLOR_BUFFER_BIT);

/* on active notre program */
if(use_shaders)
{
glUseProgram(program);
glActiveTexture(GL_TEXTURE1);
//glBindTexture(textureParameters.texTarget,texture) ;
glUniform1i(texLoc,1);
glUniform1i(widthLoc,width);
glUniform1i(heightLoc,height);
//glBindTexture(textureParameters.texTarget,0);
}
/* a partir de la, tous les rendus qui seront effectues seront
affectes par le program */
glBindTexture(textureParameters.texTarget,texture) ;
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0); glVertex2f(0.9, -0.9);
glColor3f(0.0, 1.0, 0.0); glVertex2f(-0.9, -0.9);
glColor3f(0.0, 0.0, 1.0); glVertex2f(0.0, 0.9);
glEnd();

/* on desactive */
if(use_shaders)
glUseProgram(0);

/* on flip les tampons */
glFlush();
SDL_GL_SwapBuffers();
}
ShutDown(EXIT_SUCCESS);
return EXIT_SUCCESS;
}

void createTexParam(){
textureParameters.texTarget = GL_TEXTURE_2D;
textureParameters.texInternalFormat = GL_RGBA8;
textureParameters.texFormat = GL_RGBA;
textureParameters.dataFormat = GL_UNSIGNED_BYTE;
textureParameters.shader_source = \
// "#version 130 \n"
"uniform int width;" \
"uniform int height;" \
"uniform sampler2D tex;" \
"void main(void) { " \
//" gl_FragColor = texelFetch(tex, ivec2(2,2),0);"
//"gl_FragColor = texture2D(tex, gl_TexCoord[0].st);"
"vec2 texCoord;"\
"float temp1;"\
"float temp2;"\
"temp1=gl_FragCoord.x;"\
"texCoord.x = temp1/width;"\
"temp2=gl_FragCoord.y;"\
"texCoord.y = temp2/height;"\
"gl_FragColor = texture2D(tex, texCoord);"\
//"gl_FragColor = gl_Color/vec4(texCoord,texCoord);"
"}";
}

void ShutDown(int code)
{
SDL_Quit();
exit(code);
}
void transferToTexture (GLubyte* data, GLuint texID,int width,int height) {
// version (a): HW-accelerated on NVIDIA
glBindTexture(textureParameters.texTarget, texID);
glTexImage2D(textureParameters.texTarget,0,texture Parameters.texInternalFormat,width,height,0,textur eParameters.texFormat,textureParameters.dataFormat ,data);
}
GLuint initGLSL(void) {
GLuint program;
GLuint fragmentShader;
// create program object
program = glCreateProgram();
// create shader object (fragment shader)
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER_ARB);
// set source for shader
const GLchar* source = textureParameters.shader_source;
glShaderSource(fragmentShader, 1, &amp;source, NULL);
// compile shader
glCompileShader(fragmentShader);
// check for errors
printShaderInfoLog(fragmentShader);
// attach shader to program
glAttachShader (program, fragmentShader);
// link into full program, use fixed function vertex pipeline
glLinkProgram(program);
// check for errors
printProgramInfoLog(program);
checkGLErrors("render(2)");
return program;
}

void texRGBASpeDisplay(GLuint tex,int width, int height)
{
int i;
GLubyte* data;
data = malloc(width*height*4*sizeof(GLubyte));
//printf("BEGIN_RESULTS ONLY_FIRST COLOR %s \n",name);
glBindTexture(textureParameters.texTarget, tex);
//glReadBuffer(attachmentpoints[readTex]);
//glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, textureParameters.texInternalFormat, 0,0,texSize,texSize,0);
glGetTexImage(textureParameters.texTarget, 0,textureParameters.texFormat,textureParameters.da taFormat, data);
printf("DISP\n");
for (i=0; i<(width*height*4); i+=4)
{
printf("row =%u :",(i/4)/width);
printf("column =%u :",(i/4)%width);
printf("r:%i",data[i]);
printf("g:%i",data[i+1]);
printf("b:%i",data[i+2]);
printf("a:%i\n",data[i+3]);
}
free(data);
glBindTexture(textureParameters.texTarget, 0 );
}

void printProgramInfoLog(GLuint obj) {
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLength);
if (infologLength > 1) {
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(obj, infologLength, &amp;charsWritten, infoLog);
printf(infoLog);
printf("\n");
free(infoLog);
}
}
void printShaderInfoLog(GLuint obj) {
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &amp;infologLength);
if (infologLength > 1) {
infoLog = (char *)malloc(infologLength);
glGetShaderInfoLog(obj, infologLength, &amp;charsWritten, infoLog);
printf(infoLog);
printf("\n");
free(infoLog);
}
}

void checkGLErrors (const char *label) {
GLenum errCode;
const GLubyte *errStr;

if ((errCode = glGetError()) != GL_NO_ERROR) {
errStr = gluErrorString(errCode);
printf("OpenGL ERROR: ");
printf((char*)errStr);
printf("(Label: ");
printf(label);
printf(")\n.");
}
}
void initTex(GLuint tex,int width, int height)
{
glGenTextures(1, &amp;tex);

glBindTexture(textureParameters.texTarget, tex);
glTexParameterf(textureParameters.texTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(textureParameters.texTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(textureParameters.texTarget, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(textureParameters.texTarget, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(textureParameters.texTarget, 0, textureParameters.texInternalFormat, W, H, 0, textureParameters.texFormat, textureParameters.dataFormat, NULL);
}




I will now searching to use only ARB RECT texture.

GloWondub
04-12-2010, 05:56 AM
make it work using :

textureParameters.texTarget = GL_TEXTURE_RECTANGLE_ARB;

thx for help.