FW: [info-performer] Memory leak in Performer 3.1 for Windows

Date view Thread view Subject view Author view

From: David Lannan (david.lannan++at++sydac.com.au)
Date: 04/26/2004 17:18:45


Hi all,

Previously I was going to post our results of implementing ARB vertex and
fragment shaders in Performer 3.02. I have included a basic example of Pre
and Post draw callbacks, that can be used to apply a shader to any geometry
node - it will probably work on any pfNode. This system is purely for
Performer 3.02, I am uncertain of the operation under Performer 3.1 (because
of our problems).

In these functions I was implementing a light scattering routine :-) .. but
the parameters can be set for the shader you want to use. Again this is just
a rudimentary sample. If you want to have proper parameter handling you'll
need to write it yourself :-)

VERTEX_SHADER_BUFFER and FRAGMENT_SHADER_BUFFER are char buffers of the ARB
programs. Make sure the program is formatted correctly - I didnt post any
checking routines. Also, I have have couple of simple shaders I can post if
need be, but there is a fair amount of ARB examples on the net.

I hope this helps, it certainly has the capability to improve the graphical
content and attaching to a particular node is ideal for specific
implementations - ie a water shader, some specular highlighting on metal
components and so on.

The following should be enough to get the vertex and fragment programs
running. Oh, make sure you have a decent video card for fragment shaders -
it seems GF4's and some Quadros arent fragment capable, but the 9700 & 9800
series seem to be fine.

<Sorry Peter, this was supposed to go to info-performer :-)>

Cheers,

David Lannan

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

#include<gl/gl.h> // OpenGL header.
#include<gl/glu.h> // OpenGL utility.
#include"glext.h" // OpenGL extensions.

// These are OpenGL functions that we will need for our vertex shader.
Actually they
// are pointers and we will get the address of the functions we need.
static PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
static PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB = NULL;
static PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
static PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB =
NULL;
static PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB =
NULL;

// This will hold our vertex shader - need to have list for them (can have
per node!)
static GLuint VertexShader;
static GLuint FragmentShader;

void PreRenderFragment(pfTraverser *_trav)
{
    glPushMatrix();
    // This will load our translation values into program.env[0].
    glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 0.5f, 0.5f, 0.5f,
1.0f);
    glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 0, -1, 0, 0 );
    glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, brightness,
contrast, 0, 0);

    // Here we are binding the vertex shader to the hardware after you set
the
    // constants.
    glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, FragmentShader);

    // Just like if you would like to have texture, you would need to enable
texturing right?
    // Well to use the vertex program you must enable it like so...
    glEnable(GL_FRAGMENT_PROGRAM_ARB);
}

void PostRenderFragment(pfTraverser *_trav)
{
    // When we are done we disable the vertex program.
    glDisable(GL_FRAGMENT_PROGRAM_ARB);
    glPopMatrix();
}

void PreRenderShader(pfTraverser *_trav)
{
    glPushMatrix();

    // This will load our translation values into program.env[0].
    glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, 1.0f, 10.0f, 10.0f,
0.0f);

    pfVec3 epos;
    _trav->getChan()->getEye(epos);

    // Set position and direction of the sun - relative to viewer
    glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, epos[0] - 2000,
epos[1] - 2000, 0, 0 );
    glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1, 0.14780, -0.9890,
0.2478, 0);

    // Here we are binding the vertex shader to the hardware after you set
the
    // constants.
    glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VertexShader);

    // Just like if you would like to have texture, you would need to enable
texturing right?
    // Well to use the vertex program you must enable it like so...
    glEnable(GL_VERTEX_PROGRAM_ARB);
}

void PostRenderShader(pfTraverser *_trav)
{
    // When we are done we disable the vertex program.
    glDisable(GL_VERTEX_PROGRAM_ARB);
    glPopMatrix();
}

bool Material::Init()
{
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Clear the screen to black.

   glShadeModel(GL_SMOOTH); // Smooth shading in our scenes.
   glEnable(GL_DEPTH_TEST); // Enable desth testing for hidden
surface removal.

   // With this we will load the list of extensions the hardware this
tutorial is running on
   // supports.
   char *extension = (char*)glGetString( GL_EXTENSIONS);

   // Now that we have all of the extensions the hardware supports lets test
if the
   // GL_ARB_vertex_program extension is there.
   if(strstr(extension, "GL_ARB_vertex_program") == NULL)
   {
         MessageBox(NULL, "Your hardware don't support vertex shaders!",
                    "Shader with GL_ARB_vertex_program is not supported",
MB_OK);

         return false;
   }
   if(strstr(extension, "GL_ARB_fragment_program") == NULL)
   {
         MessageBox(NULL, "Your hardware don't support fragment shaders!",
                    "Shader with GL_ARB_fragment_program is not supported",
MB_OK);

         return false;
   }

   // Next we will try to get the address of each of the functions we will
need for this tutorial.
   glGenProgramsARB =
(PFNGLGENPROGRAMSARBPROC)wglGetProcAddress("glGenProgramsARB");
   glDeleteProgramsARB =
(PFNGLDELETEPROGRAMSARBPROC)wglGetProcAddress("glDeleteProgramsARB");
   glProgramStringARB =
(PFNGLPROGRAMSTRINGARBPROC)wglGetProcAddress("glProgramStringARB");
   glBindProgramARB =
(PFNGLBINDPROGRAMARBPROC)wglGetProcAddress("glBindProgramARB");
   glProgramEnvParameter4fARB =
(PFNGLPROGRAMENVPARAMETER4FARBPROC)wglGetProcAddress("glProgramEnvParameter4
fARB");
   glProgramLocalParameter4fARB =
(PFNGLPROGRAMLOCALPARAMETER4FARBPROC)wglGetProcAddress("glProgramLocalParame
ter4fARB");

   // We need to do some error checking. We must make sure the functions
are supported.
   if(!glGenProgramsARB || !glDeleteProgramsARB || !glProgramStringARB ||
      !glBindProgramARB || !glProgramEnvParameter4fARB ||
!glProgramLocalParameter4fARB)
      {
              MessageBox(NULL, "Error, GL_ARB_vertex_program functions not
supported", "Error...",
                    MB_OK);

              return false;
      }

   // Now that we know everything is good and that the hardware actually
supports what we want
   // to do we can now actually load and create the vertex shader.

   // First we generate the vertex program using the ARB function
glGenProgramsARB.
   // Next we will bind it to our global Vertex Shader variable called,
VertexShader.
   glGenProgramsARB(1, &VertexShader);
   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VertexShader);
   glGenProgramsARB(1, &FragmentShader);
   glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, FragmentShader);

   // Next we will load the source code for the shader into OpenGL. First
we will get the data.
   int count = 0;
   int fcount = 0;
   char *ShaderCode = VERTEX_SHADER_BUFFER;
   char *FragmentCode = FRAGMENT_SHADER_BUFFER;
   count = strlen(ShaderCode);
   fcount = strlen(FragmentCode);

   // Error checking...
   if(ShaderCode == NULL)
   {
         MessageBox(NULL, "Error loading vertex shader code", "Error...",
MB_OK);
         return false;
   }
   if(FragmentCode == NULL)
   {
         MessageBox(NULL, "Error loading fragment shader code", "Error...",
MB_OK);
         return false;
   }

   // Now we take that source code and create the vertex shader out of it.
   glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
count, ShaderCode);
   glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
fcount, FragmentCode);

   // If all went well we return true.
   return true;
}

void Material::SetShader(pfNode *node)
{
    if(node)
    {
        node->setTravFuncs(PFTRAV_DRAW, PreShader, PostShader);
    }
}

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Mon Apr 26 2004 - 17:18:00 PDT