VISH  0.2
PointSprite.cpp

Example demonstrating how to use the OpenGL Point sprite rendering, with two VISH parameters, the number of points and diameter.

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

#include <ocean/GLvish/VRenderObject.hpp>
#include <ocean/plankton/VCreator.hpp>

using namespace Wizt;

class   RenderExample : public VRenderObject
{
        enum { TEXWIDTH=64, TEXHEIGHT=64 };

        struct  MyState :  State
        {
                size_t  nPoints;
                float  (*myPoints)[2];

                GLuint  textureID; //Id for the point sprite texture    
                GLuint  cmapID;    //Id for the colormap texture

                void SetupPointTexture();
                void SetupColormapTexture();
                void SetupRC();
                void CleanupRC();

                MyState()
                : nPoints(0)
                , myPoints(0)
                {}

                ~MyState()
                {
                        CleanupRC(); 
                        delete [] myPoints;
                }
        };

        override RefPtr<VObject::State> newState() const
        {
                return new MyState();
        }

        virtual void render(VRenderContext&Context) const;

public:
        TypedSlot<int>          NumPoints;
        TypedSlot<double>       PointSize;

        RenderExample(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
        : VRenderObject(name,  OVERLAY_OBJECT, VP)
        , NumPoints(this, "number", 10)
        , PointSize(this, "size", 10.0)
        {
                PointSize.setProperty("max", 30.0);
        }

        ~RenderExample()
        {}

        override bool update(VRequest&Context, double prec);
};

static VCreator<RenderExample> MyCreator("Demo/PointSprite");

VISH_DEFAULT_INIT


void RenderExample::MyState::SetupPointTexture() 
{
GLfloat texImage[TEXHEIGHT][TEXWIDTH][4];

        // Load our textures
        glActiveTextureARB(GL_TEXTURE0_ARB);
        glGenTextures(1, &textureID);
        glBindTexture(GL_TEXTURE_2D, textureID); 

 double S = .5;
        for(int y=0; y<TEXHEIGHT; y++)
        for(int x=0; x<TEXWIDTH; x++)   
        {
        double  yf = (y-32)/32.0, xf = (x-32)/32.0,
                r2 =  xf*xf + yf*yf;

                texImage[x][y][0] = exp(-r2/S);
                texImage[x][y][1] = exp(-r2/S);
                texImage[x][y][2] = exp(-r2/S);
                texImage[x][y][3] = exp(-r2/S);
        } 

        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
        glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA, TEXWIDTH, TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, texImage); 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

        glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); 
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}



//load colormap 1d texture
void RenderExample::MyState::SetupColormapTexture() 
{
        //Now set up 1D texture some silly color changes
        GLfloat cmapImage[4*32];
        float inv_32 = 1.0f/32.0f;
        for (int j = 0; j < 32; j++) {
                cmapImage[4*j] =  0.5f;
                cmapImage[4*j+1] = 1-j*inv_32;
                cmapImage[4*j+2] = j*inv_32;
                cmapImage[4*j+3] = 0.0f;
        }

        glActiveTextureARB(GL_TEXTURE1_ARB);
        glGenTextures(1, &cmapID);
        glBindTexture(GL_TEXTURE_1D, cmapID);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 32, 0,GL_RGBA, GL_FLOAT, cmapImage);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

        GLfloat plane_eqn[] = {2, 0.0, 0.0, 0.0};
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
        glTexGenfv(GL_S, GL_OBJECT_PLANE, plane_eqn);
        glEnable(GL_TEXTURE_GEN_S);

}

bool RenderExample::update(VRequest&Context, double prec)
{
RefPtr<MyState> MS = myState(Context); 
        if (!MS) 
        {
                return true;
        }

int     number = 100; 
        NumPoints << Context >> number; 
        number *= 1000;

float   (*Points)[2] = new float[number][2];

        // generate random points
        for(int i = 0; i < number; i++)
        {
                Points[i][0] = rand()*2.0/RAND_MAX - 1;
                Points[i][1] = rand()*2.0/RAND_MAX - 1;
        } 

        synchronized( *this )
        {
                delete [] MS->myPoints; 
                MS->myPoints = Points; 
                MS->nPoints  = number;
        }

        return true;
}

void RenderExample::render(VRenderContext&Context) const
{
RefPtr<MyState> MS = getState(Context); 
        if (!MS)
        {
                puts(":(");
                return;
        }

        MS->SetupRC();
 
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA); 

        glDisable( GL_DEPTH_TEST ); 

        glEnable(GL_POINT_SPRITE);
        //Texture unit 0 has the point sprite texture
        glActiveTexture(GL_TEXTURE0);
        glEnable(GL_TEXTURE_2D); 
        glBindTexture(GL_TEXTURE_2D, MS->textureID);

        //Texture unit 1 has the colormap texture
        glActiveTexture(GL_TEXTURE1);
        glEnable(GL_TEXTURE_1D);
        glBindTexture(GL_TEXTURE_1D, MS->cmapID); 


double  PS = 20.0; 
        PointSize << Context >> PS;
        //
        // Now draw points
        glPointSize( PS );
        glBegin(GL_POINTS);
        for(size_t i = 0; i < MS->nPoints; i++)
                glVertex2fv(MS->myPoints[i]);
        glEnd();

        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_1D);
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_POINT_SPRITE);
}


// This function does any needed initialization on the rendering
// context. 
void RenderExample::MyState::SetupRC()
{
        SetupPointTexture();    
        SetupColormapTexture();
}


void RenderExample::MyState::CleanupRC()
{
        glDeleteTextures(1, &textureID);
        glDeleteTextures(1, &cmapID);
}