OpenGL : reading color buffer
I attached 4 color buffers to a framebuffer and render in each of them. Each color buffer has the size of the window. I'm trying to read the color of the pixels of one of these color buffers using the coordinates of the mouse pointer.
mouse move event handler
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOIndex::GEOMETRY);
{
// I save the values I'm interested in in the attachment GL_COLOR_ATTACHMENT3
// but I always get 0 from any other attachment I try
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
But for every color buffer I always read the value 0.
The color buffers are written correctly during the rendering phase, I tested each of them by displaying the texture to which they are attached. I also tested the pixel-reading selected by the mouse pointer to the default framebuffer and it works correctly.
Where am I wrong?
Thanks!
EDIT
The seemingly strange thing is that, if I use a "dedicated" framebuffer, I can correctly read the values stored in the texture.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
GLuint fbo;
makeCurrent();
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
glDeleteFramebuffers(1, &fbo);
doneCurrent();
}
But clearly it seems useless to use another framebuffer when I already have one with exactly the information I need.
I also tried to read directly the values of the texture (as suggested by @Spektre), but also in this case I always get 0.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
doneCurrent();
}
c++ opengl graphics textures framebuffer
|
show 4 more comments
I attached 4 color buffers to a framebuffer and render in each of them. Each color buffer has the size of the window. I'm trying to read the color of the pixels of one of these color buffers using the coordinates of the mouse pointer.
mouse move event handler
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOIndex::GEOMETRY);
{
// I save the values I'm interested in in the attachment GL_COLOR_ATTACHMENT3
// but I always get 0 from any other attachment I try
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
But for every color buffer I always read the value 0.
The color buffers are written correctly during the rendering phase, I tested each of them by displaying the texture to which they are attached. I also tested the pixel-reading selected by the mouse pointer to the default framebuffer and it works correctly.
Where am I wrong?
Thanks!
EDIT
The seemingly strange thing is that, if I use a "dedicated" framebuffer, I can correctly read the values stored in the texture.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
GLuint fbo;
makeCurrent();
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
glDeleteFramebuffers(1, &fbo);
doneCurrent();
}
But clearly it seems useless to use another framebuffer when I already have one with exactly the information I need.
I also tried to read directly the values of the texture (as suggested by @Spektre), but also in this case I always get 0.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
doneCurrent();
}
c++ opengl graphics textures framebuffer
1
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
1. The link is not using FBOs at all. TheglReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to useglGetTexImage
(asglReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to useglGetTexSubImage
...
– Spektre
Dec 31 '18 at 17:01
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use alsoglReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...
– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09
|
show 4 more comments
I attached 4 color buffers to a framebuffer and render in each of them. Each color buffer has the size of the window. I'm trying to read the color of the pixels of one of these color buffers using the coordinates of the mouse pointer.
mouse move event handler
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOIndex::GEOMETRY);
{
// I save the values I'm interested in in the attachment GL_COLOR_ATTACHMENT3
// but I always get 0 from any other attachment I try
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
But for every color buffer I always read the value 0.
The color buffers are written correctly during the rendering phase, I tested each of them by displaying the texture to which they are attached. I also tested the pixel-reading selected by the mouse pointer to the default framebuffer and it works correctly.
Where am I wrong?
Thanks!
EDIT
The seemingly strange thing is that, if I use a "dedicated" framebuffer, I can correctly read the values stored in the texture.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
GLuint fbo;
makeCurrent();
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
glDeleteFramebuffers(1, &fbo);
doneCurrent();
}
But clearly it seems useless to use another framebuffer when I already have one with exactly the information I need.
I also tried to read directly the values of the texture (as suggested by @Spektre), but also in this case I always get 0.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
doneCurrent();
}
c++ opengl graphics textures framebuffer
I attached 4 color buffers to a framebuffer and render in each of them. Each color buffer has the size of the window. I'm trying to read the color of the pixels of one of these color buffers using the coordinates of the mouse pointer.
mouse move event handler
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOIndex::GEOMETRY);
{
// I save the values I'm interested in in the attachment GL_COLOR_ATTACHMENT3
// but I always get 0 from any other attachment I try
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
But for every color buffer I always read the value 0.
The color buffers are written correctly during the rendering phase, I tested each of them by displaying the texture to which they are attached. I also tested the pixel-reading selected by the mouse pointer to the default framebuffer and it works correctly.
Where am I wrong?
Thanks!
EDIT
The seemingly strange thing is that, if I use a "dedicated" framebuffer, I can correctly read the values stored in the texture.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
GLuint fbo;
makeCurrent();
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
glDeleteFramebuffers(1, &fbo);
doneCurrent();
}
But clearly it seems useless to use another framebuffer when I already have one with exactly the information I need.
I also tried to read directly the values of the texture (as suggested by @Spektre), but also in this case I always get 0.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
{
GLuint texture = textures[TextureIndex::COLOUR];
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => always 0
}
doneCurrent();
}
c++ opengl graphics textures framebuffer
c++ opengl graphics textures framebuffer
edited Jan 1 at 16:40
Arctic Pi
asked Dec 30 '18 at 17:26
Arctic PiArctic Pi
1668
1668
1
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
1. The link is not using FBOs at all. TheglReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to useglGetTexImage
(asglReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to useglGetTexSubImage
...
– Spektre
Dec 31 '18 at 17:01
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use alsoglReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...
– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09
|
show 4 more comments
1
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
1. The link is not using FBOs at all. TheglReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to useglGetTexImage
(asglReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to useglGetTexSubImage
...
– Spektre
Dec 31 '18 at 17:01
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use alsoglReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...
– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09
1
1
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
1. The link is not using FBOs at all. The
glReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to use glGetTexImage
(as glReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to use glGetTexSubImage
...– Spektre
Dec 31 '18 at 17:01
1. The link is not using FBOs at all. The
glReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to use glGetTexImage
(as glReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to use glGetTexSubImage
...– Spektre
Dec 31 '18 at 17:01
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use also
glReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...– Spektre
Jan 1 at 10:09
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use also
glReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09
|
show 4 more comments
1 Answer
1
active
oldest
votes
My approach is correct, but I was not binding to the correct framebuffer.
FBOIndex::GEOMETRY
is an enum value that I use to index a FBOs array, where I store all the framebuffer object names, so in general it is not a correct framebuffer object name.
I have defined a method addFBO(index)
that creates a framebuffer and stores it at the position index
in the FBOs array. The method returns the framebuffer object name of the generated framebuffer. If a framebuffer already exists at the position index
, then the method simply returns the associated framebuffer object name.
So, by changing the code in the following way, I finally get the desired result.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
{
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
Notwithstanding, the possibility to directly read the values from the texture withglTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.
– Arctic Pi
Jan 1 at 18:58
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53979841%2fopengl-reading-color-buffer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
My approach is correct, but I was not binding to the correct framebuffer.
FBOIndex::GEOMETRY
is an enum value that I use to index a FBOs array, where I store all the framebuffer object names, so in general it is not a correct framebuffer object name.
I have defined a method addFBO(index)
that creates a framebuffer and stores it at the position index
in the FBOs array. The method returns the framebuffer object name of the generated framebuffer. If a framebuffer already exists at the position index
, then the method simply returns the associated framebuffer object name.
So, by changing the code in the following way, I finally get the desired result.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
{
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
Notwithstanding, the possibility to directly read the values from the texture withglTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.
– Arctic Pi
Jan 1 at 18:58
add a comment |
My approach is correct, but I was not binding to the correct framebuffer.
FBOIndex::GEOMETRY
is an enum value that I use to index a FBOs array, where I store all the framebuffer object names, so in general it is not a correct framebuffer object name.
I have defined a method addFBO(index)
that creates a framebuffer and stores it at the position index
in the FBOs array. The method returns the framebuffer object name of the generated framebuffer. If a framebuffer already exists at the position index
, then the method simply returns the associated framebuffer object name.
So, by changing the code in the following way, I finally get the desired result.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
{
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
Notwithstanding, the possibility to directly read the values from the texture withglTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.
– Arctic Pi
Jan 1 at 18:58
add a comment |
My approach is correct, but I was not binding to the correct framebuffer.
FBOIndex::GEOMETRY
is an enum value that I use to index a FBOs array, where I store all the framebuffer object names, so in general it is not a correct framebuffer object name.
I have defined a method addFBO(index)
that creates a framebuffer and stores it at the position index
in the FBOs array. The method returns the framebuffer object name of the generated framebuffer. If a framebuffer already exists at the position index
, then the method simply returns the associated framebuffer object name.
So, by changing the code in the following way, I finally get the desired result.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
{
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
My approach is correct, but I was not binding to the correct framebuffer.
FBOIndex::GEOMETRY
is an enum value that I use to index a FBOs array, where I store all the framebuffer object names, so in general it is not a correct framebuffer object name.
I have defined a method addFBO(index)
that creates a framebuffer and stores it at the position index
in the FBOs array. The method returns the framebuffer object name of the generated framebuffer. If a framebuffer already exists at the position index
, then the method simply returns the associated framebuffer object name.
So, by changing the code in the following way, I finally get the desired result.
void mouseMoveEvent(QMouseEvent *event)
{
int x = event->pos().x();
int y = event->pos().y();
makeCurrent();
glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
{
glReadBuffer(GL_COLOR_ATTACHMENT3);
QVector<GLubyte> pixel(3);
glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));
QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
qDebug() << PixelColor; // => correct value
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
doneCurrent();
}
answered Jan 1 at 18:48
Arctic PiArctic Pi
1668
1668
Notwithstanding, the possibility to directly read the values from the texture withglTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.
– Arctic Pi
Jan 1 at 18:58
add a comment |
Notwithstanding, the possibility to directly read the values from the texture withglTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.
– Arctic Pi
Jan 1 at 18:58
Notwithstanding, the possibility to directly read the values from the texture with
glTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.– Arctic Pi
Jan 1 at 18:58
Notwithstanding, the possibility to directly read the values from the texture with
glTexSubImage2D
without going through a framebuffer is still unresolved for me. I found this article, but I have not had time to try.– Arctic Pi
Jan 1 at 18:58
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53979841%2fopengl-reading-color-buffer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Your attachments are stored as textures in the FBO so just read the texture but beware this will not work on IntelHD ... Also you are using the glReadPixels wrongly see depth buffer got by glReadPixels is always 1
– Spektre
Dec 31 '18 at 10:40
@Spektre thank you for the comment!! How can I read directly the texture in CPU space using the coordinates of the mouse cursor? I read the discussion you suggested, but I didn't get why I should care about the depth buffer in my case. Thank you so much for your help!!
– Arctic Pi
Dec 31 '18 at 14:54
1. The link is not using FBOs at all. The
glReadPixels
is reading rendered buffer (in that link its depth but you can use any other you need) and you select which one as one of the parameters (your code is missing that !!! and that is why it is not working) 2. FBO is rendering into texture instead so in that case you need to useglGetTexImage
(asglReadPixels
will not acquire data you want...) that however reads the whole texture for single point or sub image you need to useglGetTexSubImage
...– Spektre
Dec 31 '18 at 17:01
I just have seen this: opengl es 2.0 android c++ glGetTexImage alternative so it looks like you can use also
glReadPixels
like you do but you need to add some aditional calls see the code there for comparison/repair of yours ...– Spektre
Jan 1 at 10:09
Possible duplicate of opengl es 2.0 android c++ glGetTexImage alternative
– Spektre
Jan 1 at 10:09