NSTextField 와 겹쳐서 표시할 수 있는 OpenGL 의 View 를 구현하려면
위 그림의 샘플과 같이 OpenGL 로 그린 View 위에 텍스트 박스를 표시시키고 싶은 경우
CAOpenGLLayer
를 사용하면 잘 된다.OpenGL의
glClearColor
에서 배경을 반투명으로 설정하고 싶을 때의 주의점에 대해서도 메모하고 있다.배경
NSOpenGLView
는, 아이 요소 ( NSButton
등)를 가질 수 없게 되어 있다. NSButton
등을 자식 요소로 하지 않고 NSOpenGLView
위에 겹치도록 설치했다고 해도 OpenGL 그리기로 NSButton
등의 묘화가 무너져 버린다. NSOpenGLView
대신에, NSOpenGLView
오버라이드(override) 한 NSView
해결 방법
정책
NSButton
를 오버라이드(override) 한 커스텀 View 클래스를 작성해, 이 View 의 BackingLayer 로 OpenGL 의 렌더링 처리를 한다. NSView
를 확장한 커스텀 Layer 클래스를 사용한다. 샘플 구현
/* 指定した opacity の背景の上に、glut の teapot を表示するコードを何処かで実装する */
void DrawTeapotWithBackgroundOpacity(GLfloat opacity);
@interface LayerBackedGLView : NSView
{
}
@end
@interface CustomOpenGLLayer : CAOpenGLLayer
{
}
@end
@implementation CustomOpenGLLayer
-(BOOL)canDrawInCGLContext:(CGLContextObj)ctx
pixelFormat:(CGLPixelFormatObj)pf
forLayerTime:(CFTimeInterval)t
displayTime:(const CVTimeStamp *)ts
{
return YES;
}
-(void)drawInCGLContext:(CGLContextObj)ctx
pixelFormat:(CGLPixelFormatObj)pf
forLayerTime:(CFTimeInterval)t
displayTime:(const CVTimeStamp *)ts
{
CGLSetCurrentContext(ctx);
DrawTeapotWithBackgroundOpacity(0.5);
[super drawInCGLContext:ctx
pixelFormat:pf
forLayerTime:t
displayTime:ts];
}
-(BOOL)isOpaque
{
/* glClearColor で半透明な背景色を指定している場合、YES を返すとうまくいかない。 */
return NO;
}
@end
@implementation LayerBackedGLView : NSView
-(id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
/* ここを YES にすると、layer が必要になったタイミングで makeBackingLayer が呼ばれる */
[self setWantsLayer:YES];
/* Retina 対応. 以下を参照
https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSViewOpenGLAdditions
*/
[self setWantsBestResolutionOpenGLSurface:YES];
return self;
}
-(CALayer*)makeBackingLayer
{
CustomOpenGLLayer* layer = [[CustomOpenGLLayer alloc] init];
[layer setNeedsDisplayOnBoundsChange:YES];
return layer;
}
-(BOOL)isOpaque
{
/* glClearColor で半透明な背景色を指定している場合、YES を返すとうまくいかない。 */
return NO;
}
@end
주의점
OpenGL 그리기에서 배경색을 반투명하게 만들고 싶을 때
CAOpenGLLayer
NSView
CAOpenGLLayer
함수를 오버라이드(override) 하고 있는 경우, 어느쪽도 isOpaque
를 돌려주지 말아 주세요.
YES
를 오버라이드(override) 하지 않는 경우는 특별히 아무것도 하지 않아 OK. Mac OSX Yosemite
isOpaque
를 계승한 CAOpenGLLayer
라는 클래스가 있지만, 이쪽을 사용하면 Yosemite 에서 기대했던 대로 움직이지 않았다. 참고
LayerBackedOpenGLView
Layer-backed OpenGLView redraws only if window is resized
Reference
이 문제에 관하여(NSTextField 와 겹쳐서 표시할 수 있는 OpenGL 의 View 를 구현하려면), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kbinani/items/646bf875f52148f798a2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)