// Link statically with GLEW #define GLEW_STATIC // Headers #include #include // Vertex shader const GLchar* vertexShaderSrc = R"glsl( #version 150 core in float inValue; out float geoValue; void main() { geoValue = sqrt(inValue); } )glsl"; // Geometry shader const GLchar* geoShaderSrc = R"glsl( #version 150 core layout(points) in; layout(triangle_strip, max_vertices = 3) out; in float[] geoValue; out float outValue; void main() { for (int i = 0; i < 3; i++) { outValue = geoValue[0] + i; EmitVertex(); } EndPrimitive(); } )glsl"; int main() { sf::ContextSettings settings; settings.depthBits = 24; settings.stencilBits = 8; settings.majorVersion = 3; settings.minorVersion = 2; sf::Window window(sf::VideoMode(800, 600, 32), "Transform Feedback", sf::Style::Titlebar | sf::Style::Close, settings); // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Compile shaders GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSrc, nullptr); glCompileShader(vertexShader); GLuint geoShader = glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(geoShader, 1, &geoShaderSrc, nullptr); glCompileShader(geoShader); // Create program and specify transform feedback variables GLuint program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, geoShader); 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) * 3, nullptr, GL_STATIC_READ); // Perform feedback transform glEnable(GL_RASTERIZER_DISCARD); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo); glBeginTransformFeedback(GL_TRIANGLES); glDrawArrays(GL_POINTS, 0, 5); glEndTransformFeedback(); glDisable(GL_RASTERIZER_DISCARD); glFlush(); // Fetch and print results GLfloat feedback[15]; glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(feedback), feedback); for (int i = 0; i < 15; i++) { printf("%f\n", feedback[i]); } glDeleteProgram(program); glDeleteShader(geoShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &tbo); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); window.close(); return 0; }