vertex_program_arb usage?

basically I am trying to write a OpenGL3 compatible renderer, but since the Open Source radeon driver just supports OpenGL1.5 I have to use vp/fp instead of GLSL.

I already managed to write a simple shader and to load it. Now I want to push some external data into it like the Model-View-Matrix, which is the following in OpenGL3:

int loc = glGetUniformLocation(programObject, “name”);
glUniformMatrix4fv(loc, 1, GL_FALSE, identity);

I also would like to know whether there is a function closer to glVertexAttribPointer than glVertexPointer?

Generally I am looking for a tutorial which explains a vp/fp based render and also has some documentation for the assembly language.

Or if you have any other tips how to develop a OpenGL3 render with the OSS stack, they are welcome. Speed does not matter yet.

** Funcs you need:


glProgramStringARB
glGenProgramsARB
glBindProgramARB
glDeleteProgramsARB
glProgramLocalParameter4fARB
glProgramLocalParameter4fvARB
glProgramLocalParameters4fvEXT // very nifty, but not always available. Loop with glProgramLocalParameter4fvARB if not available

** compiler you need:
cgc
** parameters to the compiler:


paramsFP="-quiet -oglsl -profile arbfp1 -profileopts MaxDrawBuffers=4,NumTemps=32,MaxTexIndirections=4,MaxLocalParams=224";
paramsVP="-quiet -oglsl -profile arbvp1";

** how to code a shader:


uniform mat4 myMatrixProjection : C0;
uniform mat4 myMatrixModelView : C4;
uniform vec4 vtxColor0 : C8;
uniform float unif1 : C9;
uniform vec2 unif2 : C10; // notice 16-byte alignment!
uniform vec4 smartPacking : C11;
#define uni_f3 smartPacking.x
#define uni_f4 smartPacking.yz

varying vec3 varN: TEX0; // you must specify which slot the varying will use, or the compiler will pick at random
varying vec2 varCoord: TEX1;
varying vec3 varPos : TEX2;

// gl_Vertex is at ATTR0
attribute vec3 inN : ATTR1;
attribute vec2 inCoord: ATTR2;

...
uniform sampler2D myTex: TEXUNIT0;

All else in the shader looks like GLSL1.1

Uploading of uniforms (you know the C0…C255 offsets from the shader) :


void ilSetUniformsPS(int start,int vec4count,const void* data){
	const float* data4=(const float*)data;
	if(glProgramLocalParameters4fvEXT){
		glProgramLocalParameters4fvEXT(GL_FRAGMENT_PROGRAM_ARB,start,vec4count,data4);
		return;
	}
	while(vec4count--){	
		glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,start++,data4);
		data4+=4;
	}
}
void ilSetUniformsVS(int start,int vec4count,const void* data){
	float* data4=(float*)data;
	if(glProgramLocalParameters4fvEXT){
		glProgramLocalParameters4fvEXT(GL_VERTEX_PROGRAM_ARB,start,vec4count,data4);
		return;
	}
	while(vec4count--){
		glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB,start++,data4);
		data4+=4;
	}
}

Later, porting back to GL3.x isn’t really a pain: those C0 constants and stuff - you move them to your C++ side.
Have fun :slight_smile:

thanks that is exactly what I was looking for. But I have one more question. What is the best way to feed in the attribute Variables? I guess it is still glVertexPointer, glNormalPointer etc. since there is no concept of Attributes yet?

And I could use glProgramLocalParameters4fvEXT throughout, since it is available in the OSS MESA drivers :slight_smile:

Yes, you’re stuck with the glNormalPointer, etc.
Ps: but you can still be putting the attribs in the 8 tex-coords, instead of using glNormalPtr/glColorPtr .

Ah, since you’ll be specifying attribs via those glVertexPtr/etc, the “ATTR1” semantics in the shader-code should be actually “TEXCOORD0” or whatever the cgc docs specify.

I guess it is still glVertexPointer, glNormalPointer etc. since there is no concept of Attributes yet?

ARB_vertex_program was where they first introduced generic attributes. You are perfectly capable of using them with ARB_vertex_programs: just use ATTR#, where # is the attribute index.

I don’t find it in the 1.5 spec, and this is in glext.h :


#ifndef GL_VERSION_2_0
#define GL_VERSION_2_0 1
#ifdef GL_GLEXT_PROTOTYPES
....
GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *);
...
#endif

#ifndef GL_ARB_vertex_program
#define GL_ARB_vertex_program 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *);
#endif

Maybe it’s not available to him even as an extension o_O (however unlikely) ?

P.S. Anyway, even like that you can make your code remap attributes: use just the glVertexPointer and glTexCoordPtr, call attrib0=vtxPtr, attrib1…8=texcoordptr in a wrapper-func; have this macro in the shader:


#define attrib0(a) attribute a : POSITION;
#define attrib1(a) attribute a : TEXCOORD0;
#define attrib2(a) attribute a : TEXCOORD1;
..
#define attrib8(a) attribute a : TEXCOORD7;

Anyway, even like that you can make your code remap attributes

Why would you want to? If you can use generic attributes, you should.

Yes, I agree. What I meant is that if generic-attribs are not available, it’s nice to prepare his code via remapping, for the inevitable update.


void my_glVertexAttribPointerARB(...){
   if(idx==0){glVertexPointer(...);}
   else(glTexCoordPointer(idx-1,..);
}

This later really simplifies having vtx-declarations for interleaved-buffers:


struct VTXDCL_Pos{
	vec3 pos;
};
struct VTXDCL_Type0{
	vec3 pos;
	vec3 norm;
};
...
struct VTXDCL_Type4{
	vec3 pos;
	vec3 norm;
	vec2 uv0;
	U8 boneID[4];
	vec4 boneWT;
};


static const short vtxDecl_Pos[]={
	IL_ADD_VTX_ATTRIB(0,3F),
	0
};
static const short vtxDecl_Type0[]={
	IL_ADD_VTX_ATTRIB(0,3F),
	IL_ADD_VTX_ATTRIB(1,3F),
	0
};
...
static const short vtxDecl_Type4[]={
	IL_ADD_VTX_ATTRIB(0,3F),
	IL_ADD_VTX_ATTRIB(1,3F),
	IL_ADD_VTX_ATTRIB(2,2F),
	IL_ADD_VTX_ATTRIB(3,4UB),
	IL_ADD_VTX_ATTRIB(4,4F),
	0
};
...
ILVBO vboFull= ilCreateStaticVBO(verts,numv,vtxDecl_Type4,indices,numt*3*4,true);
...
ilSetTexture(0,tex1);
ilDrawVBO(vboFull);

glVertexAttribPointerARB is available, but I am still not sure how to correctly use it, since I cannot find any good documentation on it.

Right now I am doing:

// load the interleaved buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);

// set the vertex pointer to the correct offset
glVertexPointer(3, GL_FLOAT, 8*sizeof(float), (void*)(5*sizeof(float)));

// render the triangle
glDrawArrays(GL_TRIANGLES, 0, 3);

and the data is accessible as POSITION in the shader.

if I try instead:

// load the interleaved buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);

// set the attrib pointer to the correct offset
glVertexAttribPointerARB(0, 3, GL_FLOAT, false, 8*sizeof(float), (void*)(5*sizeof(float)));

// render the triangle
glDrawArrays(GL_TRIANGLES, 0, 3);

and try to access the data through ATTR0 it does not work.
Anything I have forgotten and should do?

Have you bound attribute names in the program object to the right generic vertex attribute index? Take a look at glBindAttribLocation if it not already done.

glBindAttribLocation works on 2.0+ with GLSL :frowning: .
Maybe you forgot to use glEnableVertexAttribArrayARB()

Check the result asm code, see if it’s using the fixed-func attribs instead of the generic ones. Here’s an example of using the generic ones:


!!ARBvp1.0
MOV result.texcoord[1], vertex.attrib[0];
MOV result.position, vertex.attrib[0];
MOV result.texcoord[2].xyz, vertex.attrib[0];
MOV result.texcoord[3].xyz, vertex.attrib[0];
MOV result.texcoord[4].xyz, vertex.attrib[0];
MOV result.texcoord[5].xyz, vertex.attrib[0];
MOV result.texcoord[0].xy, vertex.attrib[0];
END

In the source, I specified “attribute vec4 a : ATTR0;”
If I had specified “attribute vec4 a : POSITION;” , it would have used “vertex.position” instead of “vertex.attrib[0]”.

well, yeah… :o
thanks :slight_smile: