ポイントスプラッティング

pointsplatting.png
256%5E3Points.PNG

点に色をつける

テクスチャと元の色との関係を設定する

ポイントのサイズを視点からの距離によって変える

static GLfloat atten[] = { 0.0, 0.0, 1.0 };
glEnable(GL_POINT_SPRITE);//*注 OpenGL2.0以降は非推奨。常に点は常にポイントスプライトが有効となります。
glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION,atten);

glPointParameter
これ

glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

もあったほうがいいかな。
もしかしたら、シェーダを使って、行列変換をしているときは、これ、効き目がないかも。

OpenGL2.0以降は非推奨。常に点は常にポイントスプライトが有効となります。[1]

なのでひとたびglPointParameterfv(GL_POINT_DISTANCE_ATTENUATION)してしまうと、以降全部ポイントスプライトになってしまう。
なのでキャンセルするコードを考えました

static GLfloat atten_cancel[] = { 1.0, 0.0, 0.0 };
glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, atten_cancel);//これ以降はglPointSizeで指定した値=ピクセル上の大きさ、になる

根拠は、attenに使用される減衰関数が以下のようになっているからです
static GLfloat atten[] = { a,b,c};
(1)
\begin{align} pointsize=\sqrt{ \frac{1}{a+b*d+c*d^2}} \end{align}

dは視点からの距離です。

android

purple.jpg

点を並び替えないと、このような不自然な描画結果になる
しかし、GL_DEPTH_TESTをEnableにしないで

glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_DST_ALPHA );
glDisable(GL_BLEND);

こういうブレンド関数にすれば、大丈夫。

レンダリング点群生成

void InitPoints(){
    points_vertex=new float[VOLSIZE*VOLSIZE*VOLSIZE*3];
    for(int z=0;z<VOLSIZE;z++){
        for(int y=0;y<VOLSIZE;y++){
            for(int x=0;x<VOLSIZE;x++){
                int index=(z*VOLSIZE+y)*VOLSIZE+x;
                points_vertex[index*3+0]=2.0f*(float)x/(float)VOLSIZE-1.0f;
                points_vertex[index*3+1]=2.0f*(float)y/(float)VOLSIZE-1.0f;
                points_vertex[index*3+2]=2.0f*(float)z/(float)VOLSIZE-1.0f;
                //LOGI("(%f,%f,%f)",points_vertex[index+0],points_vertex[index+1],points_vertex[index+2]);
            }
        }
    }
}

点にガウシアンテクスチャを貼る

gaussian.png
gl_PointCoordを有効にするにはglEnable(GL_POINT_SPRITE);する必要がある、ことに注意!
これも必要っぽいぞ。

glTexEnvf(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE);

varying vec4 mColor;
uniform sampler2D gaussiantexture;
    void main() {  
    //gl_PointCoordを有効にするにはglEnable(GL_POINT_SPRITE);する必要がある。
        vec4 luminance=texture2D(gaussiantexture,gl_PointCoord);
        luminance=vec4(vec3(1.0,1.0,1.0),luminance.x);
        gl_FragColor= mColor*luminance;
    }

ビットマップのガウシアンテクスチャをOpenGLに渡す

void Load8BitmapTexture(const char* _filename,GLuint *_texId){
    wprintf(L"%s",_filename);
    HANDLE handle;
    DWORD temp=0;
    BITMAPFILEHEADER bitmapFileHeader;
    BITMAPINFOHEADER bitmapInfoHeader;
    handle = CreateFile(_filename,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL );
    //SetFilePointer(handle , 0 , NULL , FILE_BEGIN);
    // DIBファイルヘッダーを開き、読み込む
    if(handle==INVALID_HANDLE_VALUE || handle==NULL){assert(!"ファイルが見つからない");}
    ReadFile(handle,&bitmapFileHeader,sizeof(BITMAPFILEHEADER),&temp,NULL);
    if ( temp!=sizeof(BITMAPFILEHEADER) || bitmapFileHeader.bfType!=0x4D42 )
    {
        CloseHandle(handle);
        assert(!"ビットマップじゃありません");
    }
    ReadFile(handle,&bitmapInfoHeader,sizeof(BITMAPINFOHEADER),&temp,NULL);
    RGBQUAD palette[255*4];
    ReadFile(handle,&palette,sizeof(RGBQUAD)*256,&temp,NULL);
    unsigned char* texdata;
    texdata=new unsigned char[bitmapInfoHeader.biSizeImage];
    ReadFile(handle,texdata,bitmapInfoHeader.biSizeImage,&temp,NULL);
    CloseHandle(handle);
    //for(int i=0;i<200;i++){printf("%d\n",texturedatapointer[i]);}
    glGenTextures ( 1, _texId );
    glBindTexture ( GL_TEXTURE_2D, *_texId );
    glTexImage2D ( GL_TEXTURE_2D, 0, GL_INTENSITY, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texdata);
    delete[] texdata;
    checkGlError("teximage2d");
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
}
glEnable(GL_POINT_SPRITE);
            glDepthMask(GL_FALSE);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//back-to-front
 
            glActiveTexture ( GL_TEXTURE0 );
            glEnable ( GL_TEXTURE_2D );
            m_GausTexSamp.Bind2D();
            glPointSize(10);
            //黄色い点のレンダリング
            glBegin(GL_POINTS);
            glColor3f(1.0,1.0,0.0);
            glPointSize(20);
            for(int i=0;i<100;i++){
                m_YellowPoints[i].glVertex();
            }
            glEnd();
            glDisable(GL_TEXTURE_2D);
            glDisable(GL_BLEND);
            glDepthMask(GL_TRUE);
            glDisable(GL_POINT_SPRITE);

ガウシアンテクスチャ適用前 ガウシアンテクスチャ適用後
yoko.png yokog.PNG

gaussian gl_pointcoord opengl2 point

サポートサイト Wikidot.com gaussiangl_pointcoordopengl2point