Hello again and thanks for your responces
You can manage to perform multiple texture fetch using a 2D texture. For example, the x coordinate would be the vertex ID and along the y coordinate, the faces normals list.
As i need absolute integer values returned from the sampler for your GLSL code, i used Texture Integer (GL_EXT_texture_integer) to store the faces indices lists.
(This extension provides a set of new “unnormalized” integer texture formats. Formats with both signed and unsigned integers are provided.
In these formats, the components are treated as true integers. When such textures are accessed by a shader, actual integer values are returned.)
However, the returned normal vector values are not the correct ones…
I have implemented this project using :
- one VBO for vertex-normal vectors ( but i do not use normals - gl_Normal ) and some attributes.
- one TBO for normal vectors of model faces
- one Textrure Integer for face indices
Here is the vertex shader code:
#version 120
#extension GL_EXT_gpu_shader4 : require
varying vec4 Idiffuse,IambientGlobal,Iambient;
varying vec3 Inormal ,IlightDir ,IhalfVector;
varying float Idist;
attribute ivec4 attr;
uniform isampler2D TEX_I_N;
uniform samplerBuffer TBO_P_N;
// attr[2] = number of faces that contain each vertex
vec3 computeNormal()
{
int texel;
vec3 normal = vec3(0.0,0.0,0.0);
for(int i=0; i < attr[2]; i++){
texel = texture2D(TEX_I_N, ivec2(i,gl_VertexID)).x;
normal += texelFetchBuffer(TBO_P_N, texel).xyz;
}
normal /= attr[2];
return normalize(normal);
}
void main()
{
vec3 n,aux; vec4 ecPos;
Inormal = normalize(gl_NormalMatrix * computeNormal());
ecPos = gl_ModelViewMatrix * gl_Vertex;
aux = vec3(gl_LightSource[0].position-ecPos);
IlightDir = normalize(aux); Idist = length(aux);
IhalfVector = normalize(gl_LightSource[0].halfVector.xyz);
Idiffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
Iambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
IambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
…and the opengl setup code:
GLint i,j,ii=0,max_k(0);
//////////////////////
// TBO with faces normal vectors
GLfloat *normals = new GLfloat[numOfFaces*4];
for(i=0; i<numOfFaces; i++){
normals[ii] = (*Faces)[i].normal.x;
normals[ii+1] = (*Faces)[i].normal.y;
normals[ii+2] = (*Faces)[i].normal.z;
normals[ii+3] = 1.f;
ii+=4;
}
glDeleteBuffers (1, &textureBuffers); glGenBuffers (1, &textureBuffers);
glDeleteTextures(2, textures); glGenTextures(2, textures);
glBindBuffer (GL_TEXTURE_BUFFER_EXT, textureBuffers);
glBufferData (GL_TEXTURE_BUFFER_EXT, 4 * numOfFaces * sizeof(GLfloat), normals, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER_EXT, textures[0]);
glTexBufferEXT( GL_TEXTURE_BUFFER_EXT, GL_RGBA32F_ARB, textureBuffers);
glBindTexture(GL_TEXTURE_BUFFER_EXT, 0 );
glBindBuffer (GL_TEXTURE_BUFFER_EXT, 0);
//////////////////////
// Texture Integer with face indices for each vertex
// -- Vertex_Faces[i]: faces indices list for vertex 'i'
for(i=0; i<numOfVerts; i++)
if(max_k < (int)Vertex_Faces[i].size())
max_k = Vertex_Faces[i].size();
GLint *indices = new GLint [numOfVerts*max_k];
for(i=0; i<numOfVerts; i++)
for(j=0; j<max_k; j++)
indices[i*max_k + j] = (j < (int)Vertex_Faces[i].size()) ? *(Vertex_Faces[i].begin() + j) : -1;
glBindTexture (GL_TEXTURE_2D, textures[1]);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S , GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T , GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16I_EXT, max_k, numOfVerts, 0, GL_LUMINANCE_INTEGER_EXT, GL_UNSIGNED_SHORT, (const GLvoid *)indices);
glGenerateMipmapEXT(GL_TEXTURE_2D);
delete [] indices;
delete [] normals;
…and the opengl render code:
if(Rmode == GL_RENDER) glUseProgram(pro2);
glColor3f(1.f,1.f,1.f);
glActiveTexture(GL_TEXTURE0); glBindTexture( GL_TEXTURE_BUFFER_EXT, textures[0]);
glActiveTexture(GL_TEXTURE1); glBindTexture( GL_TEXTURE_2D , textures[1]);
glBindBuffer(GL_ARRAY_BUFFER, vboId[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 48, BUFFER_OFFSET(0) );
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer( GL_FLOAT, 48, BUFFER_OFFSET(12) );
////
if(Rmode == GL_RENDER){
int loc = glGetAttribLocation (pro2, "attr");
glEnableVertexAttribArray(loc);
glVertexAttribIPointerEXT(loc,4,GL_INT,48,BUFFER_OFFSET(24));
glUniform1i (glGetUniformLocation(pro2, "TBO_P_N"), 0);
glUniform1i (glGetUniformLocation(pro2, "TEX_I_N"), 1);
}
///
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId[2]);
glDrawElements(GL_TRIANGLES, 3*numOfFaces, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D , 0);
glBindTexture(GL_TEXTURE_BUFFER_EXT,0);
glActiveTexture(0);
if(Rmode == GL_RENDER) glUseProgram(NULL);
Could anybody help me…???