I'm working on an app that feeds video frames coming from the camera into an OpenGL ES texture to create some effects. The app uses Core Video and its many convenience methods to create OpenGL textures and caches.
Now I'd like to use static images instead of the video buffer, and I'm looking for standard OpenGL methods in place of those available with Core Video.
For example:
CVOpenGLESTextureRef;
CVOpenGLESTextureCacheRef;
CVOpenGLESTextureCacheCreateTextureFromImage();
CVOpenGLESTextureGetTarget();
CVOpenGLESTextureGetName();
CVOpenGLESTextureCacheFlush();
What are the standard OpenGL types and methods that I can use in place of the code above to load and create a texture from a normale image?
Thanks
*EDIT*
Following Brad's suggestion I was able to do some progress... but still doesn't work correctly. I believe the problem is that the shader is expecting two separate textures to work properly. One for the Y plane and one for the UV plane.
Here's the code used to set them up
// Y-plane
glActiveTexture(GL_TEXTURE0);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RED_EXT, _textureWidth, _textureHeight, GL_RED_EXT, GL_UNSIGNED_BYTE, 0, &_lumaTexture);
glBindTexture(CVOpenGLESTextureGetTarget(_lumaTexture), CVOpenGLESTextureGetName(_lumaTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// UV-plane
glActiveTexture(GL_TEXTURE1);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RG_EXT, _textureWidth/2, _textureHeight/2, GL_RG_EXT, GL_UNSIGNED_BYTE, 1, &_chromaTexture);
glBindTexture(CVOpenGLESTextureGetTarget(_chromaTexture), CVOpenGLESTextureGetName(_chromaTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
So I changed it this way:
here's the setup
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &_lumaImageTexture);
glBindTexture(GL_TEXTURE_2D, _lumaImageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_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);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &_chromaImageTexture);
glBindTexture(GL_TEXTURE_2D, _chromaImageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_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);
and here is how I create them
// Y-plane
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _lumaImageTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _textureWidth, _textureHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// UV-plane
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _chromaImageTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _textureWidth, _textureHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
I guess the problem is in one of the parameters in the glTexImage2D function. I tried different combinations with different results... but never the correct one :)
All those methods do is hand you an OpenGL ES texture that corresponds to a CVPixelBuffer. Before these were introduced in iOS 5.0, we had to manually grab the pixel data from a CVPixelBuffer and upload that to a texture. You'd use the same process for a static image pulled from another source (unless you wanted to use some of the GLKit convenience classes).
The following is code that I've used for uploading static images. First, you need to get the image into a BGRA byte array:
if (shouldRedrawUsingCoreGraphics)
{
// For resized image, redraw
imageData = (GLubyte *) calloc(1, (int)pixelSizeToUseForTexture.width * (int)pixelSizeToUseForTexture.height * 4);
CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef imageContext = CGBitmapContextCreate(imageData, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 8, (int)pixelSizeToUseForTexture.width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pixelSizeToUseForTexture.width, pixelSizeToUseForTexture.height), newImageSource);
CGContextRelease(imageContext);
CGColorSpaceRelease(genericRGBColorspace);
}
else
{
// Access the raw image bytes directly
dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(newImageSource));
imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider);
}
In the above code, newImageSource is a CGImageRef. This shows two different paths for extracting bitmap data, with the first path surprisingly being faster in every benchmark I've run.
Once you have that, you simply need to upload it to your OpenGL ES texture:
glBindTexture(GL_TEXTURE_2D, outputTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
This assumes that you've already created outputTexture using something like the following:
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &outputTexture);
glBindTexture(GL_TEXTURE_2D, outputTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// This is necessary for non-power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
and that the correct EAGLContext is associated with the current thread by using +setCurrentContext:.
If I may make a suggestion, why not take a look at my open source framework that handles all of this for you in order to do image processing tasks? It might save you some effort here.
Related
I'm using GLES2 to make graphics, because I intend to make a mobile application, so it has different things from classic opengl, in the part of creating a framebuffer, I looked for how to do it, and I made a simple one, but I had a depth problem
I saw some more examples and I saw that I should add a texture for the depth, I tried to add it but it doesn't work, the texture is black, I'll leave the code snippet where I create the framebuffer
//texture
glGenTextures(1, &FBO_Texture);
glBindTexture(GL_TEXTURE_2D, FBO_Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 600, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
//depth texture
/*glGenTextures(1, &this->FBO_depth);
glBindTexture(GL_TEXTURE_2D, FBO_depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 600, 600, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);*/
//frame buffer
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBO_Texture, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, FBO_depth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
The internalFormat, format and type arguments of glTexImage2D have to match and have follow special rules. If the format is GL_DEPTH_COMPONENT, then the type cannot be GL_UNSIGNED_BYTE. Try GL_FLOAT or GL_UNSIGNED_INT:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 600, 600, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 600, 600, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
I am trying to apply post processing effects to a small test program for OS X. I am trying to render the image into a texture and then render the texture to the screen (i haven't even gotten to writing a second shader for the final image). My code still just renders a black screen.
Here is the code to create the FBO. It is executed once at the beginning.
-(void)setupFramebuffer{
[self setOpenGLContext:self.openGLContext];
glEnable(GL_TEXTURE_2D);
CGSize textureSize = CGSizeMake(1024, 1024);
glGenFramebuffersEXT(1, &textureFramebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, textureFramebuffer);
glGenTextures(1, &texture);
textureImage = MFGLImageCreateWithImageID(texture, textureSize);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureSize.width, textureSize.height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, texture, 0);
if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
NSLog(#"Failed to create FBO: %i", glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
glBindTexture(GL_TEXTURE_2D, 0);
g_CurrentlyBoundTexture = 0;
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
}
Here is the rendering code.
- (void)drawRect:(NSRect)dirtyRect
{
glUniform4f(g_OffsetUniform, dirtyRect.size.width/2.0, dirtyRect.size.height/2.0, 1, 1);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, textureFramebuffer);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
[batchRenderer addFrame:CGRectMake(0, 0, textureImage.size.width, textureImage.size.height) withAlpha:1 forImage:textureImage renderAlpha:YES offset:0 color:[NSColor redColor] renderMode:GL_TRIANGLES];
[batchRenderer finishAndDrawBatch];
glFlush();
}
Right now i am just clearing the FBO buffer and writing a red color to it. Then i pass the image to my batch renderer for rendering, however i still get nothing but a black screen. (The batch renderer is not the issue, the exact same code is used in other programs) Furthermore, when i comment out the code that binds the FBO in the draw method it draws the red without an issue.
I'm learning OpenGL ES with the tutorial on raywenderlich.com http://www.raywenderlich.com/4404/opengl-es-2-0-for-iphone-tutorial-part-2-textures
When I get started to tweak the example project to grasp a UIView's content as the texture to get rendered, it's only black screen turns out just like:
The black view is the OpenGL ES view.
I used the code posted by Tommy in this post: Render contents of UIView as an OpenGL texture, and here is my version:
- (GLuint)createTexture:(UIView *)view
{
size_t width = CGRectGetWidth(view.layer.bounds) * [UIScreen mainScreen].scale;
size_t height = CGRectGetHeight(view.layer.bounds) * [UIScreen mainScreen].scale;
GLubyte * texturePixelBuffer = (GLubyte *) calloc(width * height * 4,
sizeof(GLubyte));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(texturePixelBuffer,
width, height, 8, width*4, colorSpace,
kCGImageAlphaPremultipliedLast |
kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
[view.layer renderInContext:context];
CGContextRelease(context);
GLuint texName;
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, texturePixelBuffer);
free(texturePixelBuffer);
return texName;
}
According to Open GL ES 2.0 Specification, texture can either be the power of two or not. But you must use
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_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);
to enable non-power-of-two texture support.
ES 2.0 newbie here. I'm currently trying to make some 3D interlaced images from stereo images with ES 2.0 and the PowerVR SDK. I can output one image texture fine, but when I try to output the second one, I seem to be overwriting the first. So, my question is, given the fragment shader below, can I use it to draw two textures, or can the sampler2d uniform only be bound to one texture unit?
Here's the fragment shader (taken from the PowerVR "training course" sample programs):
uniform sampler2D sampler2d;\
varying mediump vec2 myTexCoord;\
void main (void)\
{\
gl_FragColor = texture2D(sampler2d,myTexCoord);\
}";
And here's how I am loading the image textures into the shader:
//LEFT IMAGE
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &m_uiTexture_left);
glBindTexture(GL_TEXTURE_2D, m_uiTexture_left);
glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pwr2Width, pwr2Height,0, GL_RGB, GL_UNSIGNED_BYTE, xImageL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GLfloat afVertices[30] = {0.0};
genVertices(afVertices);
glGenBuffers(1, &m_ui32Vbo_leftimage);
m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_leftimage);
glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//RIGHT IMAGE
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &m_uiTexture_right);
glBindTexture(GL_TEXTURE_2D, m_uiTexture_right);
glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pwr2Width, pwr2Height,0, GL_RGB, GL_UNSIGNED_BYTE, xImageR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenBuffers(1, &m_ui32Vbo_rightimage);
m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_rightimage);
glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
So, is this code just overwriting the sampler2d uniform? Do I need another uniform or shader for the second image?
Ok, so as I mentioned in the comment above, I eventually found the answer here: http://www.opentk.com/node/2559. As mentioned by the user "Profet" on that forum, one way to re-use the fragment shader is to move the glUniform1i() calls down to the render function, i.e. call glUniform1i() to pass the first texture to the shader, call glDraw (draw your texture), then call glUniform1i() and pass the second texture to the shader (and draw). So now my initialise() code is as follows:
//LEFT IMAGE
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &m_uiTexture_left);
glBindTexture(GL_TEXTURE_2D, m_uiTexture_left);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pwr2Width, pwr2Height,0, GL_RGB, GL_UNSIGNED_BYTE, xImageL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GLfloat afVertices[30] = {0.0};
genVertices(afVertices);
glGenBuffers(1, &m_ui32Vbo_leftimage);
m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_leftimage);
glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//RIGHT IMAGE
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &m_uiTexture_right);
glBindTexture(GL_TEXTURE_2D, m_uiTexture_right);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pwr2Width, pwr2Height,0, GL_RGB, GL_UNSIGNED_BYTE, xImageR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenBuffers(1, &m_ui32Vbo_rightimage);
m_ui32VertexStride = 5 * sizeof(GLfloat); // 3 floats for the pos, 2 for the UVs
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_rightimage);
glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
And my render() code goes like:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& LEFT IMAGE &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 1); //draw on uneven lines only
glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 0); //pass texture unit 0 to shader
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_leftimage); // unbound this near the end of initView, so need to re-bind it
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
glEnableVertexAttribArray(TEXCOORD_ARRAY);
glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& RIGHT IMAGE &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 1); //draw on even lines only
glUniform1i(glGetUniformLocation(m_uiProgramObject, "sampler2d"), 1);
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo_rightimage);
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
glEnableVertexAttribArray(TEXCOORD_ARRAY);
glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Hope this helps someone someday! :)
The right way is when you send what texture you want to what texture unit you want:
http://www.opengl.org/wiki/Sampler_(GLSL)#Binding_textures_to_samplers
I am creating a frame buffer object for Render to Texture setup. It works perfectly fine on the iPhone simulator but on the Device the glCheckFramebufferStatus(GL_FRAMEBUFFER) function returns GL_FRAMEBUFFER_UNSUPPORTED at the end of the FBO creation.
I am testing it on iPhone 3GS with iOS 5.
Here is the code:
GLenum errNo;
GLsizei width = 320;
GLsizei height = 480;
GLuint textureHandle;
GLuint fboHandle;
glGetError();
glGenTextures(1, &textureHandle);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_HALF_FLOAT_OES, NULL);
glGenFramebuffers(1, &fboHandle);
glBindFramebuffer(GL_FRAMEBUFFER,fboHandle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureHandle, 0);
errNo = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(GL_FRAMEBUFFER_COMPLETE != errNo){
printf("Unable to create FBO. errNo: %x\n",errNo);
}
I am clueless. How should I debug this problem ?
Found the solution. GL_HALF_FLOAT is not supported on iPhone. I used GL_UNSIGNED_BYTE instead and it works now.
Does not work:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_HALF_FLOAT_OES, NULL);
Works:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE, NULL);