- This topic has 18 replies, 2 voices, and was last updated 8 years, 6 months ago by pemgl.
-
AuthorPosts
-
2015-09-26 at 8:33 pm #712
I’m attempting to integrate Metal into my simple cross-platform code base that uses (C++, cmake, SDL2, OpenGL ES 2). It’s a simple test case that just clears the screen to red and draws one triangle using glDrawArrays and one cube using glDrawElements. My test case works for (Windows, Linux, iOS, Android, Emscripten) and even (for OSX when I use VAOs with desktop OpenGL). I’m attempting to get my test case to work with MetalGL so I can use core GLES2 (no VAOs) for all platforms (instead of having to special case OSX for desktop OpenGL).
In my CMakeLists.txt file, I commented out OpenGL.framework, and added the relevant libraries and include folders:
#LINK_LIBRARIES(/System/Library/Frameworks/OpenGL.framework)
INCLUDE_DIRECTORIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGL/RedirectHeaders/include”)
LINK_LIBRARIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGL/OSX/MetalGL.framework”)
LINK_LIBRARIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGLShaderConverter/OSX/MetalGLShaderConverter.framework”)I also changed my C++ code to point to GLES2 instead of desktop OpenGL:
//#include <OpenGL/gl3.h>
#include <OpenGLES/ES2/gl.h>But I got this error:
[ 20%] Building CXX object CMakeFiles/pemDemos.dir/main.cpp.o
In file included from pemDemos/pemDemos/main.cpp:40:
In file included from pemDemos/pemDemos/pemdemos.h:9:
In file included from pemDemos/pemDemos/../../MetalGL-0.10.0/MetalGL/RedirectHeaders/include/OpenGLES/ES2/gl.h:24:
In file included from pemDemos/pemDemos/../../MetalGL-0.10.0/MetalGL/RedirectHeaders/include/OpenGLES/ES2/../../../orig/OpenGLES/ES2/gl.h:53:
pemDemos/pemDemos/../../MetalGL-0.10.0/MetalGL/RedirectHeaders/include/OpenGLES/gltypes.h:23:9: fatal error: ‘../../../orig/OpenGLES/gltypes.h’ file not found
#import “../../../orig/OpenGLES/gltypes.h”
^
So I modified “MetalGL-0.10.0/MetalGL/RedirectHeaders/include/OpenGLES/gltypes.h”://#import “../../../orig/OpenGLES/gltypes.h”
#include “../../orig/OpenGLES/gltypes.h”With that change it compiles but when it tries to link I get along list of undefined symbols such as:
Undefined symbols for architecture x86_64:
“_MTLCreateSystemDefaultDevice”, referenced from:
_MGLIsMetalAvailable in MetalGL(MetalGL-x86_64-master.o)
_MGLMakeMetalActive in MetalGL(MetalGL-x86_64-master.o)
_MGLGetEnvParameter in MetalGL(MetalGL-x86_64-master.o)
_mglGetMTLDevice in MetalGL(MetalGL-x86_64-master.o)
… etc …
“_glActiveShaderProgramEXT”, referenced from:
_mglActiveShaderProgramEXT in MetalGL(MetalGL-x86_64-master.o)
“_glActiveTexture”, referenced from:
_mglActiveTexture in MetalGL(MetalGL-x86_64-master.o)
“_glAttachShader”, referenced from:
_mglAttachShader in MetalGL(MetalGL-x86_64-master.o)
… etc … it’s a very long list …I verified the specified path to MetalGL.framework is correct. I even verified it has the symbols eg:
$ nm -gU MetalGL-0.10.0/MetalGL/OSX/MetalGL.framework/MetalGL | grep glActive
0000000000020400 T _mglActiveShaderProgramEXT
0000000000022430 T _mglActiveTextureSo I wonder what I could be doing wrong?
2015-09-26 at 9:08 pm #713I made some progress by copying additional frameworks from the MetalGL XCode sample project DrawLoadDemo:
INCLUDE_DIRECTORIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGL/RedirectHeaders/include”)
LINK_LIBRARIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGL/OSX/MetalGL.framework”)
#LINK_LIBRARIES(/Users/foo/Pem_Code/fooproj/MetalGL-0.10.0/MetalGL/OSX/MetalGL.framework)
LINK_LIBRARIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/MetalGLShaderConverter/OSX/MetalGLShaderConverter.framework”)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Metal.framework)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Foundation.framework)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreFoundation.framework)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreGraphics.framework)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/AppKit.framework)
LINK_LIBRARIES(/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/QuartzCore.framework)I’m getting less link errors, but I still have unresolved symbols such as:
Undefined symbols for architecture x86_64:
“_OBJC_CLASS_$_CAEAGLLayer”, referenced from:
objc-class-ref in MetalGL(MetalGL-x86_64-master.o)
“_OBJC_CLASS_$_EAGLContext”, referenced from:
objc-class-ref in MetalGL(MetalGL-x86_64-master.o)
“_glActiveShaderProgramEXT”, referenced from:
_mglActiveShaderProgramEXT in MetalGL(MetalGL-x86_64-master.o)
“_glBeginQueryEXT”, referenced from:
_mglBeginQueryEXT in MetalGL(MetalGL-x86_64-master.o)
… etc2015-09-26 at 9:24 pm #714Another data point is that I tried adding -ObjC:
add_definitions(“-std=c++11 -ObjC”)
However this causes an error:
error: invalid argument ‘-std=c++11’ not allowed with ‘C/ObjC’
Doing just -ObjC without -std=c++11 also causes an error:
main.cpp:33:10: fatal error: ‘iostream’ file not found
#include <iostream>2015-09-26 at 9:41 pm #715I think the problem is that I’m not linking to an OpenGL Extensions library because OpenGL.framework only has core OpenGL? I’m getting link errors like the following:
Undefined symbols for architecture x86_64:
… etc
“_glActiveShaderProgramEXT”, referenced from:
_mglActiveShaderProgramEXT in MetalGL(MetalGL-x86_64-master.o)
“_glBeginQueryEXT”, referenced from:
_mglBeginQueryEXT in MetalGL(MetalGL-x86_64-master.o)
“_glBindProgramPipelineEXT”, referenced from:
_mglBindProgramPipelineEXT in MetalGL(MetalGL-x86_64-master.o)
“_glBindVertexArrayOES”, referenced from:
_mglBindVertexArrayOES in MetalGL(MetalGL-x86_64-master.o)
… etc2015-09-27 at 2:18 pm #718Thanks for pointing out the issue in
gltypes.h
with#include “../../orig/OpenGLES/gltypes.h”
We’ll fix that in a future release.
With regards to the remaining header and linking issues, be sure to review the installation section of the
README-UserGuide.md
file (also available online). In particular, as described in that document, make sure the Metal framework is linked to your app, and the four files:gl.m
,glext.m
,egl.m
, andEAGL.m
from theMetalGL/OSX
folder have been added to your app.…Bill
2015-09-27 at 3:20 pm #721Oops, I now see that step 6 of the “install” section says to add (
gl.m
,glext.m
,egl.m
, andEAGL.m
from theMetalGL/OSX
folder). So I added them, but then I got a different error:[ 16%] Building C object CMakeFiles/pemDemos.dir/Users/pem/Pem_Code/grfxdemossdl2015/MetalGL-0.10.0/MetalGL/OSX/gl.m.o
error: invalid argument ‘-std=c++11’ not allowed with ‘C/ObjC’
make[2]: *** [CMakeFiles/pemDemos.dir/Users/foo/Pem_Code/fooproj/MetalGL-0.10.0/MetalGL/OSX/gl.m.o] Error 1So I removed -std=c++11 from my CMakeLists.txt:
#add_definitions(“-std=c++11 -stdlib=libc++”)
add_definitions(“-stdlib=libc++”)I notice these four files are .m instead of .h or .cpp, but my project is cross-platform so I am not building with -ObjC because building with -ObjC gives errors such as:
pemDemos/pemDemos/main.cpp:33:10: fatal error: ‘iostream’ file not found
#include <iostream>If I comment out that line, I still get compile errors from GLM ( http://glm.g-truc.net/ ) such as:
glm/glm/detail/_fixes.hpp:33:10: fatal error: ‘cmath’ file not found
#include <cmath>I don’t think there is any reason why MetalGL needs to require my project to use -ObjC? My (C++, SDL2, CMake, desktop OpenGL on OSX, GLES2 on iOS & Android & Windows ANGLE & Emscripten) project builds and runs as expected without MetalGL and without -ObjC. So requiring -ObjC makes MetalGL incompatible with my project, with GLM, and probably a lot of other cross-platform projects that use <iostream> or <cmath> etc.
So I’m not using -ObjC, and I now get this error:
MetalGL-0.10.0/MetalGL/OSX/egl.m:42:10: fatal error: ‘EGL/egl.h’ file not found
#include <EGL/egl.h>RedirectHeaders/include only has OpenGLES/EAGL.h, I don’t see EGL/egl.h. According to this link ( http://www.g-truc.net/post-0457.html ), OSX uses EAGL instead of EGL, so I’m confused why egl.m includes EGL/egl.h.
thank you
2015-09-28 at 10:19 am #724The
egl.h
file is indeed missing fromRedirectHeaders/include
. This is an oversight that we’ll fix in a future release. It works for the SampleProjects, because the EGL headers are included inSampleProjects/Common/API/EGL
. For your immediate purposes, you can add that folder to your project headers.The three files
gl.m
,glext.m
, andegl.m
really do not need to be*.m
files, and, with some minor adjustments, could be changed to*.c
files instead. Again, we’ll make that change in a future release. However, theEAGL.m
file does contain Objective-C classes, so must remain as an Objective-C file. In OpenGL ES on Apple platforms, theEAGL
classes play a key role in associating the primary renderbuffer with the underlying platform graphics.Some further use-case info might help get to the bottom of this. In your C++ only code, how would you expect to associate the OpenGL ES renderbuffer with the platform graphics on OS X, without using Objective-C? How does your code handle this under desktop OpenGL on OS X?
…Bill
2015-09-28 at 9:38 pm #725@Bill I am using (C++, SDL2, CMake) for all platforms including OSX. I’m using OpenGL ES 2 on all platforms, except on OSX I am using desktop OpenGL (that is, until I get MetalGL working). I’m using pure C++ (not Objective C) on all platforms. I can send more if needed, but here are some snippets of relevant code:
// includes
#include “SDL_platform.h”
#include “SDL_test_common.h”
#include <OpenGL/gl3.h>
#define __gl_h_ // block SDL from including OpenGL/gl.h
#include <SDL.h>// globals
SDL_Window *g_Window = nullptr;
SDL_Renderer *g_Renderer = nullptr;
SDL_GLContext g_Context = NULL;// setup
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
SDL_CreateWindowAndRenderer(g_Width, g_Height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE, &g_Window, &g_Renderer);
g_Context = SDL_GL_CreateContext(g_Window);
glViewport(0, 0, g_Width, g_Height);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);// render loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
g_Entity->render(g_CameraB.matrix());
SDL_GL_SwapWindow(g_Window);2015-09-28 at 9:43 pm #726I’m running CMake inside Qt Creator. Qt Creator lists the cmake Generator as “Unix Generator (Desktop Qt 5.5.0 clang 64bit). My simple cross-platform demo works fine using desktop OpenGL on OSX (and GLES2 for other platforms).
2015-09-28 at 9:51 pm #727Per your suggestion I added the following line to my CMakeLists.txt file:
# for EGL/egl.h, won’t be needed in future versions of MetalGL
INCLUDE_DIRECTORIES(“${CMAKE_CURRENT_SOURCE_DIR}/../../MetalGL-0.10.0/SampleProjects/Common/API”)I also installed the XCode 7.1 update, which mentions OS X 11.11 El Captain. Although “About This Mac” still says OS X Yosemite 10.10.5.
Good news – I’m now able to compile and run without link errors.
I now get the following message from MetalGL:
[mgl-info] OpenGL functionality using Metal cannot be provided because Metal is not supported on this device. OpenGL functionality provided by native OpenGL framework.
I’ll see if I can get any farther later tonight or tomorrow… I just wanted to share a quick update on my progress
thank you and best regards
2015-09-28 at 9:56 pm #728Probably the next thing I will try is to install OS X 10.11 (El Capitan). Apparently it is “coming September 30” which is in two days, so I can either install the preview, or just wait two days… best regards
2015-09-29 at 2:35 pm #729Yes…installing El Capitan is crucial, since you won’t have Metal available until you do. That’s why you’re seeing the log message you reported:
[mgl-info] OpenGL functionality using Metal cannot be provided because Metal is not supported on this device. OpenGL functionality provided by native OpenGL framework.
Metal is not available on Yosemite, hence the log message.
…Bill
2015-09-30 at 6:48 pm #732I installed OSX 10.11 and verified DrawLoadDemo sample works. Here’s where I am now (on my CMake + SDL2 project):
void CheckReturn(int retVal, const char* sMsg) { if (retVal != 0) SDL_Log("ERROR: %s; %s", sMsg, SDL_GetError()); } int main(int argc, char *argv[]) { assert(SDL_Init(SDL_INIT_VIDEO) == 0); CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES), "A"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2), "B"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0), "C"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1), "D"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16), "E"); CheckReturn(SDL_CreateWindowAndRenderer(g_Width, g_Height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE, &g_Window, &g_Renderer), "SDL_CreateWindowAndRenderer");
The error I get is:
SDL_CreateWindowAndRenderer; Couldn’t find matching render driver
The above code works on all other platforms I’ve tried using GLES2 – Windows desktop (ANGLE), iOS, Android, Linux, Emscripten. My application also works on OSX with desktop OpenGL (not MetalGL) if I make some minor changes.
2015-10-01 at 10:29 am #733It looks like you’re using a windowing library that we are not familiar with. Have a look at the
DrawLoadDemo
to understand how theDemoView
class is constructed. It’s based onMGLGLKView
, which behaves like Apple’sGLKView
class, but handles creating the framebuffers for rendering to Metal.If you can’t use the
MGLGLKView
class, can you post the code that creates yourNSView
, its underlying layer, and how the framebuffer and renderbuffer storage is allocated for that view?BTW…in future posts, can you surround your code snippets with
<pre> code snippet </pre>
so that it retains its formatting and is more readable, please?…Bill
2015-10-01 at 8:46 pm #734SDL2 (Simple DirectMedia Layer) and similar cross-platform libraries (eg GLFW, GLUT, SFML, Marmalade, a game engine like Unity, etc) are commonly used to abstract things like creating a window and an OpenGL context. This enables developers to write more cross-platform code (and less platform-specific code such as NSView).
MetalGL also lets developers write more cross-platform code (and less platform-specific code such as Metal). If a developer wants to write platform-specific code they can use (NSView + Metal + XCode). If they want to write cross-platform code they can instead use (SDL2 + MetalGL + CMake) for example. I suspect a lot of potential MetalGL users will also use cross-platform libraries (such as SDL2) for creating a window and an OpenGL context.
Since MetalGL is using MGLGLKView, then this must mean it is not expected to work with SDL2 because obviously SDL2 does not implement support for MGLGLKView. To me this seems broken… If MetalGL is able to intercept GLES calls such that developers can reuse GLES code written for other platforms… Then why does MetalGL not do the same sort of thing for NSView? I am surprised that MetalGL exists to enable cross-platform GLES code, but it requires one to use MGLGLKView. Or am I confused?
As for SDL2’s source code… It’s an open source project, see libsdl.org > download source code.
I took a quick look (ie grep) and “src/render/SDL_render.c” appears to have the implementation for SDL_CreateWindowAndRenderer():
int SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, SDL_Window **window, SDL_Renderer **renderer) { *window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, window_flags); if (!*window) { *renderer = NULL; return -1; } *renderer = SDL_CreateRenderer(*window, -1, 0); if (!*renderer) { return -1; } return 0; }
I also saw NSView used in “SDL2-2.0.3\src\video\cocoa\SDL_cocoawindow.m”
Beyond that, grep only got me so far, so to better understand how SDL2 works under-the-hood, I may need to build a debug version of SDL2 and step into it…
2015-10-02 at 12:38 pm #735You can’t mix Metal and OpenGL in a single app. That means that once you decide to use MetalGL to run your OpenGL ES code in Metal, instead of running the native OpenGL ES engine, you have to ensure that all of your OpenGL ES code is using MetalGL, including any code from any libraries you use. In other words, all of the libraries that use OpenGL ES have to be compiled so they redirect their OpenGL calls to MetalGL.
This might also be a challenge if a library detects what OS it is running on and tries to use desktop OpenGL on OS X instead of OpenGL ES. The way that GL objects like the color renderbuffer are attached to a view is different between OpenGL ES and desktop OpenGL.
For some more background, have a look at the way that the
EAGLView
andES2Renderer
classes are implemented in Apple’s GLEssentials sample code. You can download this sample and run it with MetalGL under iOS.The way the
EAGLView
class creates an OpenGL ES-compatible view is the way that it needs to be done, both on iOS and OS X, because this is the way it’s done with OpenGL ES, and is what MetalGL overrides, both on iOS and OS X. This is also essentially what theMGLGLKView
class does, both on iOS and OS X, but through aGLKView
API.In the future, we can explore options for overriding the desktop OpenGL GL context-creation functionality, in order to simplify running an OpenGL ES app on OS X, but for now, it’s important that the GL context and views be constructed the OpenGL ES way, even on OS X.
…Bill
2015-10-18 at 3:07 am #736If you download the SDL2 source code and grep for GLKView, you get no hits. If you grep for NSView, you get the following:
./src/video/cocoa/SDL_cocoakeyboard.m:60:@interface SDLTranslatorResponder : NSView <NSTextInput>
./src/video/cocoa/SDL_cocoakeyboard.m:556: NSView *parentView = [[NSApp keyWindow] contentView];
./src/video/cocoa/SDL_cocoaopengl.m:40: * AppKite/NSView.h in 10.8 SDK. */
./src/video/cocoa/SDL_cocoaopengl.m:41:@interface NSView (Backing)
./src/video/cocoa/SDL_cocoaopengl.m:313: NSView *contentView = [windata->nswindow contentView];
./src/video/cocoa/SDL_cocoashape.m:60: NSView* view;
./src/video/cocoa/SDL_cocoawindow.m:39:@interface NSView (NSOpenGLSurfaceResolution)
./src/video/cocoa/SDL_cocoawindow.m:68: NSView *view = [window contentView];
./src/video/cocoa/SDL_cocoawindow.m:152: NSView *view = [window contentView];
./src/video/cocoa/SDL_cocoawindow.m:574:@interface SDLView : NSView
./src/video/cocoa/SDL_cocoawindow.m:748: NSView *contentView = [[SDLView alloc] initWithFrame:rect];Here is the relevant open source SDL2 code online:
https://www.libsdl.org/tmp/SDL/src/video/cocoa/SDL_cocoaopengl.m
https://www.libsdl.org/tmp/SDL/src/video/cocoa/SDL_cocoawindow.mI wonder if there’s an easy way to tell SDL2 (eg with a #define?) to use the iOS version instead of the OSX version…
2015-10-18 at 3:10 am #737Oh here’s something interesting from SDL_cocoaopengl.m:
if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { SDL_SetError ("OpenGL ES is not supported on this platform"); return NULL; } if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) { SDL_SetError ("OpenGL Core Profile is not supported on this platform version"); return NULL; }
I may look more later… for now I’d better log off (it’s 2:10am in my time zone)
2015-10-18 at 3:13 am #738Oops actually I was already doing that and it still doesn’t work:
CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES), "A"); // this line CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2), "B"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0), "C"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1), "D"); CheckReturn(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16), "E"); CheckReturn(SDL_CreateWindowAndRenderer(g_Width, g_Height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE, &g_Window, &g_Renderer), "SDL_CreateWindowAndRenderer");
-
AuthorPosts
- The forum ‘MoltenGL Support’ is closed to new topics and replies.