Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <GL/glew.h>
- #include <GL/wglew.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include <cstdio>
- #include <vector>
- #include <cstdint>
- #include <sstream>
- #include <fstream>
- #include <string>
- #include <iostream>
- #include <string.h>
- #include <CL/cl.h>
- #include <CL/cl_gl.h>
- #include <CL/cl_gl_ext.h>
- #include "ocl_util.h"
- #pragma comment(lib, "opengl32.lib")
- #ifdef _DEBUG
- #pragma comment(lib, "glew32sd.lib")
- #else
- #pragma comment(lib, "glew32s.lib")
- #endif
- #pragma comment(lib, "OpenCL.lib")
- // for update loop timing
- LARGE_INTEGER lastUpdate;
- // windows window handles
- HDC hdc = 0;
- HGLRC hrc = 0;
- HWND hWnd = 0;
- int width = 512;
- int height = 512;
- // opengl "scene" data, quad vertices, uv coords, etc.
- //glm::vec2 pos[] = { glm::vec2(-1, -1), glm::vec2(-1, 1), glm::vec2(1, 1), glm::vec2(1, -1) };
- glm::vec2 pos[] = { glm::vec2(-1, -1), glm::vec2(-1, 1), glm::vec2(0, 1), glm::vec2(0, -1) };
- glm::vec2 uv[] = { glm::vec2(0, 0), glm::vec2(0, 1), glm::vec2(1, 1), glm::vec2(1, 0) };
- // opengl buffers and objects
- GLuint vertexbuffer = 0;
- GLuint uvBuffer = 0;
- GLuint program = 0;
- GLuint texture = 0;
- GLuint sampler = 0;
- // opencl buffers and objects
- //CL::Image2D<CL::NullType> *img;
- //CL::Context *context;
- cl_platform_id platform;
- cl_device_id device;
- cl_context context;
- cl_command_queue queue;
- cl_program program_cl;
- cl_kernel kernel;
- // utility functions
- unsigned long RGBA2DWORD(int iR, int iG, int iB, int iA)
- {
- return ((iA << 24) | (iB << 16) | (iG << 8) | iR);
- }
- uint64_t GetFileSize(std::string path)
- {
- std::ifstream stream(path, std::ios::binary | std::ios::ate);
- return stream.tellg();
- }
- void ReadFile(std::string path, std::vector<uint8_t>& data, std::ios::openmode mode)
- {
- std::ifstream stream(path, mode);
- uint64_t size = GetFileSize(path);
- data.resize((std::size_t)size);
- stream.read((char*)data.data(), data.size());
- }
- std::string ReadFile(std::string path, std::ios::openmode mode)
- {
- std::vector<uint8_t> data;
- ReadFile(path, data, mode);
- return std::string(data.begin(), data.end());
- }
- // opengl
- void GLAPIENTRY DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
- {
- std::stringstream ss;
- ss << "OpenGL: " << message << " [source=";
- switch(source)
- {
- case GL_DEBUG_SOURCE_API: ss << "OPENGL"; break;
- case GL_DEBUG_SOURCE_WINDOW_SYSTEM: ss << "WINDOW_SYSTEM"; break;
- case GL_DEBUG_SOURCE_SHADER_COMPILER: ss << "SHADER_COMPILER"; break;
- case GL_DEBUG_SOURCE_THIRD_PARTY: ss << "THIRD_PARTY"; break;
- case GL_DEBUG_SOURCE_APPLICATION: ss << "APPLICATION"; break;
- case GL_DEBUG_SOURCE_OTHER: ss << "OTHER"; break;
- default: ss << "UNDEFINED(0x" << std::hex << source << std::dec << ")"; break;
- }
- ss << " type=";
- switch(type)
- {
- case GL_DEBUG_TYPE_ERROR: ss << "ERROR"; break;
- case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: ss << "DEPRECATED_BEHAVIOR"; break;
- case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: ss << "UNDEFINED_BEHAVIOR"; break;
- case GL_DEBUG_TYPE_PORTABILITY: ss << "PORTABILITY"; break;
- case GL_DEBUG_TYPE_PERFORMANCE: ss << "PERFORMANCE"; break;
- case GL_DEBUG_TYPE_OTHER: ss << "OTHER"; break;
- default: ss << "UNDEFINED(0x" << std::hex << source << std::dec << ")"; break;
- }
- ss << " severity=";
- switch(severity)
- {
- case GL_DEBUG_SEVERITY_HIGH: ss << "HIGH"; break;
- case GL_DEBUG_SEVERITY_MEDIUM: ss << "MEDIUM"; break;
- case GL_DEBUG_SEVERITY_LOW: ss << "LOW"; break;
- default: ss << "UNDEFINED"; break;
- }
- ss << " id=" << id << "]";
- printf("%s", ss.str().c_str());
- }
- bool initOpenGL()
- {
- // create default opengl context
- hdc = GetDC(hWnd);
- PIXELFORMATDESCRIPTOR pfd;
- memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
- pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = 32;
- pfd.cDepthBits = 24;
- pfd.cStencilBits = 8;
- pfd.iLayerType = PFD_MAIN_PLANE;
- int nPixelFormat = ChoosePixelFormat(hdc, &pfd);
- SetPixelFormat(hdc, nPixelFormat, &pfd);
- HGLRC tempOpenGLContext = wglCreateContext(hdc);
- wglMakeCurrent(hdc, tempOpenGLContext);
- // init glew after we have our opengl context
- GLenum error = glewInit();
- if(error != GLEW_OK)
- return false;
- // set all atributes needed for a opengl 3.0+ context
- int attributes[] = {
- WGL_CONTEXT_MAJOR_VERSION_ARB, 4, // Set the MAJOR version of OpenGL to 3
- WGL_CONTEXT_MINOR_VERSION_ARB, 3, // Set the MINOR version of OpenGL to 2
- WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, // Set our OpenGL context to be forward compatible
- WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- 0
- };
- // create new context and delete
- hrc = wglCreateContextAttribsARB(hdc, NULL, attributes);
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(tempOpenGLContext);
- wglMakeCurrent(hdc, hrc);
- // check version we actually created
- int glVersion[2] = { -1, -1 };
- glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]);
- glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]);
- // check if is debug context
- bool isDebug = false;
- GLint flags;
- glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
- if(flags & GL_CONTEXT_FLAG_DEBUG_BIT)
- {
- isDebug = true;
- }
- // enable opengl debugging output if accessible
- bool useErrorChecking = false;
- if(isDebug && glewGetExtension("GL_KHR_debug"))
- {
- glDebugMessageCallback(&DebugCallback, NULL);
- useErrorChecking = true;
- }
- // enable vsync
- //wglSwapIntervalEXT(1);
- printf("using OpenGL version %d.%d (context=%s, errorChecking=%s)\n", glVersion[0], glVersion[1], isDebug ? "debug" : "default", useErrorChecking ? "true" : "false");
- return true;
- }
- void genShaders()
- {
- const char *vert = "#version 330\n" \
- "layout(location = 0) in vec2 in_position;" \
- "layout(location = 1) in vec2 in_uv;" \
- "out vec2 uv;" \
- "void main() {" \
- " gl_Position = vec4(in_position, 0, 1);"\
- " uv = in_uv;" \
- "}";
- const char *frag = "#version 330\n" \
- "out vec4 outColor;" \
- "in vec2 uv;" \
- "uniform sampler2D imgSampler;" \
- "void main() {" \
- " outColor = texture(imgSampler, uv);" \
- "}";
- // Create the shaders
- GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
- GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
- GLint Result = GL_FALSE;
- int InfoLogLength;
- // Compile Vertex Shader
- glShaderSource(VertexShaderID, 1, &vert, NULL);
- glCompileShader(VertexShaderID);
- // Check Vertex Shader
- glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
- if(Result == GL_FALSE)
- {
- glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
- std::vector<char> VertexShaderErrorMessage(InfoLogLength);
- glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
- fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
- }
- // Compile Fragment Shader
- glShaderSource(FragmentShaderID, 1, &frag, NULL);
- glCompileShader(FragmentShaderID);
- // Check Fragment Shader
- glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
- if(Result == GL_FALSE)
- {
- glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
- std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
- glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
- fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
- }
- // Link the program
- program = glCreateProgram();
- glAttachShader(program, VertexShaderID);
- glAttachShader(program, FragmentShaderID);
- glLinkProgram(program);
- // Check the program
- glGetProgramiv(program, GL_LINK_STATUS, &Result);
- if(Result == GL_FALSE)
- {
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &InfoLogLength);
- std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
- glGetProgramInfoLog(program, InfoLogLength, NULL, &ProgramErrorMessage[0]);
- fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
- }
- glDeleteShader(VertexShaderID);
- glDeleteShader(FragmentShaderID);
- }
- void setupScene()
- {
- glClearColor(0.4f, 0.6f, 0.9f, 1.0f);
- //glClearColor(1, 1, 1, 1);
- glViewport(0, 0, width, height);
- // quad positions in ndc space
- glGenBuffers(1, &vertexbuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(pos) * sizeof(glm::vec2), &pos, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- // base uv data for our quad
- glGenBuffers(1, &uvBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(uv) * sizeof(glm::vec2), &uv, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- // basic shader rendering our texture data
- genShaders();
- // sampler for reading the texture
- glGenSamplers(1, &sampler);
- glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
- // create texture with inital data
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- std::vector<uint32_t> initData(width * height, RGBA2DWORD(255, 0, 0, 32));
- //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, initData.data());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, initData.data());
- glBindTexture(GL_TEXTURE_2D, 0);
- // enable blending
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- }
- void resize(int newWidth, int newHeight)
- {
- width = newWidth;
- height = newHeight;
- glViewport(0, 0, width, height);
- }
- // opencl
- bool initOpenCL()
- {
- cl_int error;
- platform;
- error = clGetPlatformIDs(1, &platform, NULL);
- device;
- error = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &device, NULL);
- size_t ext_size = 1024;
- char ext_string[1024];
- error = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, ext_size, ext_string, &ext_size);
- cl_context_properties properties[] =
- {
- CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(platform),
- CL_GL_CONTEXT_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentContext()),
- CL_WGL_HDC_KHR, reinterpret_cast<cl_context_properties>(wglGetCurrentDC()),
- 0
- };
- context = clCreateContext(properties, 1, &device, NULL, NULL, &error);
- queue = clCreateCommandQueue(context, device, 0, &error);
- std::string kernelSrc = ReadFile("../data/kernel.cl", std::ios::binary);
- const char *source = kernelSrc.c_str();
- program_cl = clCreateProgramWithSource(context, 1, &source, NULL, &error);
- error = clBuildProgram(program_cl, 1, &device, NULL, NULL, NULL);
- if(error != CL_SUCCESS)
- {
- size_t retSize = 0;
- cl_int ret = 0;
- ret = clGetProgramBuildInfo(program_cl, device, CL_PROGRAM_BUILD_LOG, NULL, NULL, &retSize);
- std::vector<char> log(retSize);
- ret = clGetProgramBuildInfo(program_cl, device, CL_PROGRAM_BUILD_LOG, log.size(), &log[0], NULL);
- printf("build error: %d\n%s", error, std::string(log.begin(), log.end()).c_str());
- }
- kernel = clCreateKernel(program_cl, "image_write", &error);
- return true;
- /*try
- {
- auto platforms = CL::Info::GetPlatforms();
- auto devices = CL::Info::GetDevices(platforms[0], CL::GPU);
- printf("using OpenCL: %s\n", platforms[0].version.c_str());
- CL::ContextInit init(devices[0], platforms[0]);
- init.AddPropertyPair(CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC());
- init.AddPropertyPair(CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext());
- context = new CL::Context(init);
- std::string kernel = ReadFile("../data/kernel.cl", std::ios::binary);
- context->LoadProgramm(kernel, "");
- context->LoadKernel("muh");
- img = new CL::Image2D<CL::NullType>(*context, texture);
- }
- catch(CL::ocl_exception &e)
- {
- printf("%s", e.what());
- return false;
- }
- return true;*/
- }
- void setupOpenCLInteropBuffers()
- {
- cl_int error;
- cl_mem buffer = clCreateFromGLTexture(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, &error);
- cl_image_format image_format;
- clGetImageInfo(buffer, CL_IMAGE_FORMAT, sizeof(cl_image_format), &image_format, NULL);
- glFinish();
- error = clEnqueueAcquireGLObjects(queue, 1, &buffer, 0, NULL, NULL);
- error = clSetKernelArg(kernel, 0, sizeof(buffer), (void*)&buffer);
- float val = 5.0f;
- error = clSetKernelArg(kernel, 1, sizeof(float), &val);
- size_t global_work_size = width*height;
- error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, &global_work_size, NULL, 0, NULL, NULL);
- error = clEnqueueReleaseGLObjects(queue, 1, &buffer, 0, NULL, NULL);
- clFinish(queue);
- }
- // main loop
- void update(double delta)
- {
- // make memory up to date in case opengl changed buffer
- //glFlush();
- /*glFinish();
- context->AquireOpenGLBuffer(*img);
- context->SetArgs(*img, 0.5f);
- context->DoWork2D(width, height, 16, 16);
- context->ReleaseOpenGLBuffer(*img);
- context->Finish();*/
- }
- void render()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glUseProgram(program);
- glActiveTexture(GL_TEXTURE0);
- GLint pos = glGetUniformLocation(program, "imgSampler");
- glUniform1i(pos, 0);
- glBindSampler(0, sampler);
- glBindTexture(GL_TEXTURE_2D, texture),
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glDrawArrays(GL_QUADS, 0, sizeof(pos));
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glBindTexture(GL_TEXTURE_2D, 0);
- glUseProgram(0);
- }
- // winapi window stuff
- LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch(msg)
- {
- case WM_DESTROY:
- {
- PostQuitMessage(0);
- return 0;
- }
- case WM_SIZE:
- {
- int newWidth = LOWORD(lParam);
- int newHeight = HIWORD(lParam);
- resize(newWidth, newHeight);
- }
- break;
- }
- return DefWindowProc(hWnd, msg, wParam, lParam);
- }
- int createWindow()
- {
- HINSTANCE hInst = GetModuleHandle(NULL);
- WNDCLASSEX wClass;
- ZeroMemory(&wClass, sizeof(WNDCLASSEX));
- wClass.cbClsExtra = NULL;
- wClass.cbSize = sizeof(WNDCLASSEX);
- wClass.cbWndExtra = NULL;
- wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
- wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wClass.hIcon = NULL;
- wClass.hIconSm = NULL;
- wClass.hInstance = hInst;
- wClass.lpfnWndProc = (WNDPROC)WinProc;
- wClass.lpszClassName = "Window Class";
- wClass.lpszMenuName = NULL;
- wClass.style = CS_HREDRAW|CS_VREDRAW;
- if(!RegisterClassEx(&wClass))
- {
- int nResult = GetLastError();
- MessageBox(NULL, "Window class creation failed", "Window Class Failed", MB_ICONERROR);
- }
- RECT wr = { 0, 0, width, height };
- AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
- hWnd = CreateWindowEx(NULL, "Window Class", "Windows application", WS_OVERLAPPEDWINDOW, 200, 200, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInst, NULL);
- if(!hWnd)
- {
- int nResult = GetLastError();
- MessageBox(NULL, "Window creation failed", "Window Creation Failed", MB_ICONERROR);
- }
- //////////////////////////////////////////////////////////////////////////
- // opengls stuff
- if(!initOpenGL())
- {
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- if(!initOpenCL())
- {
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- setupScene();
- setupOpenCLInteropBuffers();
- //////////////////////////////////////////////////////////////////////////
- ShowWindow(hWnd, SW_SHOW);
- return true;
- }
- void run()
- {
- MSG msg;
- ZeroMemory(&msg, sizeof(MSG));
- LARGE_INTEGER frequency;
- QueryPerformanceFrequency(&frequency);
- QueryPerformanceCounter(&lastUpdate);
- while(true)
- {
- while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- // Translate the message and dispatch it to WindowProc()
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- if(msg.message == WM_QUIT)
- break;
- LARGE_INTEGER now;
- QueryPerformanceCounter(&now);
- double delta = static_cast<double>(now.QuadPart - lastUpdate.QuadPart) / frequency.QuadPart;
- lastUpdate = now;
- update(delta);
- render();
- SwapBuffers(hdc);
- }
- }
- // create window and run
- int main()
- {
- if(!createWindow())
- return -1;
- run();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement