OpenGL на Mac операции - PullRequest
       1

OpenGL на Mac операции

8 голосов
/ 02 апреля 2011

Это действительно вопрос архитектуры или вопрос «как это работает», а не проблема, которую нужно решить.

В документации Apple утверждается, что CGL является API-интерфейсом самого низкого уровня для управления контекстами OpenGL, однако в нем отсутствует функциональность, которая позволяет подключать контекст к окну. AGL и Cocoa могут без проблем связать контекст с окном, поэтому возникает вопрос - как они это делают, если они построены на CGL?

Очевидный способ, по-видимому, заключается в том, что они используют CGL для рендеринга в закадровую память, а затем способны каким-либо образом это компоновать. Если это так, как это происходит?

Ответы [ 3 ]

8 голосов
/ 12 апреля 2011

Существует частная функция CGLSetSurface, которая соединяет поверхность, которая является частью окна, с контекстом GL, созданным с помощью CGLCreateContext.И AGL, и Какао используют эту функцию внутренне.

1 голос
/ 08 июня 2017

Полный пример:

/*
mkdir -p build/test.app/Contents/MacOS
clang++ --std=c++11 
 -fno-exceptions
 -fno-rtti
 -mmacosx-version-min=10.9
 -Wno-writable-strings
 -Wno-deprecated-declarations
 -framework OpenGL
 -framework Carbon
 -g gui8.cpp
 -o build/test.app/Contents/MacOS/test


 */


#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
#include <OpenGL/CGLTypes.h>
#include <OpenGL/CGLCurrent.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>

typedef int CGSConnectionID;
typedef int CGSWindowID;
typedef int CGSSurfaceID;

typedef uint32_t _CGWindowID;

extern "C" {

typedef int CGSConnection;
typedef int CGSWindow;
typedef int CGSValue;

typedef enum _CGSWindowOrderingMode {
   kCGSOrderAbove                =  1, // Window is ordered above target.
   kCGSOrderBelow                = -1, // Window is ordered below target.
   kCGSOrderOut                  =  0  // Window is removed from the on-screen window list.
} CGSWindowOrderingMode;

typedef void *CGSRegion;
typedef CGSRegion *CGSRegionRef;
typedef CGSWindow *CGSWindowRef;

extern CGError CGSNewWindow( CGSConnection cid, int, float, float, const CGSRegion, CGSWindowRef);
extern CGError CGSNewRegionWithRect( const CGRect * rect, CGSRegionRef newRegion );
extern OSStatus CGSOrderWindow(CGSConnection cid, CGSWindow win, CGSWindowOrderingMode place, CGSWindow relativeToWindow /* nullable */);
extern OSStatus CGSSetWindowProperty(const CGSConnection cid, CGSWindow wid, CGSValue key, CGSValue value);
extern CGSConnectionID CGSMainConnectionID(void);
extern CGError CGSAddSurface(CGSConnectionID cid, _CGWindowID wid, CGSSurfaceID *sid);
extern CGError CGSSetSurfaceBounds(CGSConnectionID cid, _CGWindowID wid, CGSSurfaceID sid, CGRect rect);
extern CGError CGSOrderSurface(CGSConnectionID cid, _CGWindowID wid, CGSSurfaceID sid, int a, int b);
extern OSStatus CGSMoveWindow(const CGSConnection cid, const CGSWindow wid, CGPoint *point);
extern CGLError CGLSetSurface(CGLContextObj gl, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid);

}
#define kCGSBufferedBackingType 2


int main () {

    CGLContextObj cgl_context = NULL;
    CGSWindow window = 0;

    int width = 500, height = 500;
    CGPoint window_pos = { .x = 200, .y = 200 };
    bool quit = false;

    CGSConnectionID connection_id = CGSMainConnectionID();
    assert(connection_id);

    {

        CGSRegion region = NULL;
        CGRect r = CGRectMake(0,0, width, height);
        auto err1 = CGSNewRegionWithRect(&r, &region);
        assert(region);
        auto err2 = CGSNewWindow(connection_id, kCGSBufferedBackingType, window_pos.x, window_pos.y, region, &window);
        assert(window);
        auto err3 = CGSOrderWindow(connection_id, window, kCGSOrderAbove, 0);
        assert (err3 == kCGErrorSuccess);


        CGLPixelFormatAttribute attributes[] = {
            kCGLPFADoubleBuffer,
            kCGLPFAAccelerated, // Hardware rendering
            // kCGLPFARendererID, (CGLPixelFormatAttribute) kCGLRendererGenericFloatID, // Software rendering
            (CGLPixelFormatAttribute)0
        };

        CGLPixelFormatObj pix;
        GLint num;
        auto err4 = CGLChoosePixelFormat(attributes, &pix, &num);
        assert(err4 == kCGLNoError); // CGLErrorString(err1)
        assert(pix);

        CGLCreateContext(pix, NULL, &cgl_context);
        assert(cgl_context);
        CGLDestroyPixelFormat(pix);
        CGLSetCurrentContext(cgl_context);

        GLint v_sync_enabled = 1;
        CGLSetParameter(cgl_context, kCGLCPSwapInterval, &v_sync_enabled);

        CGSSurfaceID surface_id = 0;
        auto err5 = CGSAddSurface(connection_id, window, &surface_id);
        assert(err5 == kCGErrorSuccess);
        auto err6 = CGSSetSurfaceBounds(connection_id, window, surface_id, CGRectMake(0, 0, width, height));
        assert(err6 == kCGErrorSuccess);
        auto err7 = CGSOrderSurface(connection_id, window, surface_id, 1, 0);
        assert(err7 == kCGErrorSuccess);

        auto err8 = CGLSetSurface(cgl_context, connection_id, window, surface_id);
        assert(err8 == kCGLNoError);

        GLint drawable = 0;
        CGLGetParameter(cgl_context, kCGLCPHasDrawable, &drawable);
        assert(drawable == 1);




    }

    assert(glGetError() == GL_NO_ERROR);

    CGPoint drag_starting_position;
    bool drag_started = false;
    while (!quit) {

        glClearColor(1,1,0,1);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        static float a = 0;
        glRotatef(a * 1000, 0, 0, 1);
        // printf("a: %f\n", a);
        a= a + .001;
        glBegin(GL_QUADS);
        if (a>1.5) a=0;
        glColor4f(0,a,1,1);
        glVertex2f(0.25, 0.25);
        glVertex2f(0.75, 0.25);
        glVertex2f(0.75, 0.75);
        glVertex2f(0.25, 0.75);
        glEnd();

        auto err1 = CGLFlushDrawable(cgl_context);
        assert(err1 == kCGLNoError);

        assert(glGetError() == GL_NO_ERROR);

    }

    CGLSetCurrentContext(NULL);
    CGLDestroyContext(cgl_context);

}
0 голосов
/ 22 октября 2012

С тех пор я не возвращался к этому вопросу, вот что я смог из него сделать: Недокументированные API-интерфейсы, плавающие вокруг сети, кажутся недостающим блоком из-за всего этого - я смог CGLSetSurface без возврата ошибки, однако в итоге он не сделал ничего особенного. Очевидно, есть еще кое-что, что нужно сделать, чтобы все работало на таком низком уровне.

В целом, похоже, нет нормального способа контролировать все через CGL. Способ справиться со всем, как и все остальные, очевидно - через Cocoa classes (, используя CGL для всего, кроме присоединения к окну, это нормально, хотя после этого момента ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...