I'm using the Syphon framework to try and push frames of video from a server to a client application.
Syphon requires you to use OpenGL textures instead of normal images.
Because of this, I'm trying to render a CGImageRef as a texture and send it on to be published.
I'm creating my CGL context as so:
CGLPixelFormatAttribute attribs[13] = {
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core, // This sets the context to 3.2
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1,
kCGLPFASamples, (CGLPixelFormatAttribute)4,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatObj pix;
GLint npix;
CGLChoosePixelFormat(attribs, &pix, &npix);
CGLCreateContext(pix, 0, &_ctx);
I already have a CGImageRef that I know can be rendered properly as an NSImage.
I'm rendering the texture as so:
CGLLockContext(cgl_ctx);
if (_texture) {
glDeleteTextures(1, &_texture);
}
int width = 1920;
int height = 1080;
GLubyte* imageData = malloc(width * height * 4);
CGContextRef imageContext = CGBitmapContextCreate(imageData, width, height, 8, width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, width, height), image);
CGContextRelease(imageContext);
GLuint frameBuffer;
GLenum status;
glGenFramebuffersEXT(1, &frameBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glGenTextures(1, &_texture);
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, width, height, 0, GL_RGBA, GL_TEXTURE_2D, imageData);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
NSLog(@"OpenGL Error");
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
CGLUnlockContext(cgl_ctx);
The rendering code is in a different class, but the context should be passed through and is the same.
I've tried the advice in pretty much every other instance of this problem to no avail.
The second-to-last parameter in glTexImage2D
is:
type
Specifies the data type of the pixel data. The following symbolic values are accepted:GL_UNSIGNED_BYTE
,GL_BYTE
,GL_UNSIGNED_SHORT
,GL_SHORT
,GL_UNSIGNED_INT
,GL_INT
,GL_FLOAT
,GL_UNSIGNED_BYTE_3_3_2
,GL_UNSIGNED_BYTE_2_3_3_REV
,GL_UNSIGNED_SHORT_5_6_5
,GL_UNSIGNED_SHORT_5_6_5_REV
,GL_UNSIGNED_SHORT_4_4_4_4
,GL_UNSIGNED_SHORT_4_4_4_4_REV
,GL_UNSIGNED_SHORT_5_5_5_1
,GL_UNSIGNED_SHORT_1_5_5_5_REV
,GL_UNSIGNED_INT_8_8_8_8
,GL_UNSIGNED_INT_8_8_8_8_REV
,GL_UNSIGNED_INT_10_10_10_2
, andGL_UNSIGNED_INT_2_10_10_10_REV
.
GL_TEXTURE_2D
doesn't make sense there, it should be whatever the data type of elements of imageData
is.
You should also be checking your OpenGL errors with glGetError
or ARB_debug_output
. You would have immediately be shown what's wrong:
Source:OpenGL Type:Error ID:5 Severity:High Message:GL_INVALID_ENUM in glTexImage2D(incompatible format = GL_RGBA, type = GL_TEXTURE_2D)
There are a few problems in this code. The following are critical to get things working:
As also pointed out in an earlier answer by @orost, the type parameter for the glTexImage2D()
call is invalid. It should be:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
The texture is never attached as an FBO target. While you set up the FBO, you need:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);
There are a couple more items that probably won't keep you from getting it running, but I would recommend to change them anyway:
glTexImage2D()
is uninitialized anyway, so that can't do much good. It's much cleaner to pass NULL
as the data argument, as I already did in the call shown above. EXT
form of the FBO entry points. This is standard functionality in OpenGL 3.x. The EXT
form will probably work as long as you use it consistently, but you risk ugly surprises if you mix it with standard entry points.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.