Commit 132598d0 authored by Miklós Homolya's avatar Miklós Homolya

sample Qt + OpenGL + CUDA example (without camera)

parent b4ddfe2e
#include "glwidget.h"
#include "kernel.h"
#include <QGLFunctions>
#include <cuda_runtime_api.h>
#include <cuda_gl_interop.h>
GLuint positionsVBO;
struct cudaGraphicsResource* positionsVBO_CUDA;
GlWidget::GlWidget(QWidget *parent)
: QGLWidget(QGLFormat(), parent), func(context()), start(time(NULL))
{
}
GlWidget::~GlWidget()
{
}
QSize GlWidget::sizeHint() const
{
return QSize(640, 480);
}
void GlWidget::initializeGL()
{
makeCurrent();
// Explicitly set device 0
cudaGLSetGLDevice(0);
// Create buffer object and register it with CUDA
func.glGenBuffers(1, &positionsVBO);
func.glBindBuffer(GL_ARRAY_BUFFER, positionsVBO);
size_t size = (size_t)640 * 480 * 4 * sizeof(float); // TODO
func.glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
func.glBindBuffer(GL_ARRAY_BUFFER, 0);
cudaGraphicsGLRegisterBuffer(&positionsVBO_CUDA, positionsVBO, cudaGraphicsMapFlagsWriteDiscard);
}
void GlWidget::paintGL()
{
// Map buffer object for writing from CUDA
float4* positions;
cudaGraphicsMapResources(1, &positionsVBO_CUDA, 0);
size_t num_bytes;
cudaGraphicsResourceGetMappedPointer((void**)&positions, &num_bytes, positionsVBO_CUDA);
// Execute kernel
executeKernel(positions, 640, 480, float(time(0) - start) * 0.1);
// Unmap buffer object
cudaGraphicsUnmapResources(1, &positionsVBO_CUDA, 0);
// Render from buffer object
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
func.glBindBuffer(GL_ARRAY_BUFFER, positionsVBO);
glVertexPointer(4, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, 640 * 480); // TODO
glDisableClientState(GL_VERTEX_ARRAY);
}
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
#include <QGLFunctions>
class GlWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GlWidget(QWidget *parent = 0);
~GlWidget();
QSize sizeHint() const;
protected:
void initializeGL();
void paintGL();
private:
QGLFunctions func;
time_t start;
};
#endif // GLWIDGET_H
QT += core gui opengl
CONFIG += debug
TARGET = hello-opengl
TEMPLATE = app
SOURCES += main.cpp glwidget.cpp
HEADERS += glwidget.h kernel.h
CUDA_SOURCES += kernel.cu
LIBS += -lGLEW -lcuda -lcudart
# Path to cuda toolkit install
CUDA_DIR = /usr/
# Path to header and libs files
INCLUDEPATH += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib
# GPU architecture
CUDA_ARCH = sm_10
NVCCFLAGS = --compiler-options -use_fast_math --ptxas-options=-v
CUDA_INC = $$join(INCLUDEPATH,' -I','-I',' ')
cuda.commands = $$CUDA_DIR/bin/nvcc -m64 -O3 -arch=$$CUDA_ARCH -c $$NVCCFLAGS $$CUDA_INC $$LIBS ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
cuda.dependency_type = TYPE_C
cuda.depend_command = $$CUDA_DIR/bin/nvcc -O3 -M $$CUDA_INC $$NVCCFLAGS ${QMAKE_FILE_NAME}
cuda.input = CUDA_SOURCES
cuda.output = ${OBJECTS_DIR}${QMAKE_FILE_BASE}_cuda.o
# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda
#include "kernel.h"
__global__ void createVertices(float4* positions, float time, unsigned int width, unsigned int height)
{
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
// Calculate uv coordinates
float u = x / (float)width;
float v = y / (float)height;
u = u * 2.0f - 1.0f;
v = v * 2.0f - 1.0f;
// calculate simple sine wave pattern
float freq = 4.0f;
float w = sinf(u * freq + time)
* cosf(v * freq + time) * 0.5f;
// Write positions
positions[y * width + x] = make_float4(u, w, v, 1.0f);
}
void executeKernel(void *positions_, int width, int height, float time)
{
float4 *positions = (float4 *)positions_;
dim3 dimBlock(16, 16, 1);
dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
createVertices<<<dimGrid, dimBlock>>>(positions, time, width, height);
}
#ifndef _KERNEL_H
#define _KERNEL_H
extern "C" void executeKernel(void *positions_, int width, int height, float time);
#endif // _KERNEL_H
#include <QApplication>
#include "glwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
GlWidget w;
w.show();
return app.exec();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment