texture look-up using ATI_fragment_shader

Greetings,
I’m trying to implement a texture-palette using ATI_fragment_shader.
I have a new FireGL card.
For testing, I am trying to apply a 256-entry look-up table to a GL_UNSIGNED_BYTE luminance 2D texture.
All I get is a blank display, when I enable the shader.
I’d appreciate any suggestions.

I’ve included my code below:

simpleFragmentShader = glGenFragmentShadersATI(1);
glBindFragmentShaderATI (simpleFragmentShader);
glBeginFragmentShaderATI();

glSampleMapATI ( GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
glPassTexCoordATI(GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI);
// dummy operation to end the first pass (better way ?)
glColorFragmentOp1ATI (GL_MOV_ATI, GL_REG_2_ATI, GL_NONE, GL_NONE, GL_REG_3_ATI, GL_NONE, GL_NONE);

// Dependent texture read
glSampleMapATI ( GL_REG_1_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI);
glColorFragmentOp1ATI (GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_REG_1_ATI, GL_NONE, GL_NONE);

glEndFragmentShaderATI();

many thanks,
Maniam

Calling both glSampleMapATI and glPassTexCoordATI with a destination of GL_REG_0_ATI seems wrong. You should only be doing one of the two.

Originally posted by MalcolmB:
Calling both glSampleMapATI and glPassTexCoordATI with a destination of GL_REG_0_ATI seems wrong. You should only be doing one of the two.
I added that for this reason (ATI spec) :
" Note that in order to preserve the contents of a register from the first pass to the second, there must be a PassTexCoordATI instruction in the setup for the second pass that assigns that register to itself."

I moved the glPassTexCoordATI(GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI);
till after the (dummy) glColorFragmentOp1ATI() call.
It still doesn’t work.

You don’t want to preserve the value, you want to sample the texture. Therefore the glPassTexCoordATI() call shouldn’t be there.

Originally posted by Humus:
You don’t want to preserve the value, you want to sample the texture. Therefore the glPassTexCoordATI() call shouldn’t be there.
Thanks for clearing that up. I still can’t run it. I just found out that my card (ATI FireGL 3100) might not support ATI_fragment_shader. Is that the case? I’ll try to test on an older ATI card, as I’d like to support them too.

http://www.delphi3d.net/hardware/extsupport.php?extension=GL_ATI_fragment_shader

Originally posted by gdewan:
http://www.delphi3d.net/hardware/extsupport.php?extension=GL_ATI_fragment_shader
Well, GL_ATI_fragment_shader seems to be supported, according to the GL_EXTENSIONS string. So, I still have no idea why the shader doesn’t work.

printf("Supported extensions : %s
", glGetString(GL_EXTENSIONS));
(edited: I’m late!)

Have you downloaded ATi’s fragment shader example program ? This one should work, otherwise this means there’s something wrong with your configuration, be it driver version or anything.

Originally posted by vincoof:
[b]printf("Supported extensions : %s
", glGetString(GL_EXTENSIONS));
(edited: I’m late!)

Have you downloaded ATi’s fragment shader example program ? This one should work, otherwise this means there’s something wrong with your configuration, be it driver version or anything.[/b]
The ATI sample (using ARB_fragment_program) works fine. My ARB_fragment_program attempt didn’t work either (I started a new thread for that).
I couldn’t find an ATI sample that uses ATI_fragment_shader

This is my complete code:

#include <stdio.h>
#include <glut.h>
#include "ATIExtensions.h"

int width = 400;
int height = 400;
float distance = 0.0f;
float zoom = 60.0f;
GLuint nTex, nPalette, simpleFragmentShader;


void init()
{    
    // dependent texture
    glGenTextures(1, &nTex);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glBindTexture(GL_TEXTURE_2D, nTex);

    unsigned char pSlice[256*256], *ptr;
    ptr = pSlice;
    for(int i=0; i<256; ++i)
    {
        memset(ptr, i, 256);
        ptr += 256;
    }

    glTexImage2D(GL_TEXTURE_2D, 0, 1, 256, 256, 0,GL_LUMINANCE, GL_UNSIGNED_BYTE, (void*) pSlice);

    // texture palette
    glGenTextures(1, &nPalette);
    glActiveTextureARB( GL_TEXTURE1_ARB);
    glBindTexture( GL_TEXTURE_1D, nPalette);

    float pfLUT[256*4], *pPtr;
    pPtr = pfLUT;
    for(int l=0; l<256; ++l)
    {
        pPtr[0] = l < 128 ? 0.0 : 1.0;
        pPtr[1] = pPtr[2] = pPtr[3] = 1.0;
        pPtr += 4;
    }

    glTexImage1D(GL_TEXTURE_1D, 0, 4, 256, 0,GL_RGBA, GL_FLOAT, (void*) pfLUT);

    simpleFragmentShader = glGenFragmentShadersATI(1);
    glBindFragmentShaderATI(simpleFragmentShader);

    glBeginFragmentShaderATI();

    glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
    glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_2_ATI, GL_NONE, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE);
    glSampleMapATI(GL_REG_1_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI);
    glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE);    

    glEndFragmentShaderATI();
}


//////////////////////////////////////////////////
void drawModel()
{
   glEnable(GL_TEXTURE_2D);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   glColor3f(0,1,0);

    glActiveTextureARB(GL_TEXTURE0_ARB);
    glBindTexture(GL_TEXTURE_2D, nTex);

   glBegin(GL_QUADS); 
   glTexCoord2f(0, 0);
   glVertex2f(-.5, -.5);
   glTexCoord2f(1, 0);
   glVertex2f(.5, -.5);
   glTexCoord2f(1, 1);
   glVertex2f(.5, .5);
   glTexCoord2f(0, 1);
   glVertex2f(-.5, .5);  
   glEnd();
}

/////////////////////////////////////////////////
void draw()
{
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(zoom, width/height, distance/10.0f, distance*2.0f);

    glMatrixMode( GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -distance);
  
    glBindFragmentShaderATI(simpleFragmentShader);
    glEnable(GL_FRAGMENT_SHADER_ATI);

    drawModel();

    glDisable(GL_FRAGMENT_SHADER_ATI);
    glActiveTextureARB(GL_TEXTURE0_ARB);

    glutSwapBuffers();   
}


/////////////////////////////////////////////////
int main( int argc, char **argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
   glutInitWindowSize(width, height);
   glutCreateWindow("Simple Shader- ATI Fragment Shader");

   glutDisplayFunc(draw);
   glutIdleFunc(draw);
   
   SetupGL1_4();
   SetupATIExtensions();
   SetupARBExtensions();
  
   init();
 
   glutMainLoop();

   glDeleteFragmentShaderATI(simpleFragmentShader);
}
  

Please try this :
http://www.ati.com/developer/R8500PointlightShader.html
(full source code included)

Originally posted by vincoof:
Please try this :
http://www.ati.com/developer/R8500PointlightShader.html
(full source code included)

Thanks! The links to the old examples seem to have been removed, although the files are still there.

My shader worked once I added these:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

I thought this was the default state; apparently not!

My final shader code:
glBeginFragmentShaderATI();
// first pass
glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);
glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_1_ATI, GL_NONE, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE);
// second pass - dependent read
glSampleMapATI(GL_REG_1_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI);
glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE);
glEndFragmentShaderATI();

Maniam