Próbuję przesłać małą tablicę zmiennoprzecinkową jako teksturę OpenGL ES 2.0 i odczytać ją w celu lepszego zrozumienia GPGPU. Próbuję to zrobić na GPU SGX 530 na TI OMAP3 ARM SoC.OpenGL ES 2 Jak renderować teksturę i wyodrębnić dane dla testu GPGPU
Śledzę ten przewodnik: enter link description here
Moje kodu aktualnie tworzy i zapełnia 2 tablice float, a następnie tworzy "pass through" shaderów tak:
void GLWidget::initializeGL()
{
// Max texture size in each direction
int maxSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize);
texSize = sqrt(maxSize);
texSize = 2;
qDebug() << "GL_MAX_TEXTURE_SIZE " << maxSize << " SQRT " << texSize;
// Define input and output arrays of RGBA format with each channel being u8
m_Format = 4;
dataX = (quint8*)malloc(m_Format*texSize*texSize*sizeof(quint8));
dataY = (quint8*)malloc(m_Format*texSize*texSize*sizeof(quint8));
// Setup some dummy data
int arraySize = m_Format*texSize*texSize;
qDebug() << "Array Size: " << arraySize;
for (int i = 0; i < arraySize ; i++) {
dataX[i] = i;
}
for (int i = 0; i < arraySize ; i++) {
dataY[i] = 0;
}
QGLShader *vshader = new QGLShader(QGLShader::Vertex);
const char *vsrc =
"attribute highp vec4 vertex;\n"
"attribute highp vec4 texCoord;\n"
"varying vec2 texc;\n"
"void main(void)\n"
"{\n"
" gl_Position = vertex;\n"
" texc = texCoord.xy;\n"
"}\n";
vshader->compileSourceCode(vsrc);
QGLShader *fshader = new QGLShader(QGLShader::Fragment);
const char *fsrc =
"varying highp vec2 texc;\n"
"uniform sampler2D tex;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(tex, texc);\n"
"}\n";
fshader->compileSourceCode(fsrc);
program.addShader(vshader);
program.addShader(fshader);
program.link();
vertexAttr = program.attributeLocation("vertex");
texCoordAttr = program.attributeLocation("texCoord");
textureUniform = program.uniformLocation("tex");
}
ja spróbuje Prześlij teksturę do procesora graficznego, wyrenderuj go do bufora ramki i odczytaj go w następujący sposób:
void GLWidget::renderToScene()
{
// Bind and configure a texture
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &m_hTexture);
glBindTexture(GL_TEXTURE_2D, m_hTexture);
glUniform1i(textureUniform, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataX); // Allocate buffer to hold RGBA with 8 bytes each
// Generate handles for Frame Buffer Object
glGenFramebuffers(1, &m_hFBO);
// Switch the render target to the current FBO to update the texture map
glBindFramebuffer(GL_FRAMEBUFFER, m_hFBO);
qDebug() << "Data before roundtrip:";
int arraySize = m_Format*texSize*texSize;
for (int i = 0 ; i < arraySize ; i++)
qDebug() << dataX[i];
// FBO attachment is complete?
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "Frame buffer is present...";
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_hTexture, 0);
//glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texSize,texSize, GL_RGBA,GL_UNSIGNED_BYTE,dataX); // pixel data is RGBA and each channel u8
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat textureVertices[] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
};
// ensure no VBOs or IBOs are bound
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Set pointers to the arrays
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(ATTRIB_VERTEX);
glDisableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
}
qDebug() << "Zero data:";
for (int i = 0; i < arraySize ; i++)
qDebug() << dataY[i];
// GPGPU Extract
glReadPixels(0, 0, texSize, texSize, GL_RGBA,GL_UNSIGNED_BYTE,dataY);
// print out results
qDebug() << "Data after roundtrip:";
for (int i = 0; i < arraySize ; i++)
qDebug() << dataY[i];
// Unbind the FBO so rendering will return to the main buffer.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
qDebug() << "Done...";
sleep(60000);
}
Wygląda na wezwanie do losowania to:
void GLWidget::draw() {
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
// Draw
program.bind();
renderToScene();
program.release();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
swapBuffers();
}
Wszystko kompiluje i działa, ale moje dane wyjściowe wygląda następująco:
Found SGX/MBX driver, enabling FullClearOnEveryFrame
Found v1.4 driver, enabling brokenTexSubImage
Found non-Nokia v1.4 driver, enabling brokenFBOReadBack
GL_MAX_TEXTURE_SIZE 2048 SQRT 2
Array Size: 16
Data before roundtrip:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Zero data:
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Data after roundtrip:
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Done...
Jak mogę złożyć z powrotem i przeczytaj mój tekst prawidłowo? Dzięki!
Obsługa standardu FBO jest standardem w ES 2.0. Nie ma potrzeby rozszerzenia. –