#include #include #include #include #include static const char* g_transformVertexShader = "#version 330 \n\ in float value;\n\ out float root;\n\ void main() {\n\ root = sqrt(value);\n\ }"; static const char* g_renderingVertexShader = "#version 330\n\ in vec3 pos;\n\ out vec3 pos_out;\n\ void main() {\n\ pos_out = pos;\n\ }"; static const char* g_renderingGeomShader = "#version 330\n\ \n\ layout(points) in;\n\ layout(triangle_strip, max_vertices=4) out;\n\ \n\ in vec3 pos_out[];\n\ \n\ void main()\n\ {\n\ gl_Position = vec4(pos_out[0] + vec3(-1,-1, 0), 1);\n\ EmitVertex();\n\ gl_Position = vec4(pos_out[0] + vec3( 1,-1, 0), 1);\n\ EmitVertex();\n\ gl_Position = vec4(pos_out[0] + vec3( 1, 1, 0), 1);\n\ EmitVertex();\n\ gl_Position = vec4(pos_out[0] + vec3(-1, 1, 0), 1);\n\ EmitVertex();\n\ EndPrimitive();\n\ }"; static const char* g_renderingFragmentShader = "#version 330\n\ out vec4 fragmentColor;\n\ void main() {\n\ fragmentColor = vec4(1,1,1,1);\n\ }"; GLchar info[1024]; GLuint compileShader(GLenum shaderType, const char* script) { GLuint shader = glCreateShader(shaderType); glShaderSource(shader, 1, &script, NULL); glCompileShader(shader); GLint status = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { glGetShaderInfoLog(shader, sizeof(info), NULL, info); printf("While compiling:\n%s", script); printf("Error:\n%s\n", info); } assert(status == GL_TRUE); return shader; } void display(void) { glClear(GL_COLOR_BUFFER_BIT); // --------------------------------------------------------- // SETUP PROGRAM FOR TRANSFORM FEEDBACK GLuint transformProgram = glCreateProgram(); glAttachShader(transformProgram, compileShader(GL_VERTEX_SHADER, g_transformVertexShader)); const GLchar* varyings[1] = {"root"}; glTransformFeedbackVaryings(transformProgram, 1, varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(transformProgram); GLint status = 0; glGetProgramiv(transformProgram, GL_LINK_STATUS, &status); assert(status == GL_TRUE); // --------------------------------------------------------- // SETUP PROGRAM FOR RENDERING GLuint renderingProgram = glCreateProgram(); glAttachShader(renderingProgram, compileShader(GL_VERTEX_SHADER, g_renderingVertexShader)); glAttachShader(renderingProgram, compileShader(GL_GEOMETRY_SHADER, g_renderingGeomShader)); glAttachShader(renderingProgram, compileShader(GL_FRAGMENT_SHADER, g_renderingFragmentShader)); glLinkProgram(renderingProgram); glGetProgramiv(renderingProgram, GL_LINK_STATUS, &status); assert(status == GL_TRUE); // --------------------------------------------------------- // SETUP INPUT FOR TRANSFORM FEEDBACK GLfloat data[4] = {0, 0, 0, 0}; GLuint outputBuffer; glGenBuffers(1, &outputBuffer); glBindBuffer(GL_ARRAY_BUFFER, outputBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); GLuint inputBuffer; glGenBuffers(1, &inputBuffer); glBindBuffer(GL_ARRAY_BUFFER, inputBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); GLuint inputBufferArrayObject; glGenVertexArrays(1, &inputBufferArrayObject); glBindVertexArray(inputBufferArrayObject); GLint attrib = glGetAttribLocation(transformProgram, "value"); glVertexAttribPointer(attrib, 1, GL_FLOAT, GL_FALSE, 4, 0); glEnableVertexAttribArray(attrib); glBindVertexArray(0); // --------------------------------------------------------- // SETUP RENDERING GLfloat data2[3] = {0, 0, 0}; GLuint drawBuffer; glGenBuffers(1, &drawBuffer); glBindBuffer(GL_ARRAY_BUFFER, drawBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(data2), data2, GL_STATIC_DRAW); GLuint drawBufferArrayObject; glGenVertexArrays(1, &drawBufferArrayObject); glBindVertexArray(inputBufferArrayObject); attrib = glGetAttribLocation(renderingProgram, "pos"); glVertexAttribPointer(attrib, 3, GL_FLOAT, GL_FALSE, sizeof(data2), 0); glEnableVertexAttribArray(attrib); glBindVertexArray(0); // --------------------------------------------------------- // DRAW USING GEOMETRY SHADER glUseProgram(renderingProgram); glBindVertexArray(drawBufferArrayObject); glDrawArrays(GL_POINTS, 0, 1); #ifdef WORKAROUND glUseProgram(transformProgram); glBindVertexArray(drawBufferArrayObject); glDrawArrays(GL_POINTS, 0, 1); #endif // --------------------------------------------------------- // DRAW CAPTURING TRANSFORM FEEDBACK glUseProgram(transformProgram); glBindVertexArray(inputBufferArrayObject); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, outputBuffer); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 1); glEndTransformFeedback(); glFlush(); glFinish(); glutSwapBuffers(); } int main(int nargs, char** args) { glutInit(&nargs, args); glutInitContextVersion(3,2); glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG | GLUT_FORWARD_COMPATIBLE); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(640, 480); glutCreateWindow("Bug"); glutDisplayFunc(&display); glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 0); glutMainLoop(); return EXIT_SUCCESS; }