微软发布了一套用于部署到win8上的openframeworks库,可以用于编写universal程序~
于是迫不及待的想要试一试~
于是用example/gl/textureScreengrabExample的代码:
void ofApp::setup(){
counter = 0;
ofSetCircleResolution(100);
texScreen.allocate(1600, 900, GL_RGB);
ofBackground(230, 230, 240);
}
void ofApp::update(){
counter += 1;
}
void ofApp::draw(){
// 1st, draw on screen:
ofSetHexColor(0x66CC33);
ofRect(100, 100, 300, 300);
ofSetHexColor(0xffffff);
ofPushMatrix();
ofTranslate(200, 200, 0);
ofRotate(counter, 0, 0, 1);
ofCircle(0, 0, 80);
ofCircle(100, 0, 10); // a small one
ofPopMatrix();
ofSetHexColor(0x333333);
ofDrawBitmapString("(a) on screen", 150, 200);
ofSetHexColor(0xFFCC33);
ofCircle(mouseX, mouseY, 20);
// 2nd, grab a portion of the screen into a texture
// this is quicker then grabbing into an ofImage
// because the transfer is done in the graphics card
// as opposed to bringing pixels back to memory
// note: you need to allocate the texture to the right size
texScreen.loadScreenData(0, 0, 1600, 900);
// finally, draw that texture on screen, how ever you want
// (note: you can even draw the texture before you call loadScreenData,
// in order to make some trails or feedback type effects)
ofPushMatrix();
ofSetHexColor(0xffffff);
ofTranslate(550, 300, 0);
//glRotatef(counter, 0.1f, 0.03f, 0);
float width = 200 + 100 * sin(counter / 200.0f);
float height = 200 + 100 * sin(counter / 200.0f);
texScreen.draw(-width / 2, -height / 2, width, height);
ofPopMatrix();
ofPushMatrix();
ofSetHexColor( 0xffffff );
ofTranslate( 700 , 210 , 0 );
ofRotate( counter , 0.1f , 0.03f , 0 );
texScreen.draw( -50 , -50 , 100 , 100 );
ofPopMatrix();
ofSetHexColor(0x333333);
ofDrawBitmapString("(b) in a texture, very meta!", 500, 200);
}
果不其然的运行得不到正确的结果~
一番排查之后~发现下面这一段代码:
void Renderer::CreateDeviceDependentResources()
{
if (!m_loadingComplete)
{
m_deviceResources->aquireContext();
ofmain();
m_loadingComplete = true;
m_deviceResources->releaseContext();
}
}
void DeviceResources::aquireContext()
{
if (!m_eglSurface)
return;
std::lock_guard<std::mutex> guard(m_mutex);
if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)){
throw std::runtime_error("DeviceResouces: failed to make EGL context current");
}
}
EGLBoolean eglMakeCurrent( EGLDisplay display,
<span style="white-space:pre"> </span>EGLSurface draw,
<span style="white-space:pre"> </span>EGLSurface read,
<span style="white-space:pre"> </span>EGLContext context);
具体可参见:eglMakeCurrent
而loadScreenData()内部调用了glCopyTexSubImage2D()实现
而在执行ofmain之前执行已经调用了eglMakeCurrent()了,由于调用了eglMakeCurrent之后,不能进行任何像素数据读回操作,glCopyTexSubImage2D无法得到数据,所以上述代码无法得到正确的结果