Hi,
I am trying to do a simple OpenGl tutorial using cocoa and c++. I have a view that is derived from NSView and I set to it the OpenGl context that is created in c++. I think this is alright because I can see the clear color in my window. I also create a vao, vbo and a shader program in c++ and do the drawing from the cvdisplay link callback. The problem is that the triangle is not rendered. I check for openGL and CGL errors and there is none, I also know that the callback is called because I can break in it and the window is of the clear color.
Does anybody know what I am doing wrong?
One of the thing that is bugging me is that the view need the openGL context, at the moment I share one openGL context in the 2 thread so I wrap each call to openGL with lock and unlock calls. The thing is that i don't know when i need to lock unlock and make it the current context on the view side. For example
initWithCGLContextObj from the NSOpenGLContext should I make the context current and lock before calling that? the API is really vague in this regard.
Thanks alot for your help!
MainView.mm
- (void) awakeFromNib
{
CoreGraphic::Renderer::getSingleton().initOpenGL();
CGLContextObj& context= CoreGraphic::Renderer::getSingleton().getOpenGlContext();
openglContex_ = [[NSOpenGLContext alloc] initWithCGLContextObj:context];
[openglContex_ setView:self];
if (!openglContex_)
{
[NSException raise:@"OpenGl context is null." format:@"OpenGL context was not initialized. initWithFrame was not called."];
}
CoreGraphic::Renderer::getSingleton().startRender();
}
Renderer.cpp
void Renderer::initOpenGL()
{
CGLPixelFormatAttribute attribs[] = {
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
//kCGLPFAAcceleratedCompute,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatObj pixelFormat;
GLint npix;
CGLChoosePixelFormat(attribs, &pixelFormat, &npix);
Verify_CGL(CGLCreateContext(pixelFormat, 0, &glContext_));
Verify_CGL(CGLLockContext(glContext_));
Verify_CGL(CGLSetCurrentContext(glContext_));
{
// Synchronize buffer swaps with vertical refresh rate
GLint swapInt = 1;
Verify_CGL(CGLSetParameter(glContext_, kCGLCPSwapInterval, &swapInt));
CVReturn cvResult = CVDisplayLinkCreateWithActiveCGDisplays(&displayLink_);
// Set the renderer output callback function
cvResult = CVDisplayLinkSetOutputCallback(displayLink_, &renderFrame, this);
// Set the display link for the current renderer
cvResult = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink_, glContext_, pixelFormat);
// Depth test will always be enabled
glEnable(GL_DEPTH_TEST);
// We will always cull back faces for better performance
glEnable(GL_CULL_FACE);
// Always use this clear color
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
Verify_CGL(CGLDestroyPixelFormat(pixelFormat));
// Vertex Array Objects
{
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
}
// Create a vertex buffer object
{
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
float vertices[] = {
0.0f, 0.5f, 0.0f, 1.0f, // Vertex 1 (X, Y, Z)
0.5f, -0.5f, 0.0f, 1.0f, // Vertex 2 (X, Y, Z)
-0.5f, -0.5f, 0.0f, 1.0f // Vertex 3 (X, Y, Z)
};
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );
}
// Compiling shaders
{
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, vertexShaderSource, nullptr );
glCompileShader( vertexShader );
// Get the compilation log.
printShaderCompilationLog(vertexShader);
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, pixelShaderSource, nullptr );
glCompileShader( fragmentShader );
// Get the compilation log.
printShaderCompilationLog(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glBindFragDataLocation( shaderProgram, 0, "outColor" );
glLinkProgram( shaderProgram );
}
// Use a shader program
{
posAttrib = glGetAttribLocation( shaderProgram, "position" );
glEnableVertexAttribArray( posAttrib );
glVertexAttribPointer( posAttrib, 4, GL_FLOAT, GL_FALSE, 0, nullptr );
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Verify_CGL(CGLSetCurrentContext(0));
Verify_CGL(CGLUnlockContext(glContext_));
PRINT_OPENGL_ERRORS();
}
//CVDisplaylink callback
static CVReturn renderFrame(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
(void)displayLink;
(void)now;
(void)outputTime;
(void)flagsIn;
(void)flagsOut;
(void)displayLinkContext;
CVReturn result = kCVReturnSuccess;
CGLContextObj& glContext = Renderer::getSingleton().getOpenGlContext();
Verify_CGL(CGLLockContext(glContext));
Verify_CGL(CGLSetCurrentContext(glContext));
glClearColor( 0.0f, 0.0f, 1.0f, 0.0f );
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram( shaderProgram );
glBindVertexArray(vao);
glDrawArrays( GL_TRIANGLES, 0, 3 );
glBindVertexArray(0);
glUseProgram(0);
Verify_CGL(CGLFlushDrawable(glContext));
Verify_CGL(CGLUnlockContext(glContext));
PRINT_OPENGL_ERRORS();
return result;
}
0 comments:
Post a Comment