Vertex/fragment shader: Really easy tutorial??

Hi
I’m actually searching for a real easy examle of code, using vertex/fragment shader.
It mean, e.g, draw a triangle and change the color of the pixel using vertex and fragment shader.
I saw a lot of things, but it’s usually more complex examples or publicity for vertex/fragment shader than real easy code example.
Thanks

P.S: I’m talking about GL_ARB_Fragment/Vertex_Program. Not about ATI_Vertex_Shader. It should work with Nvidia AND with ATI.

Here is a quick example that does nothing but pass position and color all the way through. It shows the API but not the use of the instruction set in any detail, the only instruction it uses is MOV. It does no transformation ignoring the matrices, it is as simple as it gets w.r.t. the actual vertex and fragment programs. Don’t forget to swapbuffers somewhere. It should be self explanatory, you shoule call init_extensions() with a valid context active and that will also compile the shaders. You can then use them in a draw routine, the sample draw routine provided should show a single red and white shaded triangle. This uses wglgetprocaddress, if you’re not on windows then substitute the appropriate call, the rest should work… you’ll need to include glext.h.

unsigned int VP_handle1;
unsigned int FP_handle1;
PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
PFNGLBINDPROGRAMARBPROC glBindProgramARB;
PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;

void draw_all( void )
{
    glClear(GL_COLOR_BUFFER_BIT);


	glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VP_handle1);
	glEnable(GL_VERTEX_PROGRAM_ARB);
	glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, FP_handle1);
	glEnable(GL_FRAGMENT_PROGRAM_ARB);

	glBegin(GL_TRIANGLES);
	glColor3f(1.0, 1.0, 1.0);
	glVertex3f(0.0f, 0.0f, 0.5f);
	glVertex3f(0.9f, 0.0f, 0.5f);
	glColor3f(1.0, 0.0, 0.0);
	glVertex3f(0.0f, 0.9f, 0.5f);
	glEnd();

	glDisable(GL_VERTEX_PROGRAM_ARB);
	glDisable(GL_FRAGMENT_PROGRAM_ARB);

	glFinish();	
}
int setup_shader(void)
{
	char vert_prog_str1[] = "!!ARBvp1.0 
\
								ATTRIB InPos = vertex.position; 
\
								ATTRIB InColor = vertex.color; 
\
								OUTPUT OutPos = result.position; 
\
								OUTPUT OutColor = result.color; 
\
								MOV OutPos, InPos; 
\
								MOV OutColor, InColor; 
\
								END";

	char frag_prog_str1[] = "!!ARBfp1.0 
\
								ATTRIB InColor = fragment.color; 
\
								OUTPUT OutColor = result.color; 
\
								MOV OutColor, InColor; 
\
								END";

	glGenProgramsARB(1,&VP_handle1);
	glBindProgramARB(GL_VERTEX_PROGRAM_ARB,VP_handle1);
	glProgramStringARB(GL_VERTEX_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,strlen(vert_prog_str1),vert_prog_str1);

	glGenProgramsARB(1,&FP_handle1);
	glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,FP_handle1);
	glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,strlen(frag_prog_str1),frag_prog_str1);

	return 1;
}


void init_extensions(void)
{
	char *ext_str = (char *)glGetString(GL_EXTENSIONS);

    if ( ext_str == NULL ) {
                // oops
		exit(1);
    }
	else if(strstr(ext_str, "ARB_vertex_program") && strstr(ext_str, "ARB_fragment_program"))
	{
		glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) wglGetProcAddress("glGenProgramsARB");
		glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)wglGetProcAddress("glProgramStringARB");
		glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)wglGetProcAddress("glBindProgramARB");
		glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)wglGetProcAddress("glDeleteProgramsARB");
		if(glGenProgramsARB && glProgramStringARB && glBindProgramARB && glDeleteProgramsARB )
		{
			glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
			setup_shader();
		}
		else
		{	
			//oops
		}
	}
	else
	{
		//oops
	}
}

Thanks. I will compare with my code.