Vertex Shader and vertex positions

Hi,

I’ve implemented a vertex shader that calculates and assigns new vertex positions to the vertices of a triangular mesh.
Now I want to read the new position as calculated by the shader from the framebuffer.
How can this be managed?

thanks in advance,
daniel.

Either by transform-feedback, or (in a complicated+limited way) move the calculations to the frag-shader.
When transform-feedback is not available, vtx-shader output data is never written anywhere in VRAM. Only the frag-shader writes to VRAM, thus draw only 1x1 points in GL_POINTS mode (not GL_TRIANGLES), have each vertex position itself over a consecutive pixel in the framebuffer, and make the frag-shader write onto that pixel.

If you’ll be using the calculated output as a VBO, use a PBO to copy/typecast the FBO’s pixel-data as a VBO. (“render to VBO”)

I’m trying to use transform-feedback…

My Problem is now:
I’m using IndexBuffers to draw the triangles of the mesh. Transform-Feedback grabs the geometry that is passed through (or created by) the geometry shader. So it would grab 3 vertices per triangle?
This would be more than the indexed vertices…
Or am I completely wrong?

Please, post your code somewhere if you manage to get Transform Feedback (EXT version) to work.
As for your question, TF grabs resulting primitives before the rasterization, so the output size depends completely on your geometry shader.

Maybe if you “draw” them in GL_POINTS mode, without using the index-buffer, you could get exactly what you need. Only that vertices that won’t be used in the IB will also be sent for transformation; anyway it shouldn’t pose a real problem.

I’m having problems getting the locations of the transform-feedback-varyings.
No problem with gl_Position and faceNormal but no chance to get the location of gl_FrontColor (loc[1] == -1).


GLint loc[3];
loc[0] = glGetVaryingLocationNV(program,"gl_Position");
loc[1] = glGetVaryingLocationNV(program,"gl_FrontColor");
loc[2] = glGetVaryingLocationNV(program,"faceNormal");
glTransformFeedbackVaryingsNV(program, 3, loc,GL_INTERLEAVED_ATTRIBS_NV);

I tried to activate it with


glActiveVaryingNV(program,"gl_FrontColor");

before linking the program.

My VS- and GS-code looks like this
Vertex-Shader:


#version 120 
#extension GL_ARB_texture_rectangle : enable
varying vec3 normal;
varying vec4 pos;
varying vec4 diffuse;
varying vec4 ambientGlobal;
varying vec4 ambient;
varying vec3 lightDir;
varying vec3 halfVector;
varying float lightDist;

void setupLight(vec4 pos_)
{
   vec4 ecPos;
   vec3 aux;
	

   /* these are the new lines of code to compute the light's direction */
   ecPos = gl_ModelViewMatrix * pos_;
   aux = vec3(gl_LightSource[0].position-ecPos);
   lightDir = normalize(aux);
   lightDist = length(aux);
	
   halfVector = normalize(gl_LightSource[0].halfVector.xyz);
		
   /* Compute the diffuse, ambient and globalAmbient terms */
   diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
		
   /* The ambient terms have been separated since one of them */
   /* suffers attenuation */
   ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
   ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
}
void main(void) 
 {
    gl_FrontColor = gl_Color;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    normal = normalize(gl_NormalMatrix * gl_Normal);
    pos = gl_Vertex;
    setupLight(pos);
 }

Geometry-Shader:


#version 120 
#extension GL_EXT_geometry_shader4 : enable 
#extension GL_EXT_gpu_shader4 : enable 
varying in vec3 normal[3];
varying in vec4 pos[3];
varying out vec3 faceNormal;
varying in vec4 diffuse[3];
varying in vec4 ambientGlobal[3];
varying in vec4 ambient[3];
varying in vec3 lightDir[3];
varying in vec3 halfVector[3];
varying in float lightDist[3];
varying out vec4 odiffuse;
varying out vec4 oambientGlobal;
varying out vec4 oambient;
varying out vec3 olightDir;
varying out vec3 ohalfVector;
varying out float olightDist;
varying out vec3 onormal;

void main() 
{ 
   onormal = vec3(0.0);
   gl_FrontColor = vec4(0.0);
   gl_Position = vec4(0.0);
   faceNormal = normalize(gl_NormalMatrix*cross(pos[1].xyz-pos[0].xyz,pos[2].xyz-pos[0].xyz));
   for(int i = 0; i < gl_VerticesIn; ++i)
  {
    gl_Position = gl_PositionIn[i];
    gl_FrontColor = gl_FrontColorIn[i];
    onormal = faceNormal;
    odiffuse = diffuse[i];
    oambientGlobal = ambientGlobal[i];
    oambient = ambient[i];
    olightDir = lightDir[i];
    ohalfVector = halfVector[i];
    olightDist = lightDist[i];
    EmitVertex();
  }
   EndPrimitive();
  
} 

glGetError() returns no errors…
Any ideas?

don’t use gl_FrontColor :slight_smile: , declare new varying eg. myFrontColor.

Thanks, this works :smiley:
But the results differ from the results I get when calculating new vertex positions on the CPU.
I’m using a texture to store a matrix of values as input to the vertex-shader. Accessing this texture is done as follows


uniform int h;
uniform int w;
uniform sampler2DRect myTexture;
.
.
.
for(int i = 0; i<w; i++)
    {
       for(int j=0; j<h; j++)
       {
          vec4 val = texture2DRect(myTexture, vec2((float(i)+0.5),(float(j)+0.5)));
          foo(gl_Vertex,val.rgb);
       }
    }

Is this the right way to access the texture?