2011-04-30 80 views
3

我有一个着色器,用纯色绘制粒子。我希望使着色器能够对FBO纹理进行采样,以便每个粒子都可以对它后面的颜色起作用。似乎它应该很简单,但没有。GL_POINTS着色器中的纹理样本

我简化了代码,我希望我的FBO可以绘制在每个粒子的面上,缩小比例。丑陋的,但它至少会证明我的粒子可以采样纹理。相反,每个粒子只是一个纯色。我使用OpenFrameworks,所以有几个抽象。我已经验证tex.bind()绑定到第一个纹理位置,并且我可以将着色器应用于FBO而不需要GL_POINTS

这里就是我安装我的渲染,绘制FBO,并渲染粒子:

void Particles::draw(ofxFBOTexture &tex){ 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE); 
     ofEnableSmoothing(); 
     glEnable(GL_POINT_SPRITE_ARB); 
     glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 
     glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE, GL_TRUE); 
       shader.begin(); 
         shader.setUniform("winWidth", (float) width); 
         shader.setUniform("winHeight", (float) height); 
         tex.draw(0,0); // I've tried tex.bind() here too  

         for(int i = 0; i < lastDead; i++){ 
           allParticles[i]->draw(this->shader); 
         } 

       shader.end(); 
     glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 
     glDisable(GL_POINT_SPRITE_ARB); 
     ofDisableSmoothing(); 
     glDisable(GL_BLEND); 
} 
// <snip> 
void Particle::draw(ofxShader &shader){ 
     if(dead) return; 

     // this must go outside glBegin 
     shader.setAttribute("size", size); 
     shader.setAttribute("velocity", xVel, yVel, 0.0); 

     glBegin(GL_POINTS); 
       glColor4f(r, g, b, multiplier * 0.8); 
       glVertex3f(x, y, 0); 
     glEnd(); 
} 

这里是我的顶点着色器:

#version 120 
attribute float size; 
attribute vec3 velocity; 
varying vec3 vel; 
uniform float winWidth; 
uniform float winHeight; 

void main() { 
     gl_PointSize = size; 
     gl_FrontColor = gl_Color; 

     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
     gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 

     vel = velocity; 
} 

...和我的片段着色器相关的摘录,简化了调试:

#version 120 
#extension GL_ARB_texture_rectangle : enable 
varying vec3 vel; 
uniform sampler2DRect tex; 
uniform float winWidth; 
uniform float winHeight; 

void main() { 
     vec4 texColor = texture2DRect(tex, gl_TexCoord[0].st); 
     gl_FragColor = texColor; 
} 

回答

3

而不是gl_TexCoord[0].st你需要gl_PointCoord.st

+0

谢谢,但这似乎没有任何区别。有什么方法可以调试着色器,以确保正确的纹理绑定到'sampler2DRect tex'?在过去那部分工作刚刚完成,但我从来不确定如何或为什么。 'texture2DRect'是否采用'vec2([0.0 - 1.0],[0.0 - 1.0])'格式的第二个参数?我找不到任何文档。 – Ian 2011-05-01 15:59:45

+0

建立你的答案(所以我会继续接受它)。 'texture2DRect'似乎想要窗口坐标。做'gl_PointCoord.st * vec2(winWidth,winHeight)'给了我每个点的全部纹理。从这里可以很容易地看到,为了让纹理像素在每个点后面“像”texture2DRect(tex,gl_FragCoord.st +(gl_PointCoord.st * vec2(2.0,2.0)+ vec2(-1.0, - 1.0)))'。谢谢! – Ian 2011-05-01 16:30:07