Skip to content

Instantly share code, notes, and snippets.

@kezzardrix
Last active October 9, 2017 02:27
Show Gist options
  • Save kezzardrix/eb99f8683e8f0575b53b to your computer and use it in GitHub Desktop.
Save kezzardrix/eb99f8683e8f0575b53b to your computer and use it in GitHub Desktop.
Bugs caused from ofEnablePointSprites

#ofEnablePointSprites()使うと色々ハマる

ofEnablePointSprite()の中身は

glEnable(GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); ← こいつが元凶くさい
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

glTexEnvi~にGL_POINT_SPRITEを設定するとポイントスプライト用の特殊なテクスチャ座標ができる。 が、これを呼んでるとvaryingがバグることがある。

##ハマり例

全てのvarying変数をfragの中で一回参照しないと、壊れるvaryingが出てくる

 varying vec3 normal;
 varying vec4 worldPos;

 void main() {
       
       //float angle = normal.z //これコメントアウトしたらworldPosの値がおかしくなる
       gl_FragColor = vec4(worldPos);
}

##対策(どっちかやれ)

  • vertexの中でテクスチャユニットの座標を設定する

      gl_TexCoord[0] = gl_MultiTexCoord0
    
  • fragmentの中で使わなくてもテクスチャ座標を一回参照する。

      vec2 st = gl_TexCoord[0].st
    

##結論

  • glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)は使わなくて良い人は使わない。

  • テクスチャ座標が欲しい場合はgl_PointCoordでやるのが良い。

  • OpenGL SuperBibleも5th Editionだと glTexEnvi式からgl_PointCoord式へと内容が変更されてる

#include "ofMain.h"
#define STRINGIFY(A) #A
class ofApp : public ofBaseApp
{
private:
ofVbo mVbo;
vector<ofFloatColor>mColors;
vector<ofVec3f>mVerts;
vector<ofVec3f>mNormals;
static const int MAX_VERTS = 10000;
ofShader mShader;
public:
void setup()
{
string vert = STRINGIFY(
varying vec3 normal;
varying vec4 worldPos;
void main() {
normal = gl_Normal;
worldPos = gl_ModelViewMatrix * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_PointSize = 3000.0 / gl_Position.w;
gl_FrontColor = gl_Color;
//gl_TexCoord[0] = gl_MultiTexCoord0; //ここで呼んどいても良い。
}
);
string frag = STRINGIFY(
varying vec3 normal;
varying vec4 worldPos;
void main() {
//float angle = normal.z //テクスチャ座標を参照してないと全てのvaryingを参照しない時バグる
vec2 st = gl_TexCoord[0].st; //こいつもコメントアウトするとworldPosの中身がおかしくなる
gl_FragColor = vec4(worldPos);
}
);
for(int i = 0; i < MAX_VERTS; i++){
mVerts.push_back(ofPoint(ofRandomWidth(),ofRandomHeight(),ofRandom(-400,400)));
mColors.push_back(ofFloatColor(1,1,1,1));
mNormals.push_back(ofPoint(ofRandom(-1.0,1.0),
ofRandom(-1.0,1.0),
ofRandom(-1.0,1.0)));
}
mVbo.setVertexData(&mVerts[0], MAX_VERTS, GL_DYNAMIC_DRAW);
mVbo.setColorData(&mColors[0], MAX_VERTS, GL_DYNAMIC_DRAW);
mVbo.setNormalData(&mNormals[0], MAX_VERTS, GL_DYNAMIC_DRAW);
mShader.setupShaderFromSource(GL_VERTEX_SHADER, vert);
mShader.setupShaderFromSource(GL_FRAGMENT_SHADER, frag);
mShader.linkProgram();
}
void draw()
{
ofBackground(0,0,0,0);
glEnable(GL_POINT_SPRITE);
//ポイントスプライト用のテクスチャ座標を作るけど、gl_TexCoord[0].st等を一回も呼ばないとvaryingが壊れる
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); //こいつが悪い
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
mShader.begin();
mVbo.draw(GL_POINTS,0,MAX_VERTS);
mShader.end();
}
};
#pragma mark -
#pragma mark main
int main(){
ofSetupOpenGL(1024, 768, OF_WINDOW);
ofRunApp(new ofApp());
}
@kezzardrix
Copy link
Author

ポイントスプライトの形自体も中でジェネるから、テクスチャなんかいらねーよっていう性癖の人じゃないと出会わないだろうバグでした

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment