/** * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/OpenGL_Programming * This file is in the public domain. * Contributors: Sylvain Beucler */ #include #include #include /* Use glew.h instead of gl.h to get all the GL prototypes declared */ #include /* Using the GLUT library for the base windowing setup */ #include /* GLM */ // #define GLM_MESSAGES #define GLM_FORCE_RADIANS // Vertex shader const GLchar* vertexShaderSrc = R"glsl( #version 150 core in float inValue; out float outValue; void main() { outValue = sqrt(inValue); } )glsl"; int screen_width=800, screen_height=600; int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH); glutInitWindowSize(screen_width, screen_height); glutCreateWindow("My Rotating Cube"); GLenum glew_status = glewInit(); if (glew_status != GLEW_OK) { fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status)); return 1; } if (!GLEW_VERSION_2_0) { fprintf(stderr, "Error: your graphic card does not support OpenGL 2.0\n"); return 1; } // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Compile shader GLuint shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(shader, 1, &vertexShaderSrc, 0); glCompileShader(shader); // Create program and specify transform feedback variables GLuint program = glCreateProgram(); glAttachShader(program, shader); const GLchar* feedbackVaryings[] = { "outValue" }; glTransformFeedbackVaryings(program, 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(program); glUseProgram(program); // Create VAO GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create input VBO and vertex format GLfloat data[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); GLint inputAttrib = glGetAttribLocation(program, "inValue"); glEnableVertexAttribArray(inputAttrib); glVertexAttribPointer(inputAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0); // Create transform feedback buffer GLuint tbo; glGenBuffers(1, &tbo); glBindBuffer(GL_ARRAY_BUFFER, tbo); glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_STATIC_READ); // Perform feedback transform glEnable(GL_RASTERIZER_DISCARD); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 5); glEndTransformFeedback(); glDisable(GL_RASTERIZER_DISCARD); glFlush(); // Fetch and print results GLfloat feedback[5]; glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback); printf("%f %f %f %f %f\n", feedback[0], feedback[1], feedback[2], feedback[3], feedback[4]); // Now do it again! glBindBuffer(GL_ARRAY_BUFFER, tbo); // glBufferData(GL_ARRAY_BUFFER, sizeof(data), feedback, GL_STATIC_DRAW); This makes the copy - don't do this! glVertexAttribPointer(inputAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0); // Perform feedback transform glEnable(GL_RASTERIZER_DISCARD); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 5); glEndTransformFeedback(); glDisable(GL_RASTERIZER_DISCARD); glFlush(); // Fetch and print results glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback); printf("%f %f %f %f %f\n", feedback[0], feedback[1], feedback[2], feedback[3], feedback[4]); glDeleteProgram(program); glDeleteShader(shader); glDeleteBuffers(1, &tbo); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); return 0; } // Tutorial from here: // https://open.gl/feedback // Compile with: g++ -std=c++14 c8.cpp -lGL -lGLEW -lsfml-system -lsfml-graphics -lsfml-window // Link statically with GLEW //#define GLEW_STATIC