Advertisement
Guest User

OpenGL ComputeShader Error

a guest
May 22nd, 2013
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.00 KB | None | 0 0
  1. #pragma comment(lib, "glew32.lib")
  2. #pragma comment(lib, "GLFW.lib")
  3. #pragma comment(lib, "opengl32.lib")
  4. #pragma comment(lib, "user32.lib")
  5. #pragma comment(lib, "kernel32.lib")
  6.  
  7. #include "GL\glew.h"
  8. #include "GL\glfw.h"
  9.  
  10. #include <iostream>
  11.  
  12. GLuint renderHandle, computeHandle;
  13.  
  14. void updateTex(int);
  15. void draw();
  16.  
  17. GLuint genRenderProg(GLuint);
  18. GLuint genTexture();
  19. GLuint genComputeProg(GLuint);
  20. void checkErrors(std::string);
  21.  
  22. const GLuint WIN_WIDTH = 800;
  23. const GLuint WIN_HEIGHT = 600;
  24.  
  25. int main(void)
  26. {
  27.     /* Initialize the library */
  28.     if (!glfwInit())
  29.         return -1;
  30.    
  31.     glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4);
  32.     glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
  33.     //glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
  34.  
  35.     /* Create a windowed mode window and its OpenGL context */
  36.     if (!glfwOpenWindow(WIN_WIDTH, WIN_HEIGHT, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)){
  37.         return -1;
  38.     }
  39.  
  40.     glfwSetWindowTitle("Compute Shader Test");
  41.  
  42.     // Intialize Glew
  43.     glewExperimental = true;
  44.     GLenum err = glewInit();
  45.     if(GLEW_OK != err){
  46.         /* Problem: glewInit failed, something is seriously wrong. */
  47.         fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
  48.     }
  49.  
  50.     std::fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
  51.  
  52.     if (GLEW_VERSION_4_3)
  53.     {
  54.         /* Problem: No OpenGL 4.3 */
  55.         std::fprintf(stderr, "Error: No openGL 4.3. supported\n");
  56.     }
  57.  
  58.     std::fprintf(stdout, "Using OpenGL 4.3\n");
  59.  
  60.     if (!GLEW_ARB_compute_shader)
  61.     {
  62.         /* Problem: No compute shaders supported. */
  63.         std::fprintf(stderr, "Error: No compute shaders supported\n");
  64.     }
  65.  
  66.     std::fprintf(stdout, "Compute shaders are available\n");
  67.  
  68.     // Ensure we can capture the escape key
  69.     glfwEnable(GLFW_STICKY_KEYS);
  70.  
  71.     GLuint texHandle = genTexture();
  72.     renderHandle = genRenderProg(texHandle);
  73.     computeHandle = genComputeProg(texHandle);
  74.  
  75.     GLint frame = 0;
  76.  
  77.     glViewport(0, 0, WIN_WIDTH, WIN_HEIGHT);
  78.  
  79.     /* Loop until the user closes the window */
  80.     while (glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS && glfwGetWindowParam(GLFW_OPENED))
  81.     {
  82.         updateTex(frame++);
  83.         draw();
  84.     }
  85.  
  86.     return 0;
  87. }
  88.  
  89. void updateTex(int frame) {
  90.     glUseProgram(computeHandle);
  91.     glUniform1f(glGetUniformLocation(computeHandle, "roll"), (float)frame*0.01f);
  92.     glDispatchCompute(512/16, 512/16, 1); // 512^2 threads in blocks of 16^2
  93.     checkErrors("Dispatch compute shader");
  94. }
  95.  
  96. void draw() {
  97.     glUseProgram(renderHandle);
  98.     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  99.  
  100.     glfwSwapBuffers();
  101.     checkErrors("Draw screen");
  102. }
  103.  
  104. GLuint genComputeProg(GLuint texHandle) {
  105.     // Creating the compute shader, and the program object containing the shader
  106.     GLuint progHandle = glCreateProgram();
  107.     GLuint cs = glCreateShader(GL_COMPUTE_SHADER);
  108.  
  109.     // In order to write to a texture, we have to introduce it as image2D.
  110.     // local_size_x/y/z layout variables define the work group size.
  111.     // gl_GlobalInvocationID is a uvec3 variable giving the global ID of the thread,
  112.     // gl_LocalInvocationID is the local index within the work group, and
  113.     // gl_WorkGroupID is the work group's index
  114.     const char *csSrc[] = {
  115.         "#version 430\n",
  116.         "uniform float roll;\
  117.         uniform image2D destTex;\
  118.         layout (local_size_x = 16, local_size_y = 16) in;\
  119.         void main() {\
  120.             ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);\
  121.             float localCoef = length(vec2(ivec2(gl_LocalInvocationID.xy)-8)/8.0);\
  122.             float globalCoef = sin(float(gl_WorkGroupID.x+gl_WorkGroupID.y)*0.1 + roll)*0.5;\
  123.             imageStore(destTex, storePos, vec4(1.0-globalCoef*localCoef, 0.0, 0.0, 0.0));\
  124.         }"
  125.     };
  126.  
  127.     glShaderSource(cs, 2, csSrc, NULL);
  128.     glCompileShader(cs);
  129.     int rvalue;
  130.     glGetShaderiv(cs, GL_COMPILE_STATUS, &rvalue);
  131.     if (!rvalue) {
  132.         fprintf(stderr, "Error in compiling the compute shader\n");
  133.         GLchar log[10240];
  134.         GLsizei length;
  135.         glGetShaderInfoLog(cs, 10239, &length, log);
  136.         fprintf(stderr, "Compiler log:\n%s\n", log);
  137.         exit(40);
  138.     }
  139.    
  140.     fprintf(stdout, "Compute shader compiled sucessfully\n");
  141.  
  142.     glAttachShader(progHandle, cs);
  143.  
  144.     glLinkProgram(progHandle);
  145.     glGetProgramiv(progHandle, GL_LINK_STATUS, &rvalue);
  146.     if (!rvalue) {
  147.         fprintf(stderr, "Error in linking compute shader program\n");
  148.         GLchar log[10240];
  149.         GLsizei length;
  150.         glGetProgramInfoLog(progHandle, 10239, &length, log);
  151.         fprintf(stderr, "Linker log:\n%s\n", log);
  152.         exit(41);
  153.     }  
  154.  
  155.     fprintf(stdout, "Compute shader linked sucessfully\n");
  156.  
  157.     glUseProgram(progHandle);
  158.    
  159.     glUniform1i(glGetUniformLocation(progHandle, "destTex"), 0);
  160.  
  161.     checkErrors("Compute shader");
  162.     return progHandle;
  163. }
  164.  
  165.  
  166. GLuint genRenderProg(GLuint texHandle) {
  167.     GLuint progHandle = glCreateProgram();
  168.     GLuint vp = glCreateShader(GL_VERTEX_SHADER);
  169.     GLuint fp = glCreateShader(GL_FRAGMENT_SHADER);
  170.  
  171.     const char *vpSrc[] = {
  172.         "#version 430\n",
  173.         "in vec2 pos;\
  174.         out vec2 texCoord;\
  175.         void main() {\
  176.             texCoord = pos*0.5f + 0.5f;\
  177.             gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);\
  178.         }"
  179.     };
  180.  
  181.     const char *fpSrc[] = {
  182.         "#version 430\n",
  183.         "uniform sampler2D srcTex;\
  184.         in vec2 texCoord;\
  185.         out vec4 color;\
  186.         void main() {\
  187.             float c = texture(srcTex, texCoord).x;\
  188.             color = vec4(c, 1.0, 1.0, 1.0);\
  189.         }"
  190.     };
  191.  
  192.     glShaderSource(vp, 2, vpSrc, NULL);
  193.     glShaderSource(fp, 2, fpSrc, NULL);
  194.  
  195.     glCompileShader(vp);
  196.     int rvalue;
  197.     glGetShaderiv(vp, GL_COMPILE_STATUS, &rvalue);
  198.     if (!rvalue) {
  199.         fprintf(stderr, "Error in compiling vp\n");
  200.         exit(30);
  201.     }
  202.     glAttachShader(progHandle, vp);
  203.  
  204.     glCompileShader(fp);
  205.     glGetShaderiv(fp, GL_COMPILE_STATUS, &rvalue);
  206.     if (!rvalue) {
  207.         fprintf(stderr, "Error in compiling fp\n");
  208.         exit(31);
  209.     }
  210.     glAttachShader(progHandle, fp);
  211.  
  212.     glBindFragDataLocation(progHandle, 0, "color");
  213.     glLinkProgram(progHandle);
  214.  
  215.     glGetProgramiv(progHandle, GL_LINK_STATUS, &rvalue);
  216.     if (!rvalue) {
  217.         fprintf(stderr, "Error in linking sp\n");
  218.         exit(32);
  219.     }  
  220.    
  221.     glUseProgram(progHandle);
  222.     glUniform1i(glGetUniformLocation(progHandle, "srcTex"), 0);
  223.  
  224.     GLuint vertArray;
  225.     glGenVertexArrays(1, &vertArray);
  226.     glBindVertexArray(vertArray);
  227.  
  228.     GLuint posBuf;
  229.     glGenBuffers(1, &posBuf);
  230.     glBindBuffer(GL_ARRAY_BUFFER, posBuf);
  231.     float data[] = {
  232.         -1.0f, -1.0f,
  233.         -1.0f, 1.0f,
  234.         1.0f, -1.0f,
  235.         1.0f, 1.0f
  236.     };
  237.     glBufferData(GL_ARRAY_BUFFER, sizeof(float)*8, data, GL_STREAM_DRAW);
  238.     GLint posPtr = glGetAttribLocation(progHandle, "pos");
  239.     glVertexAttribPointer(posPtr, 2, GL_FLOAT, GL_FALSE, 0, 0);
  240.     glEnableVertexAttribArray(posPtr);
  241.  
  242.     checkErrors("Render shaders");
  243.     return progHandle;
  244. }
  245.  
  246. GLuint genTexture() {
  247.     // We create a single float channel 512^2 texture
  248.     GLuint texHandle;
  249.     glGenTextures(1, &texHandle);  
  250.     glActiveTexture(GL_TEXTURE0);  
  251.     glBindTexture(GL_TEXTURE_2D, texHandle);
  252.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  253.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  254.     glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 512, 0, GL_RED, GL_FLOAT, NULL);  
  255.  
  256.     // Because we're also using this tex as an image (in order to write to it),
  257.     // we bind it to an image unit as well
  258.     glBindImageTexture(0, texHandle, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32F);
  259.  
  260.     return texHandle;
  261. }
  262.  
  263. void checkErrors(std::string desc) {
  264.     GLenum e = glGetError();
  265.     if (e != GL_NO_ERROR) {
  266.         fprintf(stderr, "OpenGL error in \"%s\": (%d)\n", desc.c_str(), e);
  267.         exit(20);
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement