Problem, using 2 Texture Buffer at the same time.
In my fragment shader I want to use 2 Texture Buffer.
In the following fragment-test-shader I try to read out
from both texture buffers which I set in the application
using glMapBuffer (I read out the buffer to verify that
the values in the buffer are correct).
Problem: I can use only one sampler, but not both.
What mistake I do ?
Application:
// -----------------------------------------------------------------------------
// - Application:
// -----------------------------------------------------------------------------
//
// construction of the texture buffers
//
...
m_SweepData = new TGLTextureBufferObject(); // sweep pixel data
m_TimeStampArray = new TGLTextureBufferObject(); // parameter (including timestamp array)
...
// create the buffers (method see down):
m_SweepData->SetBufferParam(GL_R8UI, NumberOfPixelPerSweep * NumberOfSweepsPerTurn);
m_TimeStampArray->SetBufferParam(GL_R8UI, NumberOfSweepsPerTurn);
//
// fill sweep data array
//
GLubyte* p = (GLubyte*)m_SweepData->MapGraphicMemory();
for (int i = 0; i < m_SweepData->GetNumberOfEntries(); i++)
{
p[i] = 123;
}
m_SweepData->UnMapGraphicMemory();
//
// fill time stamp array
//
GLubyte* pp = (GLubyte*)m_TimeStampArray->MapGraphicMemory();
for (int i = 0; i < m_TimeStampArray->GetNumberOfEntries(); i++)
{
pp[i] = 167;
}
m_TimeStampArray->UnMapGraphicMemory();
...
//
// paint method (called cyclic):
//
m_Shader.ActivateShader();
m_SweepData->ActivateTexture(GL_TEXTURE0);
m_TimeStampArray->ActivateTexture(GL_TEXTURE1);
//
// set the texture buffer objects to the correct texture
//
glUniform1f(glGetUniformLocation(m_Shader.m_ProgramObject, "sweepTextureBuffer"), 0);
glUniform1f(glGetUniformLocation(m_Shader.m_ProgramObject, "timeStampArray"), 1);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
GLfloat texXOffset = ((BufferWidthPixel-TargetWidthPixel)/2.0/BufferWidthPixel);
GLfloat texYOffset = ((BufferHeightPixel-TargetHeightPixel)/2.0/BufferHeightPixel);
glTexCoord2f(texXOffset ,texYOffset);
glVertex2f(0.0, 0.0); // P1
glTexCoord2f(1-texXOffset,texYOffset);
glVertex2f(1.0, 0.0); // P2
glTexCoord2f(1-texXOffset,1-texYOffset);
glVertex2f(1.0, 1.0); // P3
glTexCoord2f(texXOffset ,1-texYOffset);
glVertex2f(0.0, 1.0); // P4
glEnd();
m_Shader.DeactivateShader();
// -----------------------------------------------------------------------------
// - Methods of class TGLTextureBufferObject:
// -----------------------------------------------------------------------------
__fastcall TGLTextureBufferObject::TGLTextureBufferObject()
{
m_TBO = 0;
m_textureId = 0;
m_NumberOfEntries = 0;
m_BufferCreated = false;
}
// -----------------------------------------------------------------------------
__fastcall TGLTextureBufferObject::~TGLTextureBufferObject()
{
}
// -----------------------------------------------------------------------------
GLint __fastcall TGLTextureBufferObject::GetNumberOfEntries()
{
return m_NumberOfEntries;
}
// -----------------------------------------------------------------------------
GLint __fastcall TGLTextureBufferObject::GetEntrySize(GLenum format)
{
GLint result;
switch (format)
{
case GL_R8:
{
result = sizeof(GLubyte);
}
break;
case GL_R16:
{
result = sizeof(GLushort);
}
break;
case GL_R16F:
{
result = sizeof(GLfloat)/2;
}
break;
case GL_R32F:
{
result = sizeof(GLfloat);
}
break;
case GL_R8I:
{
result = sizeof(GLbyte);
}
break;
case GL_R16I:
{
result = sizeof(GLshort);
}
break;
case GL_R32I:
{
result = sizeof(GLint);
}
break;
case GL_R8UI:
{
result = sizeof(GLubyte);
}
break;
case GL_R16UI:
{
result = sizeof(GLushort);
}
break;
case GL_R32UI:
{
result = sizeof(GLuint);
}
break;
case GL_RG8:
{
result = sizeof(GLubyte) * 2;
}
break;
case GL_RG16:
{
result = sizeof(GLushort) * 2;
}
break;
case GL_RG16F:
{
result = sizeof(GLfloat)/2 * 2;
}
break;
case GL_RG32F:
{
result = sizeof(GLfloat) * 2;
}
break;
case GL_RG8I:
{
result = sizeof(GLbyte) * 2;
}
break;
case GL_RG16I:
{
result = sizeof(GLshort) * 2;
}
break;
case GL_RG32I:
{
result = sizeof(GLint) * 2;
}
break;
case GL_RG8UI:
{
result = sizeof(GLubyte) * 2;
}
break;
case GL_RG16UI:
{
result = sizeof(GLushort) * 2;
}
break;
case GL_RG32UI:
{
result = sizeof(GLuint) * 2;
}
break;
case GL_RGBA8:
{
result = sizeof(GLuint) * 4;
}
break;
case GL_RGBA16:
{
result = sizeof(GLshort) * 4;
}
break;
case GL_RGBA16F:
{
result = sizeof(GLfloat)/2 * 4;
}
break;
case GL_RGBA32F:
{
result = sizeof(GLfloat) * 4;
}
break;
case GL_RGBA8I:
{
result = sizeof(GLbyte) * 4;
}
break;
case GL_RGBA16I:
{
result = sizeof(GLshort) * 4;
}
break;
case GL_RGBA32I:
{
result = sizeof(GLint) * 4;
}
break;
case GL_RGBA8UI:
{
result = sizeof(GLubyte) * 4;
}
break;
case GL_RGBA16UI:
{
result = sizeof(GLushort) * 4;
}
break;
case GL_RGBA32UI:
{
result = sizeof(GLuint) * 4;
}
break;
default:
{
result = 0;
};
}
return result;
}
// -----------------------------------------------------------------------------
GLint __fastcall TGLTextureBufferObject::GetMaxTextureBufferSize()
{
GLint size;
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &size);
return size;
}
// -----------------------------------------------------------------------------
void __fastcall TGLTextureBufferObject::CreateTextureBuffer()
{
DeleteTextureBuffer();
// buffer name generieren
glGenBuffers(1, &m_TBO);
// Binden des frisch erstellten Buffers
glBindBuffer(GL_TEXTURE_BUFFER, m_TBO);
// create buffer data store (but uninitialized)
glBufferData(GL_TEXTURE_BUFFER, GetEntrySize(m_Format) * m_NumberOfEntries, 0, GL_DYNAMIC_DRAW);
// bind TBO to texture unit
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_BUFFER, m_textureId);
glTexBufferARB(GL_TEXTURE_BUFFER, m_Format, m_TBO); // attach the texture buffer to the active buffer texture
glBindBuffer(GL_TEXTURE_BUFFER, 0);
m_BufferCreated = true;
}
// -----------------------------------------------------------------------------
void __fastcall TGLTextureBufferObject::DeleteTextureBuffer()
{
if (m_BufferCreated)
{
if (glIsBuffer(m_TBO))
{
glDeleteBuffers(1, &m_TBO);
}
if (glIsTexture(m_textureId))
{
glDeleteTextures(1, &m_textureId);
}
}
m_TBO = 0;
m_textureId = 0;
m_BufferCreated = false;
}
// -----------------------------------------------------------------------------
bool __fastcall TGLTextureBufferObject::SetBufferParam(GLenum format, GLint NumberOfEntries)
{
bool result = false;
if (!((NumberOfEntries * GetEntrySize(m_Format)) > GetMaxTextureBufferSize()))
{
m_Format = format;
m_NumberOfEntries = NumberOfEntries;
CreateTextureBuffer();
result = true;
}
return result;
}
// -----------------------------------------------------------------------------
void __fastcall TGLTextureBufferObject::ActivateTexture(GLenum texture) // initial value is GL_TEXTURE0
{
glActiveTexture(texture);
//glBindBuffer(GL_TEXTURE_BUFFER, m_TBO);
//glTexBufferARB(GL_TEXTURE_BUFFER, m_Format, m_TBO); // attach the texture buffer to the active buffer texture
glBindTexture(GL_TEXTURE_BUFFER, m_textureId);
}
// -----------------------------------------------------------------------------
void* __fastcall TGLTextureBufferObject::MapGraphicMemory()
{
if (m_BufferCreated)
{
// Binden des erstellten Buffers
glBindBuffer(GL_TEXTURE_BUFFER, m_TBO);
return glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
// return glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
}
else
{
return NULL;
}
}
// -----------------------------------------------------------------------------
void __fastcall TGLTextureBufferObject::UnMapGraphicMemory()
{
if (m_BufferCreated)
{
// Binden des erstellten Buffers
glBindBuffer(GL_TEXTURE_BUFFER, m_TBO);
if (glUnmapBuffer(GL_TEXTURE_BUFFER))
{
// unmapping ok !
}
else
{
// A mapped data store must be unmapped with glUnmapBuffer before its buffer
// object is used. Otherwise an error will be generated by any GL command
// that attempts to dereference the buffer object's data store. When a data
// store is unmapped, the pointer to its data store becomes invalid.
// glUnmapBuffer returns GL_TRUE unless the data store contents have become
// corrupt during the time the data store was mapped. This can occur for
// system-specific reasons that affect the availability of graphics memory,
// such as screen mode changes. In such situations, GL_FALSE is returned
// and the data store contents are undefined. An application must detect
// this rare condition and reinitialize the data store.
// ? ? ?
assert(0);
}
// Buffer unbind
glBindBuffer(GL_TEXTURE_BUFFER, 0);
}
}
Fragment-Shader:
#version 150 compatibility
uniform usamplerBuffer sweepTextureBuffer; // filled with number: 123 by application
uniform usamplerBuffer timeStampArray; // filled with number: 167 by application
// -----------------------------------------------------------------------------
// - Main
// -----------------------------------------------------------------------------
void main(void)
{
if ((texelFetch(sweepTextureBuffer, 1).r == uint(123)) &&
(texelFetch(timeStampArray, 1).r == uint(167)))
{
FragColor = vec4(1.0, 1.0, 0.0, 0.8);
}
else
{
FragColor = vec4(0.0, 0.0, 1.0, 0.8);
}
}