I've implemented sample code to convert YUV colorspace to RGB using openGL ES 3.0 for android. I've vertex & fragment shaders where i defined converison formula.
I've created textures as below,
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &ytex);
glBindTexture(GL_TEXTURE_2D,ytex);
GLint textureBinding;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
// Setup the texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Define the texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ytex, 0);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &utex);
glBindTexture(GL_TEXTURE_2D,utex);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 320, 240, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, uBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, utex, 0);
glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &vtex);
glBindTexture(GL_TEXTURE_2D,vtex);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
if(textureBinding == 0)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, textureBinding, NULL, infoLog);
errormsg = infoLog;
free (infoLog);
}
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 320, 240, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
I'm not getting any errors when i verify using glGetError().
The output of textures i dont want to display on viewport, instead i want to store it in one buffer in order to use the output later. So i created framebuffer and render buffer as below,
//Framebuffer
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, vtex, 0);
//Check the framebuffer status
GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
char* infoLog = (char*) malloc(100);
glGetProgramInfoLog(programObject, status, NULL, infoLog);
errormsg = infoLog;
free (infoLog);}
When i verify the status it is always returning 36054(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), but the same returning GL_FRAMEBUFFER_COMPLETE when i unbind the buffer before calling glCheckFrameBufferStatus()
glbindFrameBuffer(GL_FRAMEBUFFER, 0);
So later i want to read the output from the framebuffer using glReadpixels(), but that is also failing. Please someone help how to resolve this issue?
36054 means GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT check your view's frame is right ?
There is no implementation of OpenGL / OpenGL ES supports alpha or luminance textures as color-renderable. You can replicate the behavior with GL_R8,GL_RG8. These two formats are very useful when you want to draw into a one or two-channel image format using an FBO (since GL_LUMINANCE, GL_ALPHA and GL_LUMINANCE_ALPHA are not color-renderable formats).
Try replacing internal format with GL_R8 and format with GL_RED.
Related
I'm going to draw 2 textures at the same time. (from different videos, getting different frame textures in real time...)
It works well and the code is below.
// module 1---------------
{
CVPixelBufferLockBaseAddress(cameraFrame, 0);
int bufferHeight = CVPixelBufferGetHeight(cameraFrame);
int bufferWidth = CVPixelBufferGetWidth(cameraFrame);
// Create a new texture from the camera frame data, display that using the shaders
glGenTextures(1, &videoFrameTexture);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
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);
// Using BGRA extension to pull in video frame data directly
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraFrame));
}
{
CVPixelBufferLockBaseAddress(buf2, 0);
int bufferHeight = CVPixelBufferGetHeight(buf2);
int bufferWidth = CVPixelBufferGetWidth(buf2);
// Create a new texture from the camera frame data, display that using the shaders
glGenTextures(1, &videoFrameTexture2);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture2);
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);
// Using BGRA extension to pull in video frame data directly
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(buf2));
}
[self drawFrame]; // module2---------
{
glDeleteTextures(1, &videoFrameTexture);
CVPixelBufferUnlockBaseAddress(cameraFrame, 0);
glDeleteTextures(1, &videoFrameTexture2);
CVPixelBufferUnlockBaseAddress(buf2, 0);
}
But its speed is too slow. Mainly module2 is slow.
I checked about glTexSubImage2D instead of glTexImage2D, but no good result.
Is there any solution to speed up?
I got solution, I called glGenTextures only once at first, and draw in loop. Speed doubled now. And I'll replace the glTexImage2D with glTexSubImage2D. And I deleted the glDeleteTextures!
CVOpenGLESTextureCacheRef, This is the awesome key for speed-up! almost real time!!!
I have been trying to get shadow maps to work, but I can;t even get past the depth buffer part of it. I've been looking on the internet for hours now, yadayadayada. Here is my code so far -
Making the FBO and the texture for depth:
GLuint framebuffer;
GLuint depth;
GLuint texture;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1280, 800, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1280, 800, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glDrawBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "There was a problem with making the framebuffer\n";
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return framebuffer;
Rendering the 'depth' to a quad for viewing:
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int i = 0; i < objects.size(); i++)
{
objects[i].renderObjectForDepth();
}
glBindFrameBuffer(GL_TEXTURE_2D,0);
glBindTexture2D(GL_TEXTURE_2D, texture)
drawQuad();
And to me, everything looks fine, but It generates images like the picture attached. I've been ripping out my hair for days now, and any help would be appreciated.
EDIT: It was because I was rendering a blank texture, IE the texture color that never got written to. After drawing the depth texture and writing the color texture, it works fine. But how do I do it without a color texture?
Check that the following two states are set when rendering to your depth-only FBO:
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
I am attempting to get my first shadow map up and running (from here), but I have run into a very strange problem. This is the code that causes the error:
#interface HSOpenGLView() {
GLuint shadowFramebuffer;
GLuint shadowTexture;
}
#end
#implementation HSOpenGLView
- (void) drawRect:(NSRect)dirtyRect {
}
#pragma mark - Init
- (void) prepareOpenGL {
[super prepareOpenGL];
glEnable(GL_TEXTURE_2D);
glGenFramebuffers(1, &shadowFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFramebuffer);
// Depth texture. Slower than a depth buffer, but you can sample it later in your shader
glGenTextures(1, &shadowTexture);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowTexture, 0);
//glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadowTexture);
glDrawBuffer(GL_NONE); // No color buffer is drawn to.
// Always check that our framebuffer is ok
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
NSLog(#"Failed to create the shadow framebuffer! %u", glGetError());
}
}
This class is a subclass of 'NSOpenGLView'. When it prints the error number it turns out to be '0'. What could possibly be causing it?
Add a call to glReadBuffer(GL_NONE) after your call to glDrawBuffer(GL_NONE). You need to indicate that your FBO doesn't have a color buffer source for read operations too.
I'm using cpp/marmalade to make a game for ios, but sometimes textures render corrupted.
Here is the source texture file:
Example of a currupted texture:
I'm loading texture with this code:
VGTexture2D* VGTextureLoader::loadImage(std::string imagefile)
{
CIwImage img;
img.LoadFromFile(imagefile.c_str());
// Convert to an OpenGL ES native format
CIwImage nativeImg;
nativeImg.SetFormat(CIwImage::ABGR_8888);
img.ConvertToImage(&nativeImg);
// Generate texture object
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// Upload
uint32 width = img.GetWidth();
uint32 height = img.GetHeight();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nativeImg.GetTexels());
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);
// Create and return texture
VGTexture2D* tex = new VGTexture2D(texture, (float)width, (float)height);
return tex;
}
Your textures aren't being corrupted, but the channels do seem to be flipped. Could it be because you are converting the image to ABGR_8888 but then uploading it as GL_RGBA?
I get an error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT after I try to create a framebuffer that renders to a texture. I can't figure out what is wrong, any help is greatly appreciated.
Edit: Fixed it! Working code:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 768, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &rboID);
glBindRenderbuffer(GL_RENDERBUFFER, rboID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 768, 1024);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenFramebuffers(1, &backFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, backFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
[self checkFramebufferStatus];
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Note: If your version doesn't work, make sure you check for errors after each and every call AND that you clear the error before your first call, else you'll be error-checking the code before that.
It is likely that the texture is incomplete. The default MIN_FILTER for a texture specifies mipmapping, but you've provided only for Texture Level 0, so the texture itself is incomplete.
Add calls to glTexParamter to set the MIN_FILTER to one of the non-mipmapped modes.