void display(void) { pthread_mutex_lock(&display_mutex); if (!ref_file) { sdkStartTimer(&timer); simulateFluids(); } // render points from vertex buffer glClear(GL_COLOR_BUFFER_BIT); glClearColor(1.f/256*172, 1.f/256*101, 1.f/256*4, 0.f); glColor4f(1.f, 1.f, 1.f, 0.5f); glPointSize(1); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); #ifdef OPTIMUS glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(cData) * DS, particles, GL_DYNAMIC_DRAW_ARB); #endif glVertexPointer(2, GL_FLOAT, 0, NULL); glDrawArrays(GL_POINTS, 0, DS); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); if (ref_file) { return; } // Finish timing before swap buffers to avoid refresh sync sdkStopTimer(&timer); glutSwapBuffers(); fpsCount++; if (fpsCount == fpsLimit) { char fps[256]; float ifps = 1.f / (sdkGetAverageTimerValue(&timer) / 1000.f); sprintf(fps, "Caffe Macchiato / Stable Fluids (%d x %d): %3.1f fps", DIM, DIM, ifps); glutSetWindowTitle(fps); fpsCount = 0; fpsLimit = (int)MAX(ifps, 1.f); sdkResetTimer(&timer); } glutPostRedisplay(); pthread_mutex_unlock(&display_mutex); }
void autoTest(char **argv) { CFrameBufferObject *fbo = new CFrameBufferObject(wWidth, wHeight, 4, false, GL_TEXTURE_2D); g_CheckRender = new CheckFBO(wWidth, wHeight, 4, fbo); g_CheckRender->setPixelFormat(GL_RGBA); g_CheckRender->setExecPath(argv[0]); g_CheckRender->EnableQAReadback(true); fbo->bindRenderPath(); reshape(wWidth, wHeight); for (int count=0; count<g_iFrameToCompare; count++) { simulateFluids(); // add in a little force so the automated testing is interesing. if (ref_file) { int x = wWidth/(count+1); int y = wHeight/(count+1); float fx = (x / (float)wWidth); float fy = (y / (float)wHeight); int nx = (int)(fx * DIM); int ny = (int)(fy * DIM); int ddx = 35; int ddy = 35; fx = ddx / (float)wWidth; fy = ddy / (float)wHeight; int spy = ny-FR; int spx = nx-FR; addForces(dvfield, DIM, DIM, spx, spy, FORCE * DT * fx, FORCE * DT * fy, FR); lastx = x; lasty = y; } } display(); fbo->unbindRenderPath(); // compare to offical reference image, printing PASS or FAIL. printf("> (Frame %d) Readback BackBuffer\n", 100); g_CheckRender->readback(wWidth, wHeight); g_CheckRender->savePPM("fluidsGL.ppm", true, NULL); if (!g_CheckRender->PPMvsPPM("fluidsGL.ppm", ref_file, MAX_EPSILON_ERROR, 0.25f)) { g_TotalErrors++; } }
void display(void) { if (!ref_file) { sdkStartTimer(&timer); simulateFluids(); } // render points from vertex buffer glClear(GL_COLOR_BUFFER_BIT); glColor4f(0,1,0,0.5f); glPointSize(1); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); glVertexPointer(2, GL_FLOAT, 0, NULL); glDrawArrays(GL_POINTS, 0, DS); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); if (ref_file) { return; } // Finish timing before swap buffers to avoid refresh sync sdkStopTimer(&timer); glutSwapBuffers(); fpsCount++; if (fpsCount == fpsLimit) { char fps[256]; float ifps = 1.f / (sdkGetAverageTimerValue(&timer) / 1000.f); sprintf(fps, "Cuda/GL Stable Fluids (%d x %d): %3.1f fps", DIM, DIM, ifps); glutSetWindowTitle(fps); fpsCount = 0; fpsLimit = (int)MAX(ifps, 1.f); sdkResetTimer(&timer); } glutPostRedisplay(); }
GLFluids::GLFluids(QWidget *parent) : QGLWidget(parent), QGLFunctions() { vbo = 0; wWidth = qMax(512, DIM); wHeight = qMax(512, DIM); hvfield = (float2 *)malloc(sizeof(float2) * DS); memset(hvfield, 0, sizeof(float2) * DS); // Allocate and initialize device data cudaMallocPitch((void **)&dvfield, &tPitch, sizeof(float2)*DIM, DIM); cudaMemcpy(dvfield, hvfield, sizeof(float2) * DS, cudaMemcpyHostToDevice); // Temporary complex velocity field data cudaMalloc((void **)&vxfield, sizeof(float2) * PDS); cudaMalloc((void **)&vyfield, sizeof(float2) * PDS); setup_texture(DIM, DIM); bind_texture(); // Create particle array particles = (float2 *)malloc(sizeof(float2) * DS); memset(particles, 0, sizeof(float2) * DS); initParticles(particles, DIM, DIM); // Create CUFFT transform plan configuration cufftPlan2d(&planr2c, DIM, DIM, CUFFT_R2C); cufftPlan2d(&planc2r, DIM, DIM, CUFFT_C2R); // TODO: update kernels to use the new unpadded memory layout for perf // rather than the old FFTW-compatible layout cufftSetCompatibilityMode(planr2c, CUFFT_COMPATIBILITY_FFTW_PADDING); cufftSetCompatibilityMode(planc2r, CUFFT_COMPATIBILITY_FFTW_PADDING); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, [&](){ simulateFluids(); updateGL(); }); timer->start(0); }