Major problem: as soon as I attempt to add in a second out variable, I get zero primitives generated.
#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <iostream>
#include <vector>
using namespace std;
// Automatically link in the GLUT and GLEW libraries if compiling on MSVC++
#ifdef _MSC_VER
#pragma comment(lib, "glew32")
#pragma comment(lib, "freeglut")
#endif
// Vertex shader
const GLchar* vertexShaderSrc = R"glsl(
#version 150 core
//in vec4 inValue;
out vec4 geoValue;
void main()
{
geoValue = vec4(1, 2, 3, 4);//inValue;
}
)glsl";
// Geometry shader
const GLchar* geoShaderSrc = R"glsl(
#version 150 core
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
in vec4[] geoValue;
out vec4 outValue;
out vec4 outvalue2;
void main()
{
for (int i = 0; i < 3; i++)
{
outValue = geoValue[0] + vec4(i, i, i, i);
EmitVertex();
}
EndPrimitive();
}
)glsl";
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(10, 10);
glutInitWindowPosition(0, 0);
GLint win_id = glutCreateWindow("GS Test");
if (GLEW_OK != glewInit())
{
cout << "GLEW initialization error" << endl;
return 0;
}
int GL_major_version = 0;
glGetIntegerv(GL_MAJOR_VERSION, &GL_major_version);
int GL_minor_version = 0;
glGetIntegerv(GL_MINOR_VERSION, &GL_minor_version);
if (GL_major_version < 4)
{
cout << "GPU does not support OpenGL 4.3 or higher" << endl;
return 0;
}
else if (GL_major_version == 4)
{
if (GL_minor_version < 3)
{
cout << "GPU does not support OpenGL 4.3 or higher" << endl;
return 0;
}
}
// 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", "outvalue2" };
glTransformFeedbackVaryings(program, 2, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(program);
glUseProgram(program);
// Create VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
size_t num_vertices = 1;
size_t num_vertices_per_triangle = 3;
size_t num_floats_per_vertex = 4;
// Create input VBO and vertex format
//vector<GLfloat> data = { 5.0f, 6.0f, 7.0f, 0.0f };
//GLuint vbo;
//glGenBuffers(1, &vbo);
//glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*num_vertices*num_floats_per_vertex, &data[0], 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(GLfloat) * 2 * num_vertices * num_vertices_per_triangle * num_floats_per_vertex, nullptr, GL_STATIC_READ);
// Create query object to collect info
GLuint query;
glGenQueries(1, &query);
// Perform feedback transform
glEnable(GL_RASTERIZER_DISCARD);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo);
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_POINTS, 0, 1);
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glDisable(GL_RASTERIZER_DISCARD);
glFlush();
// Fetch and print results
GLuint primitives;
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &primitives);
vector<GLfloat> feedback(2 * num_vertices * num_vertices_per_triangle * num_floats_per_vertex);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat)*feedback.size(), &feedback[0]);
printf("%u primitives written!\n\n", primitives);
for (int i = 0; i < 2 * num_vertices * num_vertices_per_triangle * num_floats_per_vertex; i++)
{
cout << feedback[i] << endl;
}
glDeleteQueries(1, &query);
glDeleteProgram(program);
glDeleteShader(geoShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &tbo);
//glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
return 0;
}