Hi,
It is difficult to use a java program to find the correct way to make a C program, so
I have made my (not working) program as simpe as possible.
#include <windows.h>
#include <gl/gl.h>
#include <GL/glut.h>
#include <CL/cl.h>
#include <CL/cl_gl.h>
#include <iostream>
cl_int err;
cl_uint selectedPlatform;
cl_device_id selectedDeviceID;
cl_context context;
cl_command_queue commands;
cl_program program;
cl_kernel kernel;
cl_mem imageOutObject;
GLuint myTexture;
GLuint textureWidth;
GLuint textureHeight;
void InitGL(void);
void InitCL(void);
void Render(void);
void Resize(int width, int height);
void SpecialKey(int key, int x, int y);
int wnd_width = 800;
int wnd_height = 600;
float rotX=0;
float rotY=0;
int main(int argc, char **argv)
{
//initialise OpenGL
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
glutInitWindowSize(wnd_width,wnd_height);
glutCreateWindow("OpenGL-CL interraction!");
InitGL();
InitCL();
glutDisplayFunc(&Render);
glutReshapeFunc(&Resize);
glutSpecialFunc(&SpecialKey);
glutMainLoop();
}
void InitGL(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
//make OpenGL texture
textureWidth = 256;
textureHeight = 256;
char *buffer = new char[textureWidth * textureHeight * 4];
for (unsigned int i = 0; i < textureWidth * textureHeight * 4; i++)
{
buffer[i] = (char)255; // RGBA = (255,255,255,255) = white
}
glGenTextures(1, &myTexture);
glBindTexture(GL_TEXTURE_2D, myTexture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindTexture(GL_TEXTURE_2D, 0);
}
void InitCL(void)
{
//Get all Platforms and select a GPU one
cl_uint numPlatforms;
clGetPlatformIDs (65536, NULL, &numPlatforms);
std::cout << "Platforms detected: " << numPlatforms << std::endl;
cl_platform_id* platformIDs;
platformIDs = new cl_platform_id[numPlatforms];
err = clGetPlatformIDs(numPlatforms, platformIDs, NULL);
if(err != CL_SUCCESS)
{
std::cout << "error at clGetPlatformIDs :" << err << std::endl;
}
selectedPlatform=0; // simply take first platform(index 0), code for taking correct one is long and not postet here
cl_platform_id selectedPlatformID = platformIDs[selectedPlatform];
delete[] platformIDs;
//Select a GPU device
err = clGetDeviceIDs(selectedPlatformID, CL_DEVICE_TYPE_GPU, 1, &selectedDeviceID, NULL);
if(err != CL_SUCCESS)
{
std::cout << "error at clGetDeviceIDs :" << err << std::endl;
}
char cDeviceNameBuffer[1024];
clGetDeviceInfo (selectedDeviceID, CL_DEVICE_NAME, sizeof(char) * 1024, cDeviceNameBuffer, NULL);
std::cout <<": Device Name: " << cDeviceNameBuffer << std::endl;
std::cout << std::endl;
//Get a context with OpenGL connection
cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) selectedPlatformID, 0};
context = clCreateContext(props,1, &selectedDeviceID, NULL, NULL, &err);
if(!context || err!= CL_SUCCESS)
{
std::cout << "error at clCreateContext :" << err << std::endl;
}
//create a command queue
commands = clCreateCommandQueue(context, selectedDeviceID, 0,&err);
if(!commands || err!= CL_SUCCESS)
{
std::cout << "error at clCreateCommandQueue :" << err << std::endl;
}
//use the kernel-source code to create a program
char* kernelSource = " \
__kernel void kernel1(write_only image2d_t output)
\
{
\
int2 coordi = (int2)( get_global_id(0), get_global_id(1) );
\
float4 color;
\
color = (float4)(1.0,0.0,0.0,1.0);
\
write_imagef( output,coordi , color );
\
}";
int szKernelLength = strlen(kernelSource);
program = clCreateProgramWithSource(context, 1,(const char**)& kernelSource, NULL, &err);
if (!program)
{
std::cout << "error at clCreateProgramWithSource :" << err << std::endl;
if (kernelSource) {delete[] kernelSource;}
}
//Compile the kernel and get errors if exits
err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
if(err != CL_SUCCESS)
{
size_t len;
char buffer[2048];
std::cout << "error at clBuildProgram :" << err << std::endl;
clGetProgramBuildInfo(program, selectedDeviceID, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);
std::cout << "The kernel has bugs: "<< std::endl << buffer << std::endl;
}
//select the kernel name
kernel = clCreateKernel(program, "kernel1", &err);
if (!kernel || err != CL_SUCCESS)
{
std::cout << "error at clCreateKernel :" << err << std::endl;
}
//Get an image Object from the OpenGL texture
imageOutObject= clCreateFromGLTexture2D( context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,0, myTexture, &err);
if (err != CL_SUCCESS)
{
std::cout << "error at clCreateFromGLTexture2D:" << err << std::endl;
}
}
// Interaction to make the program to draw the OpenGL window again
void SpecialKey(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP:
rotX -= 5;
break;
case GLUT_KEY_DOWN:
rotX += 5;
break;
case GLUT_KEY_LEFT:
rotY -= 5;
break;
case GLUT_KEY_RIGHT:
rotY += 5;
break;
default:
return;
}
glutPostRedisplay();
}
void Resize(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
wnd_width = width;
wnd_height= height;
}
void Render(void)
{
//The OpenCL Part
size_t localWorkSize[2] = { 8, 8 };
size_t globalWorkSize[2] = {textureWidth, textureHeight};
err = clSetKernelArg( kernel, 0, sizeof( imageOutObject ), &imageOutObject );
if(err != CL_SUCCESS)
{
std::cout << "error at clSetKernelArg: " << err << std::endl;
}
err = clEnqueueAcquireGLObjects(commands,1,&imageOutObject,0,NULL,NULL);
if(err != CL_SUCCESS)
{
std::cout << "error at clEnqueueAcquireGLObjects: " << err << std::endl;
}
err = clEnqueueNDRangeKernel(commands, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
if(err != CL_SUCCESS)
{
std::cout << "error at clEnqueueNDRangeKernel: " << err << std::endl;
}
err = clEnqueueReleaseGLObjects(commands,1,&imageOutObject,0,NULL,NULL);
if(err != CL_SUCCESS)
{
std::cout << "error at clEnqueueReleaseGLObjects: " << err << std::endl;
}
clFinish(commands);
//The OpenGL Part (simply a quad with the texture)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0 ,-4.0);
glRotatef (rotX, 1.0, 0.0, 0.0);
glRotatef (rotY, 0.0, 1.0, 0.0);
glTranslatef (-0.5, -0.5 , -0.5);
glBindTexture(GL_TEXTURE_2D, myTexture);
glBegin (GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd ();
glBindTexture(GL_TEXTURE_2D, 0);
glFinish();
glutSwapBuffers();
}
The texture is set to white. The kernel should make it blue (GBRA mode).
But the texture is white on the screen.
Please help me to find the error.