void GLRenderer::CreateTFBuffer()
{
unsigned int size = ...;//
glGenBuffers(1, &m_TF_ID);
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_TF_ID);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_DYNAMIC_READ);
}
bool GLRenderer::QueryTF()
{
if(!m_bTFRead) return false;
if(!m_bInitTF)
{
GLint available = 0;
glGetQueryObjectiv(m_tfQuery, GL_QUERY_RESULT_AVAILABLE, &available);
if(available == 0) return false;
}
//... Other code ...
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_TF_ID);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_TF_ID);
glEnable(GL_RASTERIZER_DISCARD);
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_tfQuery);
glBeginTransformFeedback(GL_POINTS);
int first = 0, count = ...;
glDrawArrays(GL_POINTS, first, count);
glEndTransformFeedback();
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
glDisable(GL_RASTERIZER_DISCARD);
m_bInitTF = false;
m_bTFRead = false;
return true;
}
float GLRenderer::ReadTF()
{
if(m_bInitTF) return -1000.0f;
GLint available = 0;
glGetQueryObjectiv(m_tfQuery, GL_QUERY_RESULT_AVAILABLE, &available);
if(available == 0) return -1000.0f;
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_TF_ID);
//float* ptr = (float*)glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); // The same as following
float* ptr = (float*)glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 4 * sizeof(float), GL_MAP_READ_BIT); // <= Extremely costly
//...
}