Skip to content

Instantly share code, notes, and snippets.

@ddemidov
Last active June 8, 2020 21:47
Show Gist options
  • Save ddemidov/930d26fce09891a7be9e to your computer and use it in GitHub Desktop.
Save ddemidov/930d26fce09891a7be9e to your computer and use it in GitHub Desktop.
VexCL - OpenGL interaction
#include <iostream>
#include <memory>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/glx.h>
#include <vexcl/vexcl.hpp>
int n = 4096;
float t = 0;
float dt = 1e-2;
std::shared_ptr<cl::Context> c;
std::shared_ptr<cl::CommandQueue> q;
GLuint gl_buf = 0;
//---------------------------------------------------------------------------
VEX_FUNCTION(cl_float2, update_positions, (int, n)(int, i)(float, t),
float h = 2.0f / (n - 1);
float2 p = {i * h - 1, sin(h * i * i - t) / 2};
return p;
);
//---------------------------------------------------------------------------
void display() {
// Clear screen
glClear(GL_COLOR_BUFFER_BIT);
{
glFinish();
cl_mem cl_buf = clCreateFromGLBuffer((*c)(), CL_MEM_READ_WRITE, gl_buf, 0);
clEnqueueAcquireGLObjects((*q)(), 1, &cl_buf, 0, 0, 0);
// Wrap CL buffer into vex::vector.
vex::vector<cl_float2> p(*q, cl::Buffer(cl_buf));
// Update positions using vexcl function.
t += dt;
p = update_positions(n, vex::element_index(), t);
clEnqueueReleaseGLObjects((*q)(), 1, &cl_buf, 0, 0, 0);
q->finish();
}
// Draw points
glColor4f(1.0, 1.0, 0.25, 0.9);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPointSize(2);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, gl_buf);
glVertexPointer(2, GL_FLOAT, 0, NULL);
glDrawArrays(GL_POINTS, 0, n);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
// Refresh screen
glutSwapBuffers();
glutPostRedisplay();
}
//---------------------------------------------------------------------------
void keyboard( unsigned char key, int x, int y) {
const char esc = 27;
switch(key) {
case esc:
case 'q':
exit (0);
}
}
//---------------------------------------------------------------------------
int initGL(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(800, 600);
glutCreateWindow("Hello");
glewInit();
glOrtho(-1, 1, -1, 1, -1, 1);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
return 1;
}
//---------------------------------------------------------------------------
int main(int argc, char *argv[]) {
// Initialize OpenGL
if ( !initGL(argc, argv) ) return 1;
// Create GL Buffer.
glGenBuffers(1, &gl_buf);
glBindBuffer(GL_ARRAY_BUFFER, gl_buf);
glBufferData(GL_ARRAY_BUFFER, n * sizeof(cl_float2), NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Create OpenCL context and command queue.
* Need to create those explicitly, since vex::Context does not
* support specification of context_properties
*/
// Get one device that supports GL interoperation.
std::vector<cl::Device> device = vex::backend::device_list(
vex::Filter::Env &&
vex::Filter::GLSharing &&
vex::Filter::Count(1)
);
// Create OpenCL context from OpenGL context.
cl_context_properties ctx_prop[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)device[0].getInfo<CL_DEVICE_PLATFORM>(),
0
};
c = std::make_shared<cl::Context>(device, ctx_prop);
// Create command queue.
q = std::make_shared<cl::CommandQueue>(*c, device[0]);
std::cout << *q << std::endl;
// Enter the glut loop.
glutMainLoop();
}
hello: hello.cpp
g++ -std=c++0x -O3 -o hello hello.cpp -I$(VEXCL_ROOT) \
-lGL -lglut -lGLEW -lOpenCL -lboost_system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment