OpenGL 4.6 on Metal

Related tags

Graphics MGL
Overview

MGL

OpenGL 4.6 on Metal

This is a start for porting OpenGL 4.6 on top of Metal, most of it is functional and has been tested. The tests are functional, not coverage tests so they test the functionality of a path not all the possible permutations.

So far the following parts of OpenGL work

Vertex Arrays Buffers Textures Programs Shaders Vertex Fragment Compute Samplers Alpha Blending Depth and Stencil Testing Framebuffer Objects Drawbuffers Most of the draw calls Elements / Instancing and such

GLFW support

I modified a version of GLFW to work with MGL, it replaces the default MacOS OpenGL contexts. The changes are included in the repository and should build correctly with the MGL xcode project.

Mapping OpenGL onto Metal

I mapped as much of the functionality of Metal I could into OpenGL 4.6, it's surprising how much I was able to map directly from OpenGL state to Metal. But I suppose Metal evolved to meet market requirements and since OpenGL was in place the same features existed just in another form.

Not all of the functionality for OpenGL is available, but I didn't build this for conformance I just wanted to program OpenGL on the MacOS platform.

Parsing the OpenGL 4.6 XML spec

In the beginning I used ezxml to parse the gl.xml file for all the enums and functions, then printed out one giant file with all the functions. I then used the same parser to create the dispatch tables and data structures. As each functional part was built I separated blocks of functions into these functions like buffers / textures / shaders / programs.

SPIRV to Metal

I really couldn't have done this project without all the SPIRV support from Khronos, once I found out I could translate GLSL into Metal using some of the SPIRV tools this project became a reality. There are some parts in GLSL that Metal just doesn't support like Geometry Shaders, I think the way forward on support for Geometry Shaders is to translate the vertex and geometry shaders into LLVM from SPIRV then execute the results from processing them on the CPU through a passthrough vertex shader in the pipeline. Some parts of the GLSL spec probably won't map to Metal but more testing and exposure to developers will show what works and what doesn't/

OpenGL functions and how they work

Each OpenGL function starts in gl_core.c

void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
{
    GLMContext ctx = GET_CONTEXT();

    ctx->dispatch.tex_image2D(ctx, target, level, internalformat, width, height, border, format, type, pixels);
}

glTexImage2D calls into a dispatch table which lands on a mgl equivalent

void mglTexImage2D(GLMContext ctx, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
    Texture *tex;
    GLuint face;
    GLboolean is_array;
    GLboolean proxy;

    face = 0;
    is_array = false;
    proxy = false;

    switch(target)
    {
        case GL_TEXTURE_2D:
            break;

        case GL_PROXY_TEXTURE_2D:
        case GL_PROXY_TEXTURE_CUBE_MAP:
            proxy = true;
            break;

        case GL_PROXY_TEXTURE_1D_ARRAY:
            is_array = true;
            proxy = true;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
            face = target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
            break;

        case GL_PROXY_TEXTURE_RECTANGLE:
            proxy = true;
            ERROR_CHECK_RETURN(level==0, GL_INVALID_OPERATION);
            break;

        case GL_TEXTURE_RECTANGLE:
            ERROR_CHECK_RETURN(level==0, GL_INVALID_OPERATION);
            break;

        default:
            ERROR_RETURN(GL_INVALID_ENUM);
    }

    ERROR_CHECK_RETURN(level >= 0, GL_INVALID_VALUE);

    // verifyFormatType sets the error
    ERROR_CHECK_RETURN(verifyInternalFormatAndFormatType(ctx, internalformat, format, type), 0);

    ERROR_CHECK_RETURN(width >= 0, GL_INVALID_VALUE);
    ERROR_CHECK_RETURN(height >= 0, GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(border == 0, GL_INVALID_VALUE);

    tex = getTex(ctx, 0, target);

    ERROR_CHECK_RETURN(tex, GL_INVALID_OPERATION);

    tex->access = GL_READ_ONLY;

    createTextureLevel(ctx, tex, face, level, is_array, internalformat, width, height, 1, format, type, (void *)pixels, proxy);
}

The mgl function checks input parameters then modifies the OpenGL state and marks it dirty. I use macros for error checking parameters... because I got sick of writing.

if (expr == false) {
  set error
  return;
}

Common use of code for most OpenGL calls

Most functions are like mglTexImage2D, there a lot of common entry points which check parameters then call a function like createTextureLevel() which is used by all the TexImage calls to do the actual work.

OpenGL state translated to Metal using glDrawArrays as an example

All state changes are evaluated on direct commands, these are commands that will issue a command to the GPU for things like drawing primitives, copying data or executing compute kernels.

Looking at glDrawArrays..

glDrawArrays lands on mglDrawArrays which does parameter testing and calls the Objective C interface through a jump table in the context. This lands you in MGLRenderere.m

void mglDrawArrays(GLMContext ctx, GLenum mode, GLint first, GLsizei count)
{
    ERROR_CHECK_RETURN(check_draw_modes(mode), GL_INVALID_ENUM);

    ERROR_CHECK_RETURN(count > 1, GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(validate_vao(ctx), GL_INVALID_VALUE);

    ERROR_CHECK_RETURN(validate_program(ctx), GL_INVALID_VALUE);

    ctx->mtl_funcs.mtlDrawArrays(ctx, mode, first, count);
}

Which lands you in Objective C land, we do a C interface call to Objecitve C here

void mtlDrawArrays(GLMContext glm_ctx, GLenum mode, GLint first, GLsizei count)
{
    // Call the Objective-C method using Objective-C syntax
    [(__bridge id) glm_ctx->mtl_funcs.mtlObj mtlDrawArrays: glm_ctx mode: mode first: first count: count];
}

And now we speak Objective C

-(void) mtlDrawArrays: (GLMContext) ctx mode:(GLenum) mode first: (GLint) first count: (GLsizei) count
{
    MTLPrimitiveType primitiveType;

    RETURN_ON_FAILURE([self processGLState: true]);

    primitiveType = getMTLPrimitiveType(mode);
    assert(primitiveType != 0xFFFFFFFF);

     [_currentRenderEncoder drawPrimitives: primitiveType
                              vertexStart: first
                              vertexCount: count];
}

processGLState does all the state mapping from OpenGL to Metal

On OpenGL drawing calls the OpenGL state is processed for any dirty state in processGLState, you have to do this before each draw command to ensure changed state is captured into Metal.

State is transferred from OpenGL to Metal state using a Metal command queue with a MTLRenderCommandEncoder. Occasionally a new MTLRenderCommandEncoder will need to be built if the state changes need to modify the MTLRenderPipelineState so neRenderEncoder is called to create a new encoder with the current OpenGL state.

Most of the work is done in MGLRenderer.m, at first it can look like a giant piece of code. But it's simple once you figure out the mapping process.

binding buffers and textures from shader layouts

You have to bind all the buffers and textures to Metal, there are mapping operations you need to do to transfer OpenGL buffers / textures to Metal. Since all of this is driven by the GLSL shader in 4.5 which requires you to map your bindings and locations

An example vertex shader defines a vertex buffer object at location 0 and a uniform buffer at binding 0. These are not the same location, but relative to the type.

const char* vertex_shader =
GLSL(450 core,
     layout(location = 0) in vec3 position;

     layout(binding = 0) uniform matrices
     {
         mat4 rotMatrix;
     };

     void main() {
        gl_Position = rotMatrix * vec4(position, 1.0);
     }
);

Each binding point in OpenGL is a 2D array one for each type, like GL_ARRAY_BUFFER

glBindBuffer(GL_ARRAY_BUFFER, vbo);

Indexes an array like

buffers[GL_ARRAY_BUFFER].buffer = vbo

So internal to processGLState the vertex buffer array is taken apart, buffers and attributes mapped then we walk through uniforms / textures through their binding points in the GL state and map these to Metal state.

Once you walk a glDrawArrays call through processGLState, you will get a jist of how this all works.

Grabbing the SPIRV sources and building

There is an Xcode project build most of this, but you will need to clone a bunch of external projects from GitHub.

In MGL/external there is a file

clone_external.sh

Run this and all the external repositories will be downloaded.

SPIRV-Cross SPIRV-Headers SPIRV-Tools ezxml glfw glm glslang

You will need to build the following SPIRV-Cross SPIRV-Headers SPIRV-Tools glslang glm

Each is distributed by Khronos with a CMake style build

For each of the projects above build you will need to do the following

cd mkdir build cd build cmake .. make make install

Once installed in /usr/local the Xcode project should be able to build all the required dependencies for MGL.

Where to start

Start by building test_mgl_glfw, this is a chunk of test code I used to get most of the functionality up and running.

Performance

I really don't know what the performance comaprison is, how much is in overhead or in the driver. I wrote most of this as a functional exercise knowing that once it reached some level of functional coverage I would go back and address the performance issue. But I didn't write this without thinking about performance issues as I implemented the code.

Contributing

If you want to contribute that would be great, it's all written in C.. in the same style all of the OpenGL framework from Apple was written in. If you don't like the coding style, don't change it. Just follow the same coding style and put your efforts into testing and functionality.

Future

I would like to implement OpenCL directly into this framework, its much simpler mapping from OpenCL to Metal and there is zero state to deal with so you should be able to use all the buffers / textures and other resources directly on top of a OpenGL context.

Questions?

You can reach me at [email protected] for more information, it would be great to see this used by others and developed into a full fledged project anyone can use.

Cheers

Mike

Issues
  • Building without installing

    Building without installing

    How do I build without having to install all of these things into my /usr directory, and what should I reinstall/delete from that directory with brew. I don't want to stuff up my installations of things. Thanks :)

    opened by hamarb123 21
  • Makefile usage

    Makefile usage

    This PR makes it easier to compile the lib and launch the test the from scratch using uninstalled SPIRV stuff. It uses the regular, brew-provided glfw, but this requires to request an OpenGL 4.1 context instead of 4.6 in the test program.

    opened by conversy 4
  • Can't Build

    Can't Build

    Trying to build on my Mac, M1 Max, Monterey 12.1.

    I keep getting the error

    MGL/include/glm_context.h:152:5: error: unknown type name 'uint'; did you mean 'int'?
    
    

    When using xcodebuild, it succeeds, but I'm not sure it should.

    error: unable to spawn process '/usr/bin/make' (No such file or directory) (in target 'SPIRV-Headers' from project 'MGL')

    opened by lbibass 4
  • Unable to run test_mgl_glfw

    Unable to run test_mgl_glfw

    Hi, I'm not able to run the mgl test on my machine, M1 Max macOS 12.2

    I get this error from Xcode which I don't really know how to debug,

    Xcode Error
    Details
    
    Could not launch “test_mgl_glfw”
    Domain: IDEDebugSessionErrorDomain
    Code: 3
    Failure Reason: LLDB provided no error string.
    User Info: {
        DVTErrorCreationDateKey = "2022-02-06 07:55:44 +0000";
        DVTRadarComponentKey = 855031;
        IDERunOperationFailingWorker = DBGLLDBLauncher;
        RawUnderlyingErrorMessage = "LLDB provided no error string.";
    }
    --
    
    Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : {
        "device_model" = "MacBookPro18,2";
        "device_osBuild" = "12.2 (21D49)";
        "device_platform" = "com.apple.platform.macosx";
        "launchSession_schemeCommand" = Run;
        "launchSession_state" = 1;
        "launchSession_targetArch" = arm64;
        "operation_duration_ms" = 16;
        "operation_errorCode" = 3;
        "operation_errorDomain" = IDEDebugSessionErrorDomain;
        "operation_errorWorker" = DBGLLDBLauncher;
        "operation_name" = IDERunOperationWorkerGroup;
        "param_consoleMode" = 0;
        "param_debugger_attachToExtensions" = 0;
        "param_debugger_attachToXPC" = 1;
        "param_debugger_type" = 3;
        "param_destination_isProxy" = 0;
        "param_destination_platform" = "com.apple.platform.macosx";
        "param_diag_MainThreadChecker_stopOnIssue" = 0;
        "param_diag_MallocStackLogging_enableDuringAttach" = 0;
        "param_diag_MallocStackLogging_enableForXPC" = 1;
        "param_diag_allowLocationSimulation" = 1;
        "param_diag_gpu_frameCapture_enable" = 0;
        "param_diag_gpu_shaderValidation_enable" = 0;
        "param_diag_gpu_validation_enable" = 0;
        "param_diag_memoryGraphOnResourceException" = 0;
        "param_diag_queueDebugging_enable" = 1;
        "param_diag_runtimeProfile_generate" = 0;
        "param_diag_sanitizer_asan_enable" = 0;
        "param_diag_sanitizer_tsan_enable" = 0;
        "param_diag_sanitizer_tsan_stopOnIssue" = 0;
        "param_diag_sanitizer_ubsan_stopOnIssue" = 0;
        "param_diag_showNonLocalizedStrings" = 0;
        "param_diag_viewDebugging_enabled" = 1;
        "param_diag_viewDebugging_insertDylibOnLaunch" = 1;
        "param_install_style" = 0;
        "param_launcher_UID" = 2;
        "param_launcher_allowDeviceSensorReplayData" = 0;
        "param_launcher_kind" = 0;
        "param_launcher_style" = 0;
        "param_launcher_substyle" = 0;
        "param_runnable_appExtensionHostRunMode" = 0;
        "param_runnable_productType" = "com.apple.product-type.tool";
        "param_runnable_swiftVersion" = "5.5.2";
        "param_runnable_type" = 2;
        "param_testing_launchedForTesting" = 0;
        "param_testing_suppressSimulatorApp" = 0;
        "param_testing_usingCLI" = 0;
        "sdk_canonicalName" = "macosx12.1";
        "sdk_osVersion" = "12.1";
        "sdk_variant" = macos;
    }
    --
    
    
    System Information
    
    macOS Version 12.2 (Build 21D49)
    Xcode 13.2.1 (19586) (Build 13C100)
    Timestamp: 2022-02-06T00:55:44-07:00
    

    Actually, I saw this has been brought up in #9

    When trying to build through the makefile I get a missing KHR header presumably from some dependency misconfiguration on my end but I've been fiddling with this for a while and can't quite figure it out.

    Makefile Error
    ❯ make -j test
    c++ -std=c++14 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -I/opt/homebrew/Cellar/glfw/3.3.6/include -c test_mgl_glfw/main.cpp -o build/test_mgl_glfw/main.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/buffers.c -o build/MGL/src/buffers.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/compute.c -o build/MGL/src/compute.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/draw_buffers.c -o build/MGL/src/draw_buffers.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/error.c -o build/MGL/src/error.o
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/fence.c -o build/MGL/src/fence.o
    In file included from MGL/src/compute.c:21:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/buffers.c:26:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    test_mgl_glfw/main.cpp:32:10: fatal error: 'GL/glcorearb.h' file not found
    #include <GL/glcorearb.h>
             ^~~~~~~~~~~~~~~~
    1 error generated.
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/framebuffers.c -o build/MGL/src/framebuffers.o
    make: *** [build/MGL/src/compute.o] Error 1
    make: *** Waiting for unfinished jobs....
    cc -std=gnu17 -MMD -gfull -Og -arch arm64 -I/usr/local/include/spirv/1.2 -Iexternal/SPIRV-Cross -I/opt/homebrew/opt/glslang/include/glslang/Include -I/opt/homebrew/include  -I/opt/homebrew/Cellar/spirv-tools/2022.1/include -I/opt/homebrew/Cellar/glm/0.9.9.8/include -IMGL/include -IMGL/SPIRV/SPIRV-Cross -DENABLE_OPT=0 -DSPIRV_CROSS_C_API_MSL=1 -DSPIRV_CROSS_C_API_GLSL=1 -DSPIRV_CROSS_C_API_CPP=1 -DSPIRV_CROSS_C_API_REFLECT=1 -c MGL/src/get.c -o build/MGL/src/get.o
    1 error generated.
    In file included from MGL/src/draw_buffers.c:25:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    make: *** [build/MGL/src/buffers.o] Error 1
    In file included from MGL/src/error.c:25:
    In file included from MGL/include/error.h:25:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/fence.c:23:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    1 error generated.
    make: *** [build/MGL/src/draw_buffers.o] Error 1
    1 error generated.
    1 error generated.
    make: *** [build/MGL/src/error.o] Error 1
    make: *** [build/MGL/src/fence.o] Error 1
    In file included from MGL/src/get.c:21:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    In file included from MGL/src/framebuffers.c:24:
    In file included from MGL/include/glm_context.h:28:
    In file included from MGL/include/glm_dispatch.h:13:
    MGL/include/glcorearb.h:65:10: fatal error: 'KHR/khrplatform.h' file not found
    #include <KHR/khrplatform.h>
             ^~~~~~~~~~~~~~~~~~~
    1 error generated.
    make: *** [build/MGL/src/framebuffers.o] Error 1
    1 error generated.
    make: *** [build/MGL/src/get.o] Error 1
    1 error generated.
    make: *** [build/test_mgl_glfw/main.o] Error 1
    
    opened by cadenkriese 3
  • Issue when running make install

    Issue when running make install

    When trying to run make install, I get this error: CMake Error at cmake_install.cmake:41 (file): file INSTALL cannot copy file "/Users/*****/MGL/external/SPIRV-Cross/build/libspirv-cross-core.a" to "/usr/local/lib/libspirv-cross-core.a": Permission denied.

    opened by awsomenes 3
  • Using an Organization vs a User account

    Using an Organization vs a User account

    It seems like you created a GitHub user to hold this repository (and possibly related ones in the future).

    From https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts:

    Tip: Personal accounts are intended for humans, but you can create accounts to automate activity on GitHub. This type of account is called a machine user. For example, you can create a machine user account to automate continuous integration (CI) workflows.

    GitHub has a feature designed to group repositories together without being attached to a single user: an Organization. GitHub recommends as best practice to instead have a GitHub user for your person, and then group related community repositories under an organization that you manage. From https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations:

    Your team can collaborate on GitHub by using an organization account. Each person that uses GitHub signs into a user account. Multiple user accounts can collaborate on shared projects by joining the same organization account, which owns the repositories. A subset of these user accounts can be given the role of organization owner, which allows those people to granularly manage access to the organization's resources using sophisticated security and administrative features.

    It is possible to convert an existing GitHub user into an organization here: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/converting-a-user-into-an-organization I recommend doing this with @openglonmetal and then creating or using existing personal accounts for individuals contributing to the project.

    opened by magneticflux- 2
  • add -Wall and -fsanitize=address to compile options

    add -Wall and -fsanitize=address to compile options

    This will raise some warnings to be fixed. Hopefully it will also fix bugs in case some parameters were forgotten during the gl2mtl translation process

    opened by conversy 1
  • Question regarding design

    Question regarding design

    I have to say this project is very interesting as someone developing a game engine and trying to figure out if macOS support is worth it due to the lack of SSBOs in the native macOS GL4.1 driver which my engine makes use of for several effects. However the design has sort of led me to a question I'd like to ask. What was the reason for building an OpenGL state tracker from scratch as opposed to writing a Gallium3D driver for mesa, which has had a production ready OpenGL implementation for quite some time? I know the mesa team have talked here and there about such a driver although I don't think anyone's put the time into working on one.

    opened by asdfjkluiop 1
  • fix Makefile

    fix Makefile

    I was not able to compile anymore, hence this fix. However, I get a warning because spirv_cfg.hpp includes the non-1.2 version of spirv.h... Is there such thing as a spirv_cfg.hpp for spirv 1.2?

    opened by conversy 1
  • Hidpi

    Hidpi

    This will prevent autoscaling and blurring, to get a crisp image on retina display. This also requires to call glViewport with twice the width and height on retina displays. I haven't updated the test code to do so, which means that the results will appear with half their size.

    opened by conversy 0
  • add -Wall and -fsanitize=address to compile options

    add -Wall and -fsanitize=address to compile options

    "-Wall" will raise some warnings to be fixed. Hopefully it will also help fix bugs in case some parameters were forgotten during the gl2mtl translation process.

    -fsanitize=address will detect memory violation error. This should be put in a "debug" set of options only, I'll do it in another commit.

    opened by conversy 0
  • viewport

    viewport

    In the course of fixing hidpi support, I managed to get the highest possible rendering quality (i.e. no scaling, no filtering). However, I recently found that it's only working with some examples (e.g. test_2D_textures), and not with others (e.g. test_2D_array_textures): the rendering is limited to the upper-left corner of the window.

    I could not fix it as of yet. I changed the view port with glViewPort(w2, h2) for hidpi, but it's only working with test_2D_textures), I do not know why it does not with other examples...

    opened by conversy 0
  • async glReadPixels

    async glReadPixels

    Hi,

    I created a glReadPixelsbranch in which I added some code to implement async glReadPixels using PBOs. First, I fixed regular, sync'ed glReadPixels to actually get data. Then I implemented an async version when using PBO, by leveraging on MTLBlitCommandEncoder. It's working (or so it seems).

    However, to use MTLBlitCommandEncoder, I used an MTLBuffer that I attached to the Buffer mtl data:

        Buffer *ptr;
        ptr = glm_ctx->state.buffers[_PIXEL_PACK_BUFFER];
        ...
        id<MTLBuffer> buffer;
        ...
        buffer = [_device newBufferWithLength:bytesPerImage options: options];
        ptr->data.mtl_data = CFBridgingRetain(buffer);
        ...
        [blitCommandEncoder
            copyFromTexture:texture sourceSlice:0 sourceLevel:0
            sourceOrigin:MTLOriginMake(region.origin.x, region.origin.y, 0) sourceSize:MTLSizeMake(region.size.width, region.size.height, 1)
            toBuffer:buffer destinationOffset:0 destinationBytesPerRow:bytesPerRow destinationBytesPerImage:bytesPerImage];
    

    Still, I know that ptr->data.mtl_data might contain a buffer allocated with vm_allocate, something completely different...

    @guymadison could you please have a look at it, and maybe come with a better solution?

    opened by conversy 2
  • ./build_external fails

    ./build_external fails

    M1 Macbook Air, macOS 12.3

    Xcode doesn't like a few bits and bobs, so I'm working through it. The biggest roadblock right now is I have NO idea where MGLContext.h should be from. I've searched all over the internet and have no leads. It should be worth mentioning I'm not familiar with C, C++, and OBJC, although I am familiar with some other C-like languages. Any hints or help would be greatly appreciated!

    In file included from /Users/alex/Projects/MGL/external/glfw/src/context.c:30:
    In file included from /Users/alex/Projects/MGL/external/glfw/src/internal.h:331:
    In file included from /Users/alex/Projects/MGL/external/glfw/src/platform.h:42:
    /Users/alex/Projects/MGL/external/glfw/src/cocoa_platform.h:32:10: fatal error: 'MGLContext.h' file not found
    #include <MGLContext.h>
             ^~~~~~~~~~~~~~
    1 error generated.
    make[3]: *** [src/CMakeFiles/glfw.dir/context.c.o] Error 1
    make[2]: *** [src/CMakeFiles/glfw.dir/all] Error 2
    make[1]: *** [src/CMakeFiles/glfw.dir/rule] Error 2
    make: *** [glfw] Error 2
    
    opened by WoMspace 0
  • Not an issue: wiki to help starters

    Not an issue: wiki to help starters

    Hi,

    I set up a wiki page on my fork to list the things I had to do in order to make my app launches with MGL. Note: my app is not working yet with MGL (I think I'm closed to making it work), but it might be valuable for anyone who wants to try.

    https://github.com/conversy/MGL/wiki

    I do not know how to PR this wiki on the main repository...

    opened by conversy 1
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.4k Jun 19, 2022
OpenGL 4.6 on Metal

MGL OpenGL 4.6 on Metal This is a start for porting OpenGL 4.6 on top of Metal, most of it is functional and has been tested. The tests are functional

null 316 Jun 26, 2022
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input

GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf

GLFW 9.2k Jun 24, 2022
A legacy OpenGL simulator for OpenGL 4.4, written in C++.

the-ancient-tri A legacy OpenGL simulator for OpenGL 4.4, written in C++. Why? My Uni forces us to use legacy OpenGL (eww!), and I didn't want to lear

Mohammad Issawi 4 Feb 10, 2022
🎮 C Bindings/Wrappers for Apple's METAL framework

Apple's Metal for C C Wrapper for Apple's METAL framework. This library is C bindings of Metal API (MetalGL). Since OpenGL is deprecated, this library

Recep Aslantas 104 Jun 24, 2022
A header-only C-like shading language compiler that writes Metal, HLSL, GLSL

GPUC A generic shading language compiler that writes metal, HLSL, and GLSL GPUC is a work in progress, not ready for prime time. The primary motivatio

Garett Bass 57 Jun 22, 2022
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.

This project is not actively maintained. NanoVG NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled afte

Mikko Mononen 4.4k Jun 30, 2022
Epoxy is a library for handling OpenGL function pointer management for you

Epoxy is a library for handling OpenGL function pointer management for you. It hides the complexity of dlopen(), dlsym(), glXGetProcAddress(), eglGetP

Eric Anholt 545 Jun 27, 2022
3D engine from scratch (without OpenGL or any other 3D graphics library)

Simple 3d engine based on SFML library. I tried to make this engine powerful and easy to understand.

Vectozavr 21 Jun 4, 2022
RGL - 3D visualization device system for R using OpenGL

RGL - 3D visualization device system for R using OpenGL INTRODUCTION The RGL package is a visualization device system for R, using OpenGL or WebGL as

null 58 Jun 20, 2022
OpenGL Demo: Simulating Ocean Waves with FFT

OceanFFT Realistic ocean wave simulation, primarily based on J. Tessendorf's paper, using OpenGL compute shaders. Checkout the demo video here. In the

Achal Pandey 59 Jun 9, 2022
OBS Linux Vulkan/OpenGL game capture

OBS Linux Vulkan/OpenGL game capture OBS plugin for Vulkan/OpenGL game capture on Linux. Requires OBS with EGL support (currently unreleased, you need

David Rosca 181 Jul 2, 2022
NodeEditor basiced on Qt and OpenGL/CV

Vapour 基于Qt的轻量级的节点式几何建模工具与shader材质生成工具 可能加入图像处理(合成)的功能 日志: 2021-5-17: 完成背景绘制,右键菜单,节点连线,节点删除,初步拓扑排序 (细节)连线位于节点层级之下,使用lambda处理右键菜单slot,节点创建生成在鼠标位置处 2021

Cuimi 13 Apr 14, 2022
C Wavefront OBJ loader for OpenGL

OBJ GL Loader v2 Quite fast .OBJ loader written in C How to use it Put objgl2.c and objgl2.h files in Your project and include them. To put it simply:

null 6 Dec 17, 2021
Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui

Orbit Engine Orbit is a multiplatform-focus graphical engine build on top of OpenGl, ImGui and more... The development of the engine is documented via

Madsycode 11 Jul 3, 2021
Axel Gneiting 1.3k Jun 24, 2022
A 2d Graphing Calculator using OpenGL

glGraph A 2d Graphing Calculator using Modern OpenGL Demo glGraph.mp4 Information This has only been tested on Fedora 34, it should work on other OS's

Nathan Medros 16 Apr 19, 2022
Tetris written with C++ and OpenGL.

Tetrec This is yet another Tetris game, which is in 3D, written using C++ and OpenGL 2.1, aiming at being lightweight towards not-so-beefy computers (

Lê Duy Quang 14 Jan 17, 2022
OpenGL made easy.

SmartGL OpenGL made easy. Demo video: https://youtu.be/zDuNxg4LJ18 (sorry for low-quality recording) For an example of how my engine is used, please r

null 16 Jun 21, 2022