这是我对stackOverflow的第一篇文章,所以我希望你对我很好:)。在使用XCode v4.4,MonoDevelop v3.0.5以及MonoMac(v2.10.9)git hub的最新开发分支设置我的系统后,在运行包含OpenGL的MonoMac示例时,我不断获得这些异常,其他任何示例都按预期工作。以下是异常的堆栈跟踪: -
2012-08-27 15:23:17.117 NeHeLesson1[229:1207] invalid pixel format
2012-08-27 15:23:17.119 NeHeLesson1[229:1207] invalid context
Unhandled Exception: System.Exception: Invalid parameters to context creation
at MonoMac.OpenGL.CGLContext..ctor (intptr) <0x0006f>
at MonoMac.AppKit.NSOpenGLContext.get_CGLContext () <0x00053>
at NeHeLesson1.MyOpenGLView.SetupDisplayLink () <0x00089>
at NeHeLesson1.MyOpenGLView..ctor (System.Drawing.RectangleF,MonoMac.AppKit.NSOpenGLContext) <0x00283>
at NeHeLesson1.MyOpenGLView..ctor (System.Drawing.RectangleF) <0x00033>
at (wrapper dynamic-method) object.ee521f2b-bbc7-4e1d-ad69-1022ce59ef12 (intptr,MonoMac.ObjCRuntime.Selector,System.Drawing.RectangleF) <0x00077>
at (wrapper native-to-managed) object.ee521f2b-bbc7-4e1d-ad69-1022ce59ef12 (intptr,MonoMac.ObjCRuntime.Selector,System.Drawing.RectangleF) <0x0008f>
at (wrapper managed-to-native) MonoMac.ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper (intptr,intptr) <0x00003>
at MonoMac.AppKit.NSWindowController.get_Window () <0x0007b>
at NeHeLesson1.MainWindowController.get_Window () <0x00013>
at NeHeLesson1.AppDelegate.FinishedLaunching (MonoMac.Foundation.NSObject) <0x0003b>
at (wrapper dynamic-method) object.[NeHeLesson1.AppDelegate.Void FinishedLaunching(MonoMac.Foundation.NSObject)] (MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject) <0x00033>
at (wrapper native-to-managed) object.[NeHeLesson1.AppDelegate.Void FinishedLaunching(MonoMac.Foundation.NSObject)] (MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject) <0x000fb>
at (wrapper managed-to-native) MonoMac.AppKit.NSApplication.NSApplicationMain (int,string[]) <0x00003>
at MonoMac.AppKit.NSApplication.Main (string[]) <0x00017>
at NeHeLesson1.MainClass.Main (string[]) <0x00017>
[ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: Invalid parameters to context creation
at MonoMac.OpenGL.CGLContext..ctor (intptr) <0x0006f>
at MonoMac.AppKit.NSOpenGLContext.get_CGLContext () <0x00053>
at NeHeLesson1.MyOpenGLView.SetupDisplayLink () <0x00089>
at NeHeLesson1.MyOpenGLView..ctor (System.Drawing.RectangleF,MonoMac.AppKit.NSOpenGLContext) <0x00283>
at NeHeLesson1.MyOpenGLView..ctor (System.Drawing.RectangleF) <0x00033>
at (wrapper dynamic-method) object.ee521f2b-bbc7-4e1d-ad69-1022ce59ef12 (intptr,MonoMac.ObjCRuntime.Selector,System.Drawing.RectangleF) <0x00077>
at (wrapper native-to-managed) object.ee521f2b-bbc7-4e1d-ad69-1022ce59ef12 (intptr,MonoMac.ObjCRuntime.Selector,System.Drawing.RectangleF) <0x0008f>
at (wrapper managed-to-native) MonoMac.ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper (intptr,intptr) <0x00003>
at MonoMac.AppKit.NSWindowController.get_Window () <0x0007b>
at NeHeLesson1.MainWindowController.get_Window () <0x00013>
at NeHeLesson1.AppDelegate.FinishedLaunching (MonoMac.Foundation.NSObject) <0x0003b>
at (wrapper dynamic-method) object.[NeHeLesson1.AppDelegate.Void FinishedLaunching(MonoMac.Foundation.NSObject)] (MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject) <0x00033>
at (wrapper native-to-managed) object.[NeHeLesson1.AppDelegate.Void FinishedLaunching(MonoMac.Foundation.NSObject)] (MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject) <0x000fb>
at (wrapper managed-to-native) MonoMac.AppKit.NSApplication.NSApplicationMain (int,string[]) <0x00003>
at MonoMac.AppKit.NSApplication.Main (string[]) <0x00017>
at NeHeLesson1.MainClass.Main (string[]) <0x00017>
导致错误的代码是: -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.CoreVideo;
using MonoMac.CoreGraphics;
using MonoMac.OpenGL;
namespace NeHeLesson1
{
public partial class MyOpenGLView : MonoMac.AppKit.NSView
{
NSOpenGLContext openGLContext;
NSOpenGLPixelFormat pixelFormat;
MainWindowController controller;
CVDisplayLink displayLink;
NSObject notificationProxy;
[Export("initWithFrame:")]
public MyOpenGLView (RectangleF frame) : this(frame, null)
{
}
public MyOpenGLView (RectangleF frame, NSOpenGLContext context) : base(frame)
{
var attribs = new object [] {
NSOpenGLPixelFormatAttribute.Accelerated,
NSOpenGLPixelFormatAttribute.NoRecovery,
NSOpenGLPixelFormatAttribute.DoubleBuffer,
NSOpenGLPixelFormatAttribute.ColorSize, 24,
NSOpenGLPixelFormatAttribute.DepthSize, 16 };
pixelFormat = new NSOpenGLPixelFormat (attribs);
if (pixelFormat == null)
Console.WriteLine ("No OpenGL pixel format");
// NSOpenGLView does not handle context sharing, so we draw to a custom NSView instead
openGLContext = new NSOpenGLContext (pixelFormat, context);
openGLContext.MakeCurrentContext ();
// Synchronize buffer swaps with vertical refresh rate
openGLContext.SwapInterval = true;
// Initialize our newly created view.
InitGL ();
SetupDisplayLink();
// Look for changes in view size
// Note, -reshape will not be called automatically on size changes because NSView does not export it to override
notificationProxy = NSNotificationCenter.DefaultCenter.AddObserver (NSView.NSViewGlobalFrameDidChangeNotification, HandleReshape);
}
public override void DrawRect (RectangleF dirtyRect)
{
// Ignore if the display link is still running
if (!displayLink.IsRunning && controller != null)
DrawView ();
}
public override bool AcceptsFirstResponder ()
{
// We want this view to be able to receive key events
return true;
}
public override void LockFocus ()
{
base.LockFocus ();
if (openGLContext.View != this)
openGLContext.View = this;
}
public override void KeyDown (NSEvent theEvent)
{
controller.KeyDown (theEvent);
}
public override void MouseDown (NSEvent theEvent)
{
controller.MouseDown (theEvent);
}
// All Setup For OpenGL Goes Here
public bool InitGL ()
{
// Enables Smooth Shading
GL.ShadeModel (ShadingModel.Smooth);
// Set background color to black
GL.ClearColor (Color.Black);
// Setup Depth Testing
// Depth Buffer setup
GL.ClearDepth (1.0);
// Enables Depth testing
GL.Enable (EnableCap.DepthTest);
// The type of depth testing to do
GL.DepthFunc (DepthFunction.Lequal);
// Really Nice Perspective Calculations
GL.Hint (HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
return true;
}
private void DrawView ()
{
// This method will be called on both the main thread (through -drawRect:) and a secondary thread (through the display link rendering loop)
// Also, when resizing the view, -reshape is called on the main thread, but we may be drawing on a secondary thread
// Add a mutex around to avoid the threads accessing the context simultaneously
openGLContext.CGLContext.Lock ();
// Make sure we draw to the right context
openGLContext.MakeCurrentContext ();
// Delegate to the scene object for rendering
controller.Scene.DrawGLScene ();
openGLContext.FlushBuffer ();
openGLContext.CGLContext.Unlock ();
}
private void SetupDisplayLink ()
{
// Create a display link capable of being used with all active displays
displayLink = new CVDisplayLink ();
// Set the renderer output callback function
displayLink.SetOutputCallback (MyDisplayLinkOutputCallback);
// Set the display link for the current renderer
CGLContext cglContext = openGLContext.CGLContext;
CGLPixelFormat cglPixelFormat = PixelFormat.CGLPixelFormat;
displayLink.SetCurrentDisplay (cglContext, cglPixelFormat);
}
public CVReturn MyDisplayLinkOutputCallback (CVDisplayLink displayLink, ref CVTimeStamp inNow, ref CVTimeStamp inOutputTime, CVOptionFlags flagsIn, ref CVOptionFlags flagsOut)
{
CVReturn result = GetFrameForTime (inOutputTime);
return result;
}
private CVReturn GetFrameForTime (CVTimeStamp outputTime)
{
// There is no autorelease pool when this method is called because it will be called from a background thread
// It's important to create one or you will leak objects
using (NSAutoreleasePool pool = new NSAutoreleasePool ()) {
// Update the animation
DrawView ();
}
return CVReturn.Success;
}
public NSOpenGLContext OpenGLContext {
get { return openGLContext; }
}
public NSOpenGLPixelFormat PixelFormat {
get { return pixelFormat; }
}
public MainWindowController MainController {
set { controller = value; }
}
public void UpdateView ()
{
// This method will be called on the main thread when resizing, but we may be drawing on a secondary thread through the display link
// Add a mutex around to avoid the threads accessing the context simultaneously
openGLContext.CGLContext.Lock ();
// Delegate to the scene object to update for a change in the view size
controller.Scene.ResizeGLScene (Bounds);
openGLContext.Update ();
openGLContext.CGLContext.Unlock ();
}
private void HandleReshape (NSNotification note)
{
UpdateView ();
}
public void StartAnimation ()
{
if (displayLink != null && !displayLink.IsRunning)
displayLink.Start ();
}
public void StopAnimation ()
{
if (displayLink != null && displayLink.IsRunning)
displayLink.Stop ();
}
// Clean up the notifications
public void DeAllocate()
{
displayLink.Stop();
displayLink.SetOutputCallback(null);
NSNotificationCenter.DefaultCenter.RemoveObserver(notificationProxy);
}
[Export("toggleFullScreen:")]
public void toggleFullScreen (NSObject sender)
{
controller.toggleFullScreen (sender);
}
}
}
scene.cs
namespace NeHeLesson1
{
public class Scene : NSObject
{
public Scene () : base()
{
}
// Resize And Initialize The GL Window
// - See also the method in the MyOpenGLView Constructor about the NSView.NSViewGlobalFrameDidChangeNotification
public void ResizeGLScene (RectangleF bounds)
{
// Reset The Current Viewport
GL.Viewport (0, 0, (int)bounds.Size.Width, (int)bounds.Size.Height);
// Select The Projection Matrix
GL.MatrixMode (MatrixMode.Projection);
// Reset The Projection Matrix
GL.LoadIdentity ();
// Set perspective here - Calculate The Aspect Ratio Of The Window
Perspective (45, bounds.Size.Width / bounds.Size.Height, 0.1, 100);
// Select The Modelview Matrix
GL.MatrixMode (MatrixMode.Modelview);
// Reset The Modelview Matrix
GL.LoadIdentity ();
}
// This creates a symmetric frustum.
// It converts to 6 params (l, r, b, t, n, f) for glFrustum()
// from given 4 params (fovy, aspect, near, far)
public static void Perspective (double fovY, double aspectRatio, double front, double back)
{
const double DEG2RAD = Math.PI / 180;
// tangent of half fovY
double tangent = Math.Tan (fovY / 2 * DEG2RAD);
// half height of near plane
double height = front * tangent;
// half width of near plane
double width = height * aspectRatio;
// params: left, right, bottom, top, near, far
GL.Frustum (-width, width, -height, height, front, back);
}
// This method renders our scene and where all of your drawing code will go.
// The main thing to note is that we've factored the drawing code out of the NSView subclass so that
// the full-screen and non-fullscreen views share the same states for rendering
public bool DrawGLScene ()
{
// Clear The Screen And The Depth Buffer
GL.Clear (ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// Reset The Current Modelview Matrix
GL.LoadIdentity ();
return true;
}
}
}
希望有人可以帮助我解决这个问题,因为它停止运行MonoMac和MonoGameFrameWork,我错过了我的设置。顺便说一句,我能够运行所有OpenGLExtentions Viewer测试,所以我的openGL似乎可以工作。
Jase
答案 0 :(得分:-1)
我会做的事情......
注意:如上所述,NeheLesson1不是MonoGame框架示例。它是纯OpenGL样本。 MonoGame Framework示例可以在上面克隆的MonoGame仓库的Samples和StarterKit子目录中找到。
我希望这会有所帮助。