//----------------------------------------------------------------------------// void OpenGLApplePBTextureTarget::declareRenderSize(const Size& sz) { // exit if current size is enough if ((d_area.getWidth() >= sz.d_width) && (d_area.getHeight() >= sz.d_height)) return; setArea(Rect(d_area.getPosition(), d_owner.getAdjustedTextureSize(sz))); // dump any previous pbuffer if (d_pbuffer) { CGLDestroyPBuffer(d_pbuffer); d_pbuffer = 0; } CGLError err; if (err = CGLCreatePBuffer(d_area.getWidth(), d_area.getHeight(), GL_TEXTURE_2D, GL_RGBA, 0, &d_pbuffer)) { CEGUI_THROW(RendererException( "OpenGLApplePBTextureTarget::declareRenderSize " "- CGLCreatePBuffer failed: " + String(CGLErrorString(err)))); } if (err = CGLSetPBuffer(d_context, d_pbuffer, 0, 0, d_screen)) CEGUI_THROW(RendererException( "OpenGLApplePBTextureTarget::declareRenderSize " "- CGLSetPBuffer failed: " + String(CGLErrorString(err)))); clear(); // make d_texture use the pbuffer as it's data source // save old texture binding GLuint old_tex; glGetIntegerv(GL_TEXTURE_BINDING_2D, reinterpret_cast<GLint*>(&old_tex)); glBindTexture(GL_TEXTURE_2D, d_texture); err = CGLTexImagePBuffer(CGLGetCurrentContext(), d_pbuffer, GL_FRONT); // restore previous texture binding. glBindTexture(GL_TEXTURE_2D, old_tex); if (err) CEGUI_THROW(RendererException( "OpenGLApplePBTextureTarget::declareRenderSize " "- CGLTexImagePBuffer failed: " + String(CGLErrorString(err)))); // ensure CEGUI::Texture is wrapping real GL texture and has correct size d_CEGUITexture->setOpenGLTexture(d_texture, d_area.getSize()); }
NS_IMETHODIMP nsCanvasRenderingContextGLPrivate::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f) { nsresult rv = NS_OK; if (!mGLPbuffer) return NS_OK; // use GL Drawing if we can get a target GL context; otherwise // go through the fallback path. #ifdef HAVE_GL_DRAWING if (mCanvasElement->GLWidgetBeginDrawing()) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); int bwidth = mGLPbuffer->Width(); int bheight = mGLPbuffer->Height(); GLuint tex = 0; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex); CGLError err = CGLTexImagePBuffer(CGLGetCurrentContext(), ((nsGLPbufferCGL*)mGLPbuffer)->GetCGLPbuffer(), GL_BACK); if (err) { fprintf (stderr, "CGLTexImagePBuffer failed: %d\n", err); glDeleteTextures(1, &tex); return NS_OK; } glEnable(GL_TEXTURE_RECTANGLE_EXT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glFrustum(-halfWidth, halfWidth, halfHeight, -halfHeight, 1.0, 100000.0); glOrtho(0, bwidth, bheight, 0, -0.5, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_QUADS); /* Note that the texture needs a y-flip */ glTexCoord2f(0.0, bheight); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(bwidth, bheight); glVertex3f(bwidth, 0.0, 0.0); glTexCoord2f(bwidth, 0); glVertex3f(bwidth, bheight, 0.0); glTexCoord2f(0.0, 0); glVertex3f(0.0, bheight, 0.0); glEnd(); glDisable(GL_TEXTURE_RECTANGLE_EXT); glDeleteTextures(1, &tex); mCanvasElement->GLWidgetSwapBuffers(); mCanvasElement->GLWidgetEndDrawing(); } else #endif { nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface(); if (!surf) return NS_OK; nsRefPtr<gfxPattern> pat = CanvasGLThebes::CreatePattern(surf); gfxMatrix m; m.Translate(gfxPoint(0.0, mGLPbuffer->Height())); m.Scale(1.0, -1.0); pat->SetMatrix(m); // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee // pixel alignment for this stuff! ctx->NewPath(); ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat); ctx->Fill(); } return rv; }