How to directly get the result of the programmable vertex processor?

The results of programmable vertex processor always send to fragment processor, and we cann’t access it directly.
But if i want to get the result and write it to buffer or memory, what should i do?

Thanks very much!

You could copy the vertex result into a texture coordinate set (say texcoord0 for instance), then make a fragment program that reads that value and returns it as the fragment output color and then read that. You could have a pbuffer setup so that when this frag program returns that result, it gets written to the pbuffer, then your app could use that value in any wat it wants.

-SirKnight

If you use NV hardware you may take a look in a PBO spec . Here is a example code:

  
        #define BUFFER_OFFSET(i) ((char *)NULL + (i))

    Example 1: Render to vertex array

        // create a buffer object for a number of vertices consisting of 
        // 4 float values per vertex
        GenBuffers(1, vertexBuffer);
        BindBuffer(PIXEL_PACK_BUFFER_EXT, vertexBuffer);
        BufferData(PIXEL_PACK_BUFFER_EXT, numberVertices*4, NULL, DYNAMIC_DRAW);

        // render vertex data into framebuffer using a fragment program
        BindProgramARB(FRAGMENT_PROGRAM_ARB, fragmentProgram);
        DrawBuffer(GL_BACK);
        renderVertexData();
        BindProgramARB(FRAGMENT_PROGRAM_ARB, 0);

        // read the vertex data back from framebuffer
        ReadBuffer(GL_BACK);
        ReadPixels(0, 0, numberVertices*4, height/2,
            GL_BGRA, GL_FLOAT, BUFFER_OFFSET(0));

        // change the binding point of the buffer object to
        // the vertex array binding point
        BindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

        EnableClientState(VERTEX_ARRAY);
        VertexPointer(4, FLOAT, 0, BUFFER_OFFSET(0));
        DrawArrays(TRIANGLE_STRIP, 0, numberVertices);

Depending on hw you can use multi render target and you can calculate up to 4 vertex attributes.

Also be carefull with this approach. ATI cards have internal 24bit FPU precision and this is NOT enough. NV hardware have 32bit precision and this is enough.

yooyo

Thank you for your reply.

I have tried the p-buffer solution. But i found that the value in p-buffer are not accruate. For example, when I set the result of vertex processor as a color (0.5,0,0,0.5), the value i get from the float p-buffer is something as (0.5019,0,0,0.5019). Is the problem caused by limitation of Float P-Buffer? Will PBO avoid this problem?

Because of the problem, I had planned to get the result directly from vertex processor, that is, do not pass the fragment processor and turn into color buffers. Is this way applicable? If it is, what should i do?

it’s probably a conversion problem. all float values have to be converted to bytes to be stored in a buffer.

you can avoid this by using functions which use unsigned bytes as parameters. instead of

glColor4f(0.5, 0., 0., 0.5);

you should use

glColor4ub(128, 0, 0, 128);

Which type of float buffer do you use? A 16 or 32 bit float buffer?

The issue of getting results from the vertex processor has come up a few times before. However, it’s never been 100% clear (to me, anyway) what people want from that functionality.

Here’s a hypothetical question. If there were a way to get the output directly from the vertex processing state (i.e., the output of the vertex program / shader), would that be in lieu of rendering or in addition to rendering?

How would the resulting data be used? Would it just be re-used by the vertex processor in another pass (as some sort of T&L cache perhaps) or would it be used by the CPU?

The typical purpose for such functionality is to be able to do something like skinning on the GPU, and multipass on it without making the vertex processor redo that computation over and over again.

I use the 32-bit p-buffer.

I can’t set color in ubytes because I need the float output of vertex processor.

I do not necessarily need to get the direct result of vertex processor, what i need is to get the accurate result. The way to achieve it is not important. Please help me about the inaccurate result in the p-buffer!

My video card is Nvidia 6800.

Thank you very much!

Do you use GL_SMOOTH or GL_FLAT? I’m not sure if its important.

Originally posted by marco:
Do you use GL_SMOOTH or GL_FLAT? I’m not sure if its important.
That only has to do with the shading model of the triangles.

-SirKnight

Originally posted by CppInterpreter:
when I set the result of vertex processor as a color (0.5,0,0,0.5), the value i get from the float p-buffer is something as (0.5019,0,0,0.5019).
That error amount of 0.0019 is awfully suspicious. What happens when you use values that can only be represented as unclamped floats (say, 1000)? In other words, are you sure you’re getting some sort of float representation all the way through?

Originally posted by SirKnight:
[b] [quote]Originally posted by marco:
Do you use GL_SMOOTH or GL_FLAT? I’m not sure if its important.
That only has to do with the shading model of the triangles.

-SirKnight[/b][/QUOTE]I tought that it has to do with the interpolation of the values in the rasterizer(the varyings). smooth mean interpolations, flat not. How do it the fixed pipeline?