Forge
opencl/plotting.cpp
/*******************************************************
* Copyright (c) 2015-2019, ArrayFire
* All rights reserved.
*
* This file is distributed under 3-clause BSD license.
* The complete license agreement can be obtained at:
* http://arrayfire.com/licenses/BSD-3-Clause
********************************************************/
#include <forge.h>
#include "cl_helpers.h"
#include <mutex>
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace cl;
using namespace std;
const unsigned DIMX = 1000;
const unsigned DIMY = 800;
const float dx = 0.1;
const float FRANGE_START = 0.f;
const float FRANGE_END = 2 * 3.141592f;
const unsigned DATA_SIZE = ( FRANGE_END - FRANGE_START ) / dx;
#define USE_FORGE_OPENCL_COPY_HELPERS
#include <ComputeCopy.h>
static const std::string sinf_ocl_kernel = R"(
kernel void sinf(global float* out, const float dx, const unsigned DATA_SIZE, int fnCode)
{
unsigned x = get_global_id(0);
if(x < DATA_SIZE) {
out[2 * x] = x * dx ;
switch(fnCode) {
case 0:
out[ 2 * x + 1 ] = sin(x*dx);
break;
case 1:
out[ 2 * x + 1 ] = cos(x*dx);
break;
case 2:
out[ 2 * x + 1 ] = tan(x*dx);
break;
case 3:
out[ 2 * x + 1 ] = log10(x*dx);
break;
}
}
}
)";
void kernel(cl::Buffer& devOut, cl::CommandQueue& queue, int fnCode)
{
static std::once_flag compileFlag;
static cl::Program prog;
static cl::Kernel kern;
std::call_once(compileFlag,
[queue]() {
prog = cl::Program(queue.getInfo<CL_QUEUE_CONTEXT>(), sinf_ocl_kernel, true);
kern = cl::Kernel(prog, "sinf");
});
static const NDRange global(DATA_SIZE * 2);
kern.setArg(0, devOut);
kern.setArg(1, dx);
kern.setArg(2, DATA_SIZE);
kern.setArg(3, fnCode);
queue.enqueueNDRangeKernel(kern, cl::NullRange, global);
}
int main(void)
{
try {
/*
* First Forge call should be a window creation call
* so that necessary OpenGL context is created for any
* other forge::* object to be created successfully
*/
forge::Window wnd(DIMX, DIMY, "Plotting Demo");
wnd.makeCurrent();
chart.setAxesLimits(FRANGE_START, FRANGE_END, -1.0f, 1.0f);
/* Create several plot objects which creates the necessary
* vertex buffer objects to hold the different plot types
*/
forge::Plot plt0 = chart.plot(DATA_SIZE, forge::f32); //create a default plot
forge::Plot plt1 = chart.plot(DATA_SIZE, forge::f32, FG_PLOT_LINE, FG_MARKER_NONE); //or specify a specific plot type
forge::Plot plt2 = chart.plot(DATA_SIZE, forge::f32, FG_PLOT_LINE, FG_MARKER_TRIANGLE); //last parameter specifies marker shape
forge::Plot plt3 = chart.plot(DATA_SIZE, forge::f32, FG_PLOT_SCATTER, FG_MARKER_CROSS);
/*
* Set plot colors
*/
plt2.setColor(FG_YELLOW); //use a forge predefined color
plt3.setColor((forge::Color) 0x257973FF); //or any hex-valued color
/*
* Set plot legends
*/
plt0.setLegend("Sine");
plt1.setLegend("Cosine");
plt2.setLegend("Tangent");
plt3.setLegend("Log base 10");
/*
* Helper function to create a CLGL interop context.
* This function checks for if the extension is available
* and creates the context on the appropriate device.
* Note: context and queue are defined in cl_helpers.h
*/
context = createCLGLContext(wnd);
Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
queue = CommandQueue(context, device);
cl::Buffer sinOut(context, CL_MEM_READ_WRITE, sizeof(float) * DATA_SIZE * 2);
cl::Buffer cosOut(context, CL_MEM_READ_WRITE, sizeof(float) * DATA_SIZE * 2);
cl::Buffer tanOut(context, CL_MEM_READ_WRITE, sizeof(float) * DATA_SIZE * 2);
cl::Buffer logOut(context, CL_MEM_READ_WRITE, sizeof(float) * DATA_SIZE * 2);
kernel(sinOut, queue, 0);
kernel(cosOut, queue, 1);
kernel(tanOut, queue, 2);
kernel(logOut, queue, 3);
GfxHandle* handles[4];
createGLBuffer(&handles[0], plt0.vertices(), FORGE_VERTEX_BUFFER);
createGLBuffer(&handles[1], plt1.vertices(), FORGE_VERTEX_BUFFER);
createGLBuffer(&handles[2], plt2.vertices(), FORGE_VERTEX_BUFFER);
createGLBuffer(&handles[3], plt3.vertices(), FORGE_VERTEX_BUFFER);
/* copy your data into the vertex buffer object exposed by
* forge::Plot class and then proceed to rendering.
* To help the users with copying the data from compute
* memory to display memory, Forge provides copy headers
* along with the library to help with this task
*/
copyToGLBuffer(handles[0], (ComputeResourceHandle)sinOut(), plt0.verticesSize());
copyToGLBuffer(handles[1], (ComputeResourceHandle)cosOut(), plt1.verticesSize());
copyToGLBuffer(handles[2], (ComputeResourceHandle)tanOut(), plt2.verticesSize());
copyToGLBuffer(handles[3], (ComputeResourceHandle)logOut(), plt3.verticesSize());
do {
wnd.draw(chart);
} while(!wnd.close());
releaseGLBuffer(handles[0]);
releaseGLBuffer(handles[1]);
releaseGLBuffer(handles[2]);
releaseGLBuffer(handles[3]);
}catch (forge::Error err) {
std::cout << err.what() << "(" << err.err() << ")" << std::endl;
} catch (cl::Error err) {
std::cout << err.what() << "(" << err.err() << ")" << std::endl;
}
return 0;
}
FG_MARKER_TRIANGLE
@ FG_MARKER_TRIANGLE
Triangle marker.
Definition: defines.h:171
forge.h
forge::Plot
Plot is a line graph to display two dimensional data.
Definition: plot.h:198
FG_MARKER_NONE
@ FG_MARKER_NONE
No marker.
Definition: defines.h:167
FG_PLOT_SCATTER
@ FG_PLOT_SCATTER
Scatter plot.
Definition: defines.h:162
forge::Error::what
virtual const char * what() const
Definition: exception.h:60
ComputeResourceHandle
void * ComputeResourceHandle
A backend-agnostic handle to a compute memory resource originating from an OpenGL resource.
Definition: ComputeCopy.h:73
forge::Error
Definition: exception.h:28
forge::Window
Window is where other objects such as Images, Plots etc. are rendered.
Definition: window.h:300
forge::Plot::setLegend
FGAPI void setLegend(const char *pLegend)
Set plot legend.
forge::Plot::vertices
FGAPI unsigned vertices() const
Get the buffer identifier for vertices.
forge::Plot::setColor
FGAPI void setColor(const forge::Color pColor)
Set the color of line graph(plot)
FG_RED
@ FG_RED
Definition: defines.h:140
FG_PLOT_LINE
@ FG_PLOT_LINE
Line plot.
Definition: defines.h:161
forge::Error::err
ErrorCode err() const
Definition: exception.h:45
forge::Plot::verticesSize
FGAPI unsigned verticesSize() const
Get the vertex buffer size in bytes.
FORGE_VERTEX_BUFFER
@ FORGE_VERTEX_BUFFER
OpenGL Vertex Buffer Object.
Definition: ComputeCopy.h:77
FG_MARKER_CROSS
@ FG_MARKER_CROSS
Cross-hair marker.
Definition: defines.h:172
FG_CHART_2D
@ FG_CHART_2D
Two dimensional charts.
Definition: defines.h:118
fg_color
fg_color
Definition: defines.h:139
FG_BLUE
@ FG_BLUE
Definition: defines.h:142
GfxHandle
Definition: ComputeCopy.h:80
forge::Chart
Chart is base canvas where other plottable objects are rendered.
Definition: chart.h:316
ComputeCopy.h
FG_YELLOW
@ FG_YELLOW
Definition: defines.h:143
forge::f32
@ f32
Definition: defines.h:193