Chaps,
I've been trying to move my particle system over to shaders (which I am trying to fathom as I go along) but I've reached a complete standstill and would really appreciate some advice. I have reduced my code to the simplest form I can - one textured quad. But I still cannot seem to provide, or get the shader to use, the texture coordinates set as an attribute. If I use a hardwired tex coord in the shader the colour is found correctly, so I think that texture is available and working. However when I try to use gl_TexCoord[0].st I just seem to always get the colour at 0,0 (I think). Unfortunately I can't find many examples in G3D to use a reference - the code I have is largely lifted from Draw::skyBox.
My draw code is:
void ParticleEmitter::Draw()
{
m_render_device->pushState();
m_render_device->setProjectionAndCameraMatrix(m_camera->GetProjection(), m_camera->GetCoordinateFrame());
m_render_device->setObjectToWorldMatrix(CoordinateFrame(GetOrientation().toRotationMatrix(), GetPosition()));
m_render_device->setCullFace(CullFace::NONE);
static Args args;
static shared_ptr<Shader> shader;
static bool init = true;
if (init)
{
Shader::Specification shaderSpec;
shaderSpec[Shader::VERTEX] = Shader::Source(STR(
void main()
{
gl_Position = g3d_ModelViewProjectionMatrix * gl_Vertex;
}));
shaderSpec[Shader::PIXEL] = Shader::Source(STR(
uniform sampler2D texture;
void main()
{
gl_FragColor = texture2D(texture, gl_TexCoord[0].st);
//gl_FragColor = texture2D(texture, vec2(0.4, 0.4));
}));
shader = Shader::create(shaderSpec);
args.geometryInput = PrimitiveType::QUADS;
float s = 5.0f;
// Used for the failed attempt to use Attribute arrays
//static Array<Vector4> positions;
//positions.append(Vector4(-s, -s, 0, 0)); // bottom left
//positions.append(Vector4(-s, +s, 0, 0)); // top left
//positions.append(Vector4(+s, +s, 0, 0)); // top right
//positions.append(Vector4(+s, -s, 0, 0)); // bottom right
static Array<Point3> point_positions;
point_positions.append(Point3(-s, -s, 0)); // bottom left
point_positions.append(Point3(-s, +s, 0)); // top left
point_positions.append(Point3(+s, +s, 0)); // top right
point_positions.append(Point3(+s, -s, 0)); // bottom right
static Array<Vector2> tex_coords;
tex_coords.append(Vector2(0, 0));
tex_coords.append(Vector2(0, 1));
tex_coords.append(Vector2(1, 1));
tex_coords.append(Vector2(1, 0));
static Array<int> indices;
indices.append(0, 1, 2, 3);
// Upload to GPU
//shared_ptr<VertexBuffer> vbuffer = VertexBuffer::create( (sizeof(Vector4) + sizeof(Vector2) ) * positions.size() + sizeof(int) * indices.size());
//AttributeArray gpuVertex = AttributeArray(positions, vbuffer);
//AttributeArray gpuTexCoord = AttributeArray(tex_coords, vbuffer);
//IndexStream gpuIndices = IndexStream(indices, vbuffer);
//args.setAttributeArray("gl_Vertex", gpuVertex);
//args.setAttributeArray("gl_MultiTexCoord0", gpuTexCoord);
//args.setIndexStream(gpuIndices);
args.setAttributePointer("gl_Vertex", point_positions);
args.setAttributePointer("gl_TexCoord", tex_coords);
args.setIndexPointer(indices);
init = false;
}
Texture::Ref particle_texture = Texture::fromFile("data/Textures/bling2.jpg");
args.setUniform("texture", particle_texture);
m_render_device->apply(shader, args);
m_render_device->popState();
}
From the code comments it seemed to me that the I should be *actually* be trying to use AttributeArrays? You can see from the commented out sections above how I tried to do this, but with even less success unfortunately - not only can I not seem to texture the quad, but I also appear to lose the gl_Vertex transformation too so I just get one massive untransformed coloured quad.
If you can spot my stupid mistake or point me to some existing example code/docs, I would be *very* grateful.
Cheers
E