How to use Open_GL

Hi, Im using 9800GT in Windows platform with Core2 CPU.

Im working with simple_GL sdk to figure out how to use open_gl for display. Following is my kernel code.

#ifndef _RESAMPLING_KERNEL_H_

#define _RESAMPLING_GL_KERNEL_H_

//definitions of constants..

.....

///

__global__ void doResample(int* a, cuComplex* d, float* e, float* f, float* g ){

	int AscanIdx = 8*blockIdx.x+threadIdx.x;

	int AscanPix = 64*blockIdx.y+threadIdx.y;

	int b = *a;

	float resampledspacing = *e;

	if(AscanIdx < XDIM)

	{

		if(AscanPix <YDIM){

			int i = int(g[AscanPix*2]);

			d[AscanIdx+AscanPix*XDIM].x = f[b*YDIM*XDIM+AscanIdx*YDIM+i]-g[AscanPix*2+1]*(f[b*YDIM*XDIM+AscanIdx*YDIM+i+1]-f[b*YDIM*XDIM+AscanIdx*YDIM+i])/resampledspacing;

			d[AscanIdx+AscanPix*XDIM].y = 0;

		}			

	}	

}

__global__ void ptr_Allocator(cuComplex* d, float4 *ptr){

	int AscanIdx = 8*blockIdx.x+threadIdx.x;

	int AscanPix = 64*blockIdx.y+threadIdx.y;

	if(AscanIdx < XDIM){

		if(AscanPix <YDIM){

				int offset = AscanIdx + AscanPix * XDIM;

				float u = 255 * d[offset].x/(65535);

				float w = 255 * d[offset].x/(65535);

				float x = 255 * d[offset].x/(65535);

				float y = 255;

				ptr[offset*4]= (u, w, x, y);

			}

	}

}

__global__ void frame_plus(int* a){

	*a = *a +1;

	if(*a >= 20) *a =0;

}

extern "C" void launch_kernel(int* a, cuComplex* d, float* e, float* f, float* g, float *ptr)

{

	dim3 bDim(8,64);

	dim3 gDim(XDIM/bDim.x,YDIM/bDim.y);

	doResample<<<gDim, bDim>>>(a, d, e, f, g);

	ptr_Allocator<<<gDim, bDim>>>(d, ptr);

	frame_plus<<<1,1>>>(a);

	

}

#endif

Im trying to use launch_kernel by calling on separate cpp using open gl. Can somebody help me with this? Thank you.

unless you want to get into your OS-specific windowing, use freeglut. If you want to display a 2D image, declare a pixel buffer object (PBO), register it with CUDA (to a cudaGraphicsResource), then map your cudaGraphicsResource, then get the mapped pointer (which will be a device pointer mapped to the PBO memory). Do whatever CUDA processing you want, using the mapped device pointer. Then, unmap your cudaGraphicsResource, copy your PBO to an OpenGL texture (not a CUDA texture), then draw it to a quad… Or at least, that’s how I did it.
You could also just memcpy your result from your kernel to a host-based array and use glDrawPixels on it.

By the way, have you looked at the programming guide? It has a pretty decent explanation of DirectX/OpenGL interop with CUDA (although be forewarned, the Driver API example with OpenGL is incorrect)

I followed what you wrote but the program asks me for header files. Following is my code.

#ifdef _WIN32

#  define WINDOWS_LEAN_AND_MEAN

#  define NOMINMAX

#  include <windows.h>

#endif

// includes, system

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <math.h>

// includes, GL

#include "../../../common/inc/GL/freeglut.h"

#include "../../../common/inc/dynlink/cuda_runtime_api_dynlink.h"

//#include <glew.h>

//#include <glut.h>

// includes

//#include <cuda_runtime.h>

//#include <cutil_inline.h>

//#include <cutil_gl_inline.h>

//#include <cutil_gl_error.h>

//#include <cuda_gl_interop.h>

//#include <vector_types.h>

//#include <rendercheck_gl.h>

//define variables

#define XDIM 1000 //original value 1000

#define YDIM 1024 //original value 1024

#define FRAMES 20

#define START_WAVELENGTH 7.5226E+02

#define WAVELENGTH_SPACING 8.6969E-02	

#define SECOND_ORDER_CORRECTION -4.2264E-06

#define THIRD_ORDER_CORRECTION 8.9511E-10

#define FOURTH_ORDER_CORRECTION -1.7987E-13

#define LINE_LENGTH 1024	//Note same as YDIM, should be fixed

#define CAPTURE_LINE_OFFSET 800

#define RESAMPLE_POINTS 1024

// variables into cuda

unsigned char a[XDIM*XDIM*YDIM];

float resamp_1D[LINE_LENGTH*2], orignal_cpu[XDIM*XDIM*YDIM];

float k_resampledspacing;

cuComplex *d_in;

float *dev_k_resampledspacing, *dc_subtracted;

int *dev_frame, *dev_sum;

float *dev_resamp, *dev_b;

// pbo variables

GLuint pbo;

struct cudaGraphicsResource *cuda_pbo_resource;

extern "C"

void launch_kernel(float* original_data, int* frame_num, cuComplex* d, float* k_resamp, float* dc_subtracted, float* resample, float4 *ptr);

// Read Data from file

void readData() {

	FILE *fp;

	long size;

	fp=fopen(inputfile, "rb");

	if (fp==NULL) perror ("Error opening data file");

	else {

		fseek (fp, 0, SEEK_END);

		size=ftell (fp);

		printf ("Size of joecornearadialvolume.unp: %ld bytes.\n",size);

		rewind (fp);

	}

	fread(a, 2, XDIM*YDIM*FRAMES, fp);

	fclose(fp);

}

void convertor(){

	for(int i=0;i<XDIM*YDIM*FRAMES; i++){

		original_cpu[i] = a[i]; 

	}

}

//simply use cudaGraphicsMapFlagsWriteDiscard as cudaGraphicsResource

void createVBO(GLuint* pixel_buffer, struct cudaGraphicsResource **cuda_pixel_resource)

{

	// create buffer object

	glGenBuffers(1, pixel_buffer);

	glBindBuffer(GL_ARRAY_BUFFER, *pixel_buffer);

	//register buffer on cuda

	unsigned int size = XDIM * YDIM * 4 * sizeof(float); 

	glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW); 

	glBindBuffer(GL_ARRAY_BUFFER, 0); 

	cutilSafeCall(cudaGraphicsGLRegisterBuffer(cuda_pixel_resource, *pixel_buffer, cudaGraphicsMapFlagsWriteDiscard);

}

void display() { 

	// Map buffer object for writing from CUDA 

	float4* pix_buff; 

	cudaGraphicsMapResources(1, &cuda_pbo_resource, 0); 

	size_t num_bytes; 

	cudaGraphicsResourceGetMappedPointer((void**)&pix_buff, &num_bytes, cuda_pbo_resource));

	// Execute kernel 

	// will execute by calling kernel.cu file

	launch_kernel(sum, dev_original, dev_frame, d_in, dev_k_resampledspacing, dc_subtracted, dev_resamp, pix_buff);

	// Unmap buffer object 

	cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0);

	//////////////////////////////////////////////////////////

	// Under is the part I do not understand clear

	//////////////////////////////////////////////////////////

	// copy to Open_gl texture

	// Render from buffer object 

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

	glBindBuffer(GL_ARRAY_BUFFER, pbo); 

	glVertexPointer(4, GL_FLOAT, 0, 0); 

	glEnableClientState(GL_VERTEX_ARRAY); 

	glDrawArrays(GL_POINTS, 0, XDIM * YDIM); 

	glDisableClientState(GL_VERTEX_ARRAY); 

	

	// Swap buffers 

	glutSwapBuffers(); 

	glutPostRedisplay(); 

}

void deleteVBO() { 

	cudaGraphicsUnregisterResource(cuda_pbo_resource); 

	glDeleteBuffers(1, &pbo);

}

int main() { 

	// Pre-Calculation

	readData();

	convertor(); //convert values into single float

	//Cuda Memory Allocation

	int frame = 0, sum =0;

	HANDLE_ERROR( cudaMalloc((void**)&dev_frame, sizeof(int)));

	HANDLE_ERROR( cudaMalloc((void**)&sum, sizeof(int)));

	HANDLE_ERROR( cudaMalloc((void**)&dev_orginal, sizeof(float)*FRAMES*XDIM*YDIM));

	HANDLE_ERROR( cudaMalloc((void**)&d_in,sizeof(cuComplex)*YDIM*XDIM));

	HANDLE_ERROR( cudaMalloc((void**)&dev_resamp, sizeof(float)*LINE_LENGTH*2));

	HANDLE_ERROR( cudaMalloc((void**)&dev_k_resampledspacing, sizeof(float)));

	HANDLE_ERROR( cudaMalloc((void**)&dc_subtracted, sizeof(float)*XDIM*YDIM));

		

	HANDLE_ERROR(cudaMemcpy(dev_k_resampledspacing, &k_resampledspacing, sizeof(float), cudaMemcpyHostToDevice));

	HANDLE_ERROR(cudaMemcpy(dev_resamp, resamp_1D, sizeof(float)*LINE_LENGTH*2, cudaMemcpyHostToDevice));

	HANDLE_ERROR(cudaMemcpy(dev_original, original_cpu, sizeof(float)*FRAMES*XDIM*YDIM, cudaMemcpyHostToDevice));

	HANDLE_ERROR(cudaMemcpy(dev_frame, &frame, sizeof(int), cudaMemcpyHostToDevice));

	HANDLE_ERROR(cudaMemcpy(dev_sum, &sum, sizeof(int), cudaMemcpyHostToDevice));

	// Explicitly set device 

	cudaGLSetGLDevice(0); 

	glutDisplayFunc(display);

	

	// Create buffer object and register it with CUDA 

	createVBO(&pbo, &cuda_pbo_resource);

	// Loop 

	glutMainLoop(); 

}

my code is under …/src/Resampling/Resampling and my header files are on …/commons/inc/GL

I have no idea why compiler cannot find the directory. Can somebody help me with this? Thank you

I actually fixed the previous problem by plugging in everything inside single .cu file instead of using separate cpp file. Thing is that
I get this messages and errors.

:\users\retinaloct2\desktop\jay\oct processor\common\gl\freeglut_std.h(78) : warning C4005: ‘GLUT_API_VERSION’ : macro redefinition
1> c:\users\retinaloct2\desktop\jay\oct processor\common\GL/glut.h(95) : see previous definition of ‘GLUT_API_VERSION’

1>c:\users\retinaloct2\desktop\jay\oct processor\common\gl\freeglut_std.h(354): error: redeclaration cannot add dllexport/dllimport to “glutInit”
1>c:\users\retinaloct2\desktop\jay\oct processor\common\GL/glut.h(394): here

I get multiples of these for every instructions. Can somebody help me with this? I see in the headerfile version for glut.h is 3 but freeglut_std.h is version 4. Does this mean anything? Thankyou.

I would advise keeping your code for OpenGL and CUDA in separate files, namely with OpenGL related items in a C++ file and your cuda code in the .cu file. Including libraries (i.e. OpenGL, OpenCV, etc) in code that nvcc compiles doesn’t always end well. Your previous include file woes stem from you not informing the compiler of the header files/where to find them.

The only includes I needed as far as OpenGL goes were

//OpenGL includes

#include <GL/glew.h>

#include <GL/freeglut.h>

The easiest way to have these in your project (assuming you’re using visual studio) is to add the path to the header files to your project, i.e.

right click on your project in the solution explorer → properties → C/C++ → General → Additional Include Directories. On my computer, these files are at

“C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.0\CUDALibraries\common\inc\GL”.

Let me know if you need clarification

Okay I have made two version one with separate cpp file for display and one with everything clustered in one .cu file. Thing is that for project with

.cu file gives

1>c:/Users/RETINALOCT2/Desktop/Jay/OCT Processor/gpu_testers/Resampling2 _GL/Resampling2/kernel.cu(288): error: identifier “cudaGraphicsGLRegisterBuffer” is undefined

error message which I have no Idea what is happening. Also for separate cpp version, I have problem calling cudaMemcpy to map pointer to GPU.

How can I make cpp to work with cuda functions as well? Can somebody help me out with this problem? Thank you

Regards,

MasterKiten

You should probably be having your cudaGraphicsGLRegisterBuffer call done in the host code, and have your CUDA<–>OpenGL include header(s), such as “cuda_gl_interop.h”. I would highly advise looking at an existing project that works, and building off of their framework. Take a look at [post=‘this article’]http://drdobbs.com/cpp/222600097[/post] for an idea about this.

As a rule of thumb, you want to do your CUDA && OpenGL setup in your C++ file, then generate your data in your .cu file. Also, you’ll want to minimize your call(s) to cudaGraphicsGLRegisterBuffer, i.e. only do this once if at all possible for your given PBO. As for the pointer mapping, your want to get a cudaGraphicsResource *, then use “cudaGraphicsMapResources”, then “cudaGraphicsResourceGetMappedPointer” to get the device pointer. This is your mapped CUDA/OpenGL pointer where you want to put your result(s) into in order to display them.

To put it succinctly, “cudaGraphicsGLRegisterBuffer” (once), then (for each frame), “cudaGraphicsMapResources”, then “cudaGraphicsResourceGetMappedPointer” in your host code, then call your kernel (in your .cu file) w/ the mapped pointer, then “cudaGraphicsUnmapResources”, then display the PBO.

Thanks for the reply. I have resolved the headerfile problems. The link helped me alot. Actually but now Im having some errors that I do not understand. It seems like a hardware language problem. The errors are as bellow.

Linking…
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: ___iob_func already defined in LIBCMT.lib(_file.obj)
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj)
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: _printf already defined in LIBCMT.lib(printf.obj)
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: _exit already defined in LIBCMT.lib(crt0dat.obj)
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: _free already defined in LIBCMT.lib(free.obj)
1>MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: _malloc already defined in LIBCMT.lib(malloc.obj)
1>LINK : warning LNK4098: defaultlib ‘MSVCRTD’ conflicts with use of other libs; use /NODEFAULTLIB:library
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutPostRedisplay referenced in function “void __cdecl display(void)” (?display@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutSwapBuffers referenced in function “void __cdecl display(void)” (?display@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutMainLoop referenced in function _main
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutDisplayFunc referenced in function _main
1>C:\Users\RETINALOCT2\Desktop\Jay\OCT Processor\gpu_testers\Resampling_GL\Debug\Resampling_GL.exe : fatal error LNK1120: 4 unresolved externals
1>Build log was saved at “file://c:\Users\RETINALOCT2\Desktop\Jay\OCT Processor\gpu_testers\Resampling_GL\Resampling_GL\Debug\BuildLog.htm”
1>Resampling_GL - 11 error(s), 9 warning(s)

Can somebody help me with this? My short experience make me impossible to solve the problem. Thank you

Your glut* linker errors mean you’re not linking one of the necessary glut-based .lib files, most likely freeglut.lib. Check your project’s linker settings by right clicking on your project → properties → Linker → Additional Dependencies. Make sure freeglut.lib is part of your list.
As for the MSVCRTD linker problems, you’re most likely using libraries that were compiled as release, but your project is debug. This is a pretty common issue - MSVC has 4 different runtime linking libraries, MT, MTd, MD, and MDd. check out some of the resources online, i.e. visual c++ - Runtime Library mis-matches and VC++ - Oh, the misery! - Stack Overflow for some more information on this

I fixed the problem related to libcmt.lib. However, I still don’t get with Link2017 problem. As one discribed above I have
included additional libraries for freeglut.lib but still its showing the following errors.

Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__fprintf referenced in function “enum CUTBoolean __stdcall cutCheckErrorGL(char const *,int)” (?cutCheckErrorGL@@YG?AW4CUTBoolean@@PBDH@Z)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__sprintf_s referenced in function “enum CUTBoolean __stdcall cutCheckErrorGL(char const *,int)” (?cutCheckErrorGL@@YG?AW4CUTBoolean@@PBDH@Z)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__fread referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__rewind referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__ftell referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__fseek referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__perror referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp__fopen referenced in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol __imp___vsnprintf referenced in function “void __cdecl VSPrintf(struct _iobuf *,char const *,…)” (?VSPrintf@@YAXPAU_iobuf@@PBDZZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutPostRedisplay referenced in function “void __cdecl display(void)” (?display@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutSwapBuffers referenced in function “void __cdecl display(void)” (?display@@YAXXZ)
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutMainLoop referenced in function _main
1>Resampling_GL.obj : error LNK2019: unresolved external symbol _glutDisplayFunc referenced in function _main

One of the friend says it might be a problem related to namespace. Does this ring a bell? Can somebody help me with this? Once again thank you for
helping me out.

1>Resampling_GL.obj : warning LNK4217: locally defined symbol ___iob_func imported in function “enum CUTBoolean __stdcall cutCheckErrorGL(char const *,int)” (?cutCheckErrorGL@@YG?AW4CUTBoolean@@PBDH@Z)
1>Resampling_GL.obj : warning LNK4217: locally defined symbol _fclose imported in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : warning LNK4217: locally defined symbol _printf imported in function “void __cdecl readData(void)” (?readData@@YAXXZ)
1>Resampling_GL.obj : warning LNK4217: locally defined symbol _exit imported in function “void __cdecl __cudaSafeCall(enum cudaError,char const *,int)” (?__cudaSafeCall@@YAXW4cudaError@@PBDH@Z)
1>Resampling_GL.obj : warning LNK4217: locally defined symbol _free imported in function “void __cdecl VSPrintf(struct _iobuf *,char const *,…)” (?VSPrintf@@YAXPAU_iobuf@@PBDZZ)
1>Resampling_GL.obj : warning LNK4217: locally defined symbol _malloc imported in function “void __cdecl VSPrintf(struct _iobuf *,char const *,…)” (?VSPrintf@@YAXPAU_iobuf@@PBDZZ)

Im also having such errors. It seems like ignoring msvcrtd.lib makes these problems. Can somebody help me out with the settings? Thank you.