Hi everyone,
I am trying to add color to those nice particles, but it seems I can’t do that. Here’s my code:
void ofApp::draw(){
opencl.finish();
ofFloatColor *colorPointer = &color[0];
//glColor3f(1.0f, 1.0f, 1.0f);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
opencl.finish();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(ofFloatColor), colorPointer );
glVertexPointer(2, GL_FLOAT, 0, 0);
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
Now, color is a simple array, with NUM_PARTICLES size, of type ofColor filled with random colors:
for(int i=0; i<NUM_PARTICLES; i++) {
Particle &p = particles[i];
p.vel.set(0, 0);
p.mass = ofRandom(0.5, 1);
color[i].set((ofRandom(1),ofRandom(1),ofRandom(1)));
particlePos[i].set(ofRandomWidth(), ofRandomHeight());
}
Maybe there is something wrong in my glColorPointer. I’d greatly appreciate any help, thank you!
Update - I almost have this now but I want to update the particle colours at the same time as their positions. This appears to be causing an error; am I missing something?
Approach taken so far is as follows:
-
produce a second vbo object similar to that which stores particle position but that contains float3 items; fill these with random ofFloat colour profiles
-
so in setup():
opencl.setupFromOpenGL();
// create vbo
glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float2) * NUM_PARTICLES, 0, GL_DYNAMIC_COPY_ARB);
// create cbo
glGenBuffersARB(1, &cbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float3) * NUM_PARTICLES, 0, GL_DYNAMIC_COPY_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
// init host and CL buffers
particles.initBuffer(NUM_PARTICLES);
particlePos.initFromGLObject(vbo, NUM_PARTICLES);
particleCos.initFromGLObject(cbo, NUM_PARTICLES);
// init data
for(int i=0; i<NUM_PARTICLES; i++) {
Particle &p = particles[i];
p.vel.set(0, 0);
p.mass = ofRandom(0.5, 1);
particleCos[i].set(ofRandom(1),ofRandom(1),ofRandom(1));
particlePos[i].set(ofRandomWidth(), ofRandomHeight());
}
particles.writeToDevice();
particlePos.writeToDevice();
particleCos.writeToDevice();
opencl.loadProgramFromFile("MSAOpenCL/Particle.cl");
opencl.loadKernel("updateParticle");
opencl.kernel("updateParticle")->setArg(0, particles);
opencl.kernel("updateParticle")->setArg(1, particlePos);
opencl.kernel("updateParticle")->setArg(2, mousePos);
opencl.kernel("updateParticle")->setArg(3, dimensions);
opencl.kernel("updateParticle")->setArg(4, particleCos);
-
update() remains the same and then, in draw():
opencl.finish();
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glVertexPointer(2, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cbo);
glColorPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glPointSize(1);
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
opencl.finish();
-
finally, in particle.cl file I add an extra global argument to the function ‘updateParticle’, giving:
__kernel void updateParticle(__global Particle* particles, __global float2* posBuffer, const float2 mousePos, const float2 dimensions, __global float3* cosBuffer){
int id = get_global_id(0);
__global Particle *p = &particles[id];
float2 diff = mousePos - posBuffer[id];
float invDistSQ = 1.0f / dot(diff, diff);
diff *= MOUSE_FORCE * invDistSQ;
p->vel += (dimensions*0.5f - posBuffer[id]) * CENTER_FORCE - diff* p->mass;
float speed2 = dot(p->vel, p->vel);
if(speed2<MIN_SPEED) posBuffer[id] = mousePos + diff * (1.0f + p->mass);
posBuffer[id] += p->vel;
p->vel *= DAMP;
//cosBuffer[id]+=1;
}
The above runs perfectly, with random colours assigned to each particle, until I comment in the line: cosBuffer[id]+=1; At this point it throws a crash.
I was assuming that adding this line would allow me to manipulate and update individual particle colours via the second vbo object. What am I doing wrong? I recon it must be a pretty simple solution, but can’t figure it out. Can anyone help?
S
1 Like
well, here’s the point where it is pausing up, in the MSAOpenCLKernel.cpp:
cl_int OpenCLKernel::unbindOpenGLInterOp(){
cl_int err = CL_SUCCESS;
if (!mOpenGLInteropArguments.empty()){
// we have to release our opengl interop objects, if we acquired them earlier.
err = clEnqueueReleaseGLObjects(pOpenCL->getQueue(), mOpenGLInteropArguments.size() , mOpenGLInteropArguments.data(), 0, NULL, NULL);
}
return err;
}
I don’t have much of a clue as to why, other than it looks like a binding issue. Pretty stumped…
In my experience openCL doesn’t deal really well with float3 variables. Instead of that you should use a float4 with some 0.0 number in the fourth value. Anyway I used ofFloatColor as a float4 because it actually has 4 values, the fourth being the alpha channel.
In the openCL kernel, why would you sum 1 to your float color? It is in the range 0. 1. so a +1 would go out of range.
ARG, indeed it does look like it was a result of the difference between float3 and float4. That’s two days of my life I’ll never get back!
(the a+1 was just me being clumsy, and of no consequence)
Good to know though, many thanks for pointing that one out.
S
1 Like