Vegac, as you rightly pointed out on #nekochan, the YCrCb extension doesn't work with glTexSubImage2D() so one can't have hardware colourspace conversion && textured zooming on O2... but actually you can, with some messing about with UMA. If you know the PBuffer-as-texture trick then disregard this, otherwise this is ripped wholesale from something else I'm writing so it should work, ish:
Obviously... link with -ldmedia too.
Code: Select all
#include <dmedia.h>
Make and init a texture, nothing new here, move along...
Code: Select all
int tex;
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
Make a DMbufferpool suitable for GL with just one buffer in it:
Code: Select all
DMparams *texPoolParams, *texImageParams;
DMbufferpool texPool;
DMbuffer texDMBuffer;
dmParamsCreate(&texImageParams);
dmSetImageDefaults(texImageParams, 1024, 1024, DM_IMAGE_PACKING_RGBA);
dmParamsSetEnum(texImageParams, DM_IMAGE_LAYOUT, DM_IMAGE_LAYOUT_GRAPHICS);
dmParamsCreate(&texPoolParams);
dmBufferSetPoolDefaults(texPoolParams, 1, 1024 * 1024 * 4, DM_FALSE, DM_FALSE);
dmBufferGetGLPoolParams(texImageParams, texPoolParams);
dmBufferCreatePool(texPoolParams, &texPool);
dmBufferAllocate(texPool, texDMBuffer);
Make a PBuffer:
Code: Select all
GLXFBConfig *fbConfigs;
GLXPbuffer texPBuffer;
int configCount;
int fbAttrs[] = {GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
GLX_DOUBLEBUFFER, False,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
None};
int pbAttrs[] = {GLX_PBUFFER_WIDTH, 1024,
GLX_PBUFFER_HEIGHT, 1024,
GLX_PRESERVED_CONTENTS, True,
GLX_DIGITAL_MEDIA_PBUFFER_SGIX, True,
None};
fbConfigs = glXChooseFBConfig(xDisplay, DefaultScreen(xDisplay), fbAttrs,
&configCount);
texPBuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbAttrs);
Associate the PBuffer with the DMBuffer. The glTexSubImage2D() copies by reference (hurrah!) if everything above has worked, so you only need to do it once. Thereafter drawing into the PBuffer draws straight into the texture.
Code: Select all
glXAssociateDMPbufferSGIX(xDisplay, texPBuffer, texImageParams, texDMBuffer);
glXMakeContextCurrent(xDisplay, glxPBuffer, glxPBuffer, glxContext);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024, 1024);
Now on each frame, you draw into the texture, then draw a textured quad as big as you like, keeping aspect would be a good plan:
Code: Select all
glXMakeContextCurrent(xDisplay, texPBuffer, texPBuffer, glxContext);
glRasterPos2i(0, height);
glPixelZoom(1.0, -1.0);
glDrawPixels(width, height, GL_YCRCB_422_SGIX, GL_UNSIGNED_BYTE, pixels);
glXMakeContextCurrent(xDisplay, glxWindow, glxWindow, glxContext);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2i(0, 0);
glTexCoord2f(0.0, (float)height/1024.0);
glVertex2i(0, 1024);
glTexCoord2f((float)width/1024.0, (float)height/1024.0);
glVertex2i(1280, 1024);
glTexCoord2f((float)width/1024.0, 0.0);
glVertex2i(1280, 0);
glEnd();
glXSwapBuffers(xDisplay, glxWin);
I'm sure you get the idea... some checking of return vales and liberal use of XFree() might be wise :) Crime can handle the fill rates up to PAL sizes. Should go at about the same speed as using glTexSubImage2D() on every frame in the normal textured-zooming manner. Wouldn't cope with zooming PAL up to 1600x1024, perhaps, that would be about 51MPixels/sec, probably not achievable on mips4 O2s and surely not on the broken 175Mhz R10k.
Enjoy...