Okay, turns out I was wrong! glReadPixels works on the frame buffer, which does match the screen size, with 0, 0 in the lower left. Here's a function that can take the camera point to frame buffer space:
- (QCAR::Vec2F)cameraPointToFramebufferPoint:(QCAR::Vec2F)cameraPoint
{
// Note this function assumes landscape orientation
QCAR::VideoMode videoMode = QCAR::CameraDevice::getInstance().getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
QCAR::VideoBackgroundConfig config = QCAR::Renderer::getInstance().getVideoBackgroundConfig();
int xOffset = ((int) framebufferWidth - config.mSize.data[0]) / 2.0f + config.mPosition.data[0];
int yOffset = ((int) framebufferHeight - config.mSize.data[1]) / 2.0f - config.mPosition.data[1];
QCAR::Vec2F fbPoint = QCAR::Vec2F(cameraPoint.data[0] * config.mSize.data[0] / (float) videoMode.mWidth + xOffset,
cameraPoint.data[1] * config.mSize.data[1] / (float) videoMode.mHeight + yOffset);
// Camera origin is upper left, while framebuffer origin is lower left
fbPoint.data[1] = framebufferHeight - fbPoint.data[1];
return fbPoint;
}
Given that, I was able to get reasonable values from your target with this code:
for (int h = 2; h <= 3; h++) {
for (int j = 1; j <= 4; j++) {
pixelPointMarker = CGPointMake(-15.0 + 6.1 * h, -15.0 + 5.9 * j);
QCAR::Vec2F cameraPoint = QCAR::Tool::projectPoint(cameraCalibration, pose, QCAR::Vec3F(pixelPointMarker.x, pixelPointMarker.y, 0));
QCAR::Vec2F framebufferPoint = [self cameraPointToFramebufferPoint:cameraPoint];
glReadPixels(framebufferPoint.data[0], framebufferPoint.data[1], 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelColor);
NSLog(@"pixelColor: %d, %d, %d", (int) pixelColor[0], (int) pixelColor[1], (int) pixelColor[2]);
}
}
Let me know if that works any better for you.
- Kim
The result is perfect. Thanks Kim for taking the time to help me !
- DaProd