summaryrefslogtreecommitdiffstats
path: root/balls.c
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2024-10-30 12:30:48 -0400
committerSam Anthony <sam@samanthony.xyz>2024-10-30 12:30:48 -0400
commit070fc3909cd954def7e70592d222eea29b0ce902 (patch)
tree385f30401be4e1d5192294ecb5ab00a1b1fd2ddd /balls.c
parent5023e0a4bac400f7eea9bc0bdaef9d6a952c4d70 (diff)
downloadballs-070fc3909cd954def7e70592d222eea29b0ce902.zip
parameterize number of balls
Diffstat (limited to 'balls.c')
-rw-r--r--balls.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/balls.c b/balls.c
index 54197e9..b1c12d5 100644
--- a/balls.c
+++ b/balls.c
@@ -28,8 +28,8 @@
enum { WIDTH = 640, HEIGHT = 480 };
enum { KEY_QUIT = 'q' };
+enum { NBALLS_DEFAULT = 3 };
enum {
- NBALLS = 8,
CIRCLE_POINTS = 32+2, /* +2 for center point and last point which overlaps with first point. */
};
@@ -62,6 +62,7 @@ float2 *noOverlapPositions(int n);
void frameCount(void);
void drawString(const char *str);
+int nBalls;
cl_context context;
cl_program prog;
cl_command_queue queue;
@@ -72,6 +73,14 @@ Partition collisionPartition;
int
main(int argc, char *argv[]) {
+ nBalls = NBALLS_DEFAULT;
+ if (argc > 1) {
+ if (sscanf(argv[1], "%d", &nBalls) != 1 || nBalls < 1) {
+ printf("usage: balls [number of balls]\n");
+ return 1;
+ }
+ }
+
initGL(argc, argv);
initCL();
@@ -209,15 +218,15 @@ setPositions(void) {
int err;
/* Generate initial ball positions. */
- hostPositions = noOverlapPositions(NBALLS);
+ hostPositions = noOverlapPositions(nBalls);
/* Create device-side buffer. */
- positions = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, NBALLS*sizeof(float2), hostPositions, &err);
+ positions = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, nBalls*sizeof(float2), hostPositions, &err);
if (err < 0)
sysfatal("Failed to allocate position buffer.\n");
/* Copy positions to device. */
- err = clEnqueueWriteBuffer(queue, positions, CL_TRUE, 0, NBALLS*sizeof(float2), hostPositions, 0, NULL, NULL);
+ err = clEnqueueWriteBuffer(queue, positions, CL_TRUE, 0, nBalls*sizeof(float2), hostPositions, 0, NULL, NULL);
if (err < 0)
sysfatal("Failed to copy ball positions to device.\n");
@@ -230,18 +239,18 @@ setVelocities(void) {
int i, err;
/* Generate initial ball velocities. */
- if ((hostVelocities = malloc(NBALLS*sizeof(float2))) == NULL)
+ if ((hostVelocities = malloc(nBalls*sizeof(float2))) == NULL)
sysfatal("Failed to allocate velocity array.\n");
- for (i = 0; i < NBALLS; i++)
+ for (i = 0; i < nBalls; i++)
hostVelocities[i] = randVec(-VMAX_INIT, VMAX_INIT, -VMAX_INIT, VMAX_INIT);
/* Create device-side buffer. */
- velocities = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, NBALLS*sizeof(float2), hostVelocities, &err);
+ velocities = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, nBalls*sizeof(float2), hostVelocities, &err);
if (err < 0)
sysfatal("Failed to allocate velocity buffer.\n");
/* Copy velocities to device. */
- err = clEnqueueWriteBuffer(queue, velocities, CL_TRUE, 0, NBALLS*sizeof(float2), hostVelocities, 0, NULL, NULL);
+ err = clEnqueueWriteBuffer(queue, velocities, CL_TRUE, 0, nBalls*sizeof(float2), hostVelocities, 0, NULL, NULL);
if (err < 0)
sysfatal("Failed to copy ball velocities to device.\n");
@@ -254,18 +263,18 @@ setRadii(void) {
int i, err;
/* Generate radii. */
- if ((hostRadii = malloc(NBALLS*sizeof(float))) == NULL)
+ if ((hostRadii = malloc(nBalls*sizeof(float))) == NULL)
sysfatal("Failed to allocate radii array.\n");
- for (i = 0; i < NBALLS; i++)
+ for (i = 0; i < nBalls; i++)
hostRadii[i] = randFloat(RMIN, RMAX);
/* Create device-side buffer. */
- radii = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, NBALLS*sizeof(float), hostRadii, &err);
+ radii = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, nBalls*sizeof(float), hostRadii, &err);
if (err <0)
sysfatal("Failed to allocate radii buffer.\n");
/* Copy radii to device. */
- err = clEnqueueWriteBuffer(queue, radii, CL_TRUE, 0, NBALLS*sizeof(float), hostRadii, 0, NULL, NULL);
+ err = clEnqueueWriteBuffer(queue, radii, CL_TRUE, 0, nBalls*sizeof(float), hostRadii, 0, NULL, NULL);
if (err < 0)
sysfatal("Failed to copy radii to device.\n");
@@ -276,7 +285,7 @@ void
setCollisions(void) {
int i, err;
- collisionPartition = partitionCollisions(NBALLS);
+ collisionPartition = partitionCollisions(nBalls);
printf("Collision partition:\n");
printPartition(collisionPartition);
@@ -314,7 +323,7 @@ void
genVertexBuffer(void) {
glGenBuffers(1, &vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
- glBufferData(GL_ARRAY_BUFFER, NBALLS*CIRCLE_POINTS*2*sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, nBalls*CIRCLE_POINTS*2*sizeof(GLfloat), NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
}
@@ -326,9 +335,9 @@ setColors(void) {
GLfloat color[3];
int i, j;
- if ((colors = malloc(NBALLS*CIRCLE_POINTS*3*sizeof(GLfloat))) == NULL)
+ if ((colors = malloc(nBalls*CIRCLE_POINTS*3*sizeof(GLfloat))) == NULL)
sysfatal("Failed to allocate color array.\n");
- for (i = 0; i < NBALLS; i++) {
+ for (i = 0; i < nBalls; i++) {
color[0] = randFloat(0, 1);
color[1] = randFloat(0, 1);
color[2] = randFloat(0, 1);
@@ -340,7 +349,7 @@ setColors(void) {
}
glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
- glBufferData(GL_ARRAY_BUFFER, NBALLS*CIRCLE_POINTS*3*sizeof(GLfloat), colors, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, nBalls*CIRCLE_POINTS*3*sizeof(GLfloat), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
@@ -393,7 +402,7 @@ display(void) {
genVertices();
glBindVertexArray(vertexVAO);
- for (i = 0; i < NBALLS; i++)
+ for (i = 0; i < nBalls; i++)
glDrawArrays(GL_TRIANGLE_FAN, i*CIRCLE_POINTS, CIRCLE_POINTS);
glBindVertexArray(0);
@@ -419,7 +428,7 @@ move(void) {
size_t size;
int err;
- size = NBALLS;
+ size = nBalls;
err = clEnqueueNDRangeKernel(queue, moveKernel, 1, NULL, &size, NULL, 0, NULL, NULL);
if (err < 0)
sysfatal("Couldn't enqueue kernel.\n");
@@ -430,7 +439,7 @@ collideWalls(void) {
size_t size;
int err;
- size = NBALLS;
+ size = nBalls;
err = clEnqueueNDRangeKernel(queue, collideWallsKernel, 1, NULL, &size, NULL, 0, NULL, NULL);
if (err < 0)
sysfatal("Couldn't enqueue kernel.\n");
@@ -463,7 +472,7 @@ genVertices(void) {
sysfatal("Couldn't acquire the GL objects.\n");
localSize = CIRCLE_POINTS;
- globalSize = NBALLS * localSize;
+ globalSize = nBalls * localSize;
err = clEnqueueNDRangeKernel(queue, genVerticesKernel, 1, NULL, &globalSize, &localSize, 0, NULL, &kernelEvent);
if (err < 0)
sysfatal("Couldn't enqueue kernel.\n");
@@ -576,6 +585,10 @@ compileShader(GLint shader) {
}
}
+/*
+ * Generate n circle coordinates such that none overlap even if all circles
+ * have the maximum radius.
+ */
float2 *
noOverlapPositions(int n) {
float2 *ps;