I'm pretty sure now after hours of bashing that this cannot be done.
This is my code so far (BELOW) for rendering to a texture; it does the job, but is very wasteful. I only want a single 8-bit channel, possibly 16-bit greyscale. I don't want a useless R G and B channel.
But if I try to switch GL_RGBA /*GL_ALPHA*/ in glTexImage2D, glCheckFramebufferStatus catches a 'frame buffer incomplete' error: 36054 0x8CD6 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
guys on IRC suggest GL_R but Xcode doesn't offer autocompleteion for that, so it looks like maybe it is one of those things pruned out of GL for GLES
but that seems really bizarre! this is a mobile device. Surely something that reduces by a factor of four the amount of bits needed to perform an operation... surely this would be one of the last things to take out.
?!?
can anyone bury this one definitively? Is it possible to render onto a single channel texture in GLES2.0?
+ (void) blurTexture: (GLuint) in_texId
POTWidth: (GLuint) in_W
POTHeight: (GLuint) in_H
returningTexId: (GLuint*) out_pTexId
{
// search HELP: 'Using a Framebuffer Object as a Texture'
// http://stackoverflow.com/questions/3613889/gl-framebuffer-incomplete-attachment-when-trying-to-attach-texture
// Create the destination texture, and attach it to the framebuffer’s color attachment point.
// create the texture
GLuint id_texDest;
{
// fragshader will use 0
glActiveTexture( GL_TEXTURE0 );
// Ask GL to give us a texture-ID for us to use
glGenTextures( 1, & id_texDest );
glBindTexture( GL_TEXTURE_2D, id_texDest );
// actually allocate memory for this texture
GLuint pixCount = in_W * in_H;
typedef struct { uint8_t r, g, b, a } rgba;
rgba * alphas = calloc( pixCount, sizeof( rgba ) );
// XOR texture
int pix=0;
for ( int x = 0; x < in_W; x++ )
{
for ( int y = 0; y < in_H; y++ )
{
//alphas[ pix ].r = (y < 256) ? x^y : 0;
//alphas[ pix ].g = (y < 512) ? 127 : 0;
//alphas[ pix ].b = (y < 768) ? 127 : 0;
alphas[ pix ].a = (y < 512) ? x^y : 0; // half mottled, half black
pix++;
}
}
// set some params on the ACTIVE texture
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/ );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
// WRITE/COPY from P into active texture
glTexImage2D( GL_TEXTURE_2D, 0,
GL_RGBA /*GL_ALPHA*/, in_W, in_H, 0,
GL_RGBA /*GL_ALPHA*/,
GL_UNSIGNED_BYTE,
(void *) alphas );
//glGenerateMipmap( GL_TEXTURE_2D );
free( alphas );
glLogAndFlushErrors();
}
GLuint textureFrameBuffer;
{
GLint oldFBO;
glGetIntegerv( GL_FRAMEBUFFER_BINDING, & oldFBO );
// create framebuffer
glGenFramebuffers( 1, & textureFrameBuffer );
glBindFramebuffer( GL_FRAMEBUFFER, textureFrameBuffer );
// attach renderbuffer
glFramebufferTexture2D( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
id_texDest,
0 );
//glDisable( GL_DEPTH_TEST );
// Test the framebuffer for completeness. This test only needs to be performed when the framebuffer’s configuration changes.
GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER ) ;
NSAssert1( status == GL_FRAMEBUFFER_COMPLETE, @"failed to make complete framebuffer object %x", status );
// 36054 0x8CD6 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
// unbind frame buffer
glBindFramebuffer( GL_FRAMEBUFFER, oldFBO );
}
glLogAndFlushErrors();
// clear texture bitmap to backcolor
{
GLint oldFBO;
glGetIntegerv( GL_FRAMEBUFFER_BINDING, & oldFBO );
glBindFramebuffer( GL_FRAMEBUFFER, textureFrameBuffer );
glLogAndFlushErrors();
{
float j = 0.1f;
glClearColor( j, j, j, j );
glLogAndFlushErrors();
glClear( GL_COLOR_BUFFER_BIT );
glLogAndFlushErrors();
}
glBindFramebuffer( GL_FRAMEBUFFER, oldFBO );
}
glDeleteFramebuffers( 1, & textureFrameBuffer );
* out_pTexId = id_texDest;
glLogAndFlushErrors();
}
Since iOS 5.0, you can render to both 1 and 2 channel textures using GL_EXT_texture_rg.
http://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_rg.txt
http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iOS5.html#//apple_ref/doc/uid/TP30915195-SW47
Edit: I've tested this and it works, but only on A5 and above (iPad2/3/4/mini, iPhone4S/5, iPod touch 5th gen). Unfortunately it's not available on A4 and older where it's needed most (iPhone4, iPod touch 4th gen, 3GS, iPad1).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With