【发布时间】:2015-09-06 22:08:29
【问题描述】:
我正在尝试创建一个 iOS/Android 演示应用程序,该应用程序显示 Xamarin OpenTK / OpenGl 在屏幕上呈现一些立方体。在 iOS 中一切正常,但在 Android 中相同的代码会崩溃。这是基于他们的一些演示代码的完全共享代码。
我没有得到有关崩溃的信息。
using OpenTK.Graphics.ES20;
using Xamarin.Forms;
using OpenTK.Graphics;
using OpenTK;
using System.Reflection;
using System.IO;
using System.Diagnostics;
using System;
namespace GLDemo
{
public class App
{
public static Page GetMainPage ()
{
return new OpenGLPage ();
}
}
public class OpenGLPage : ContentPage
{
uint positionSlot;
uint colorSlot;
uint projectionSlot;
uint modelViewSlot;
uint colorRenderBuffer;
uint depthBuffer;
// cube verticies
Vector3[] Verticies = new Vector3[] {
new Vector3 (1.0f, -1.0f, 1.0f),
new Vector3 (1.0f, 1.0f, 1.0f),
new Vector3 (-1.0f, 1.0f, 1.0f),
new Vector3(-1.0f, -1.0f, 1.0f),
new Vector3(1.0f, -1.0f, -1.0f),
new Vector3(1.0f, 1.0f, -1.0f),
new Vector3(-1.0f, 1.0f, -1.0f),
new Vector3(-1.0f, -1.0f, -1.0f)};
Vector4[] Colors = new Vector4[]{
new Vector4(0.0f, 0.0f, 0.0f, 1.0f),
new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(1.0f, 1.0f, 1.0f, 1.0f)};
byte[] Indices = new byte []
{ 0, 1, 2,
2, 3, 0,
4, 6, 5,
4, 7, 6,
2, 7, 3,
7, 6, 2,
0, 4, 1,
4, 1, 5,
6, 2, 1,
1, 6, 5,
0, 3, 7,
0, 7, 4};
public OpenGLPage ()
{
Title = "OpenGL";
var view = new OpenGLView { HasRenderLoop = true };
var toggle = new Xamarin.Forms.Switch { IsToggled = true };
var button = new Button { Text = "Display" };
view.HeightRequest = 300;
view.WidthRequest = 300;
bool initialize = false;
float rotation = 0.0f;
float translation = 0.0f;
bool goingRight = true;
view.OnDisplay = r => {
if(!initialize){
SetupDepthBuffer ();
SetupRenderBuffers ();
SetupFrameBuffer ();
CompileShaders ();
SetupVBOs ();
initialize = true;
}
GL.ClearColor(0.0f,0.0f,0.0f,1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
rotation += 0.02f;
if(goingRight){
translation += 0.01f;
if(translation > 1.0f){
goingRight = false;
}
} else{
translation -= 0.01f;
if(translation < -1.0f){
goingRight = true;
}
}
for(int i = 0; i < 3; i++){
float h = 4.0f * (float)view.Height / (float)view.Width;
Matrix4[] projection = new Matrix4[]{ Matrix4.CreatePerspectiveOffCenter(-2, 2, -h/2, h/2, 4, 10) };
GL.UniformMatrix4 ((int)projectionSlot, false, ref projection[0]);
Matrix4[] modelView = new Matrix4[]{ Matrix4.CreateRotationX(rotation) * Matrix4.CreateRotationY(rotation) * Matrix4.CreateRotationZ(rotation) * Matrix4.CreateTranslation (translation - i * 3.5f + 4.0f, (float)(-1^i) * translation, -7 + translation) };
GL.UniformMatrix4 ((int)modelViewSlot, false, ref modelView [0]);
GL.DrawElements(BeginMode.Triangles, Indices.Length, DrawElementsType.UnsignedByte, 0);
}
};
toggle.Toggled += (s, a) => {
view.HasRenderLoop = toggle.IsToggled;
};
button.Clicked += (s, a) => view.Display ();
var stack = new StackLayout {
Padding = new Size (20, 20),
Children = {view, toggle, button}
};
Content = stack;
}
void SetupRenderBuffers(){
GL.GenRenderbuffers (1, out colorRenderBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, colorRenderBuffer);
GL.RenderbufferStorage (RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.Rgba4, 300, 300);
}
void SetupFrameBuffer(){
uint frameBuffer;
GL.GenFramebuffers (1, out frameBuffer);
GL.BindFramebuffer (FramebufferTarget.Framebuffer, frameBuffer);
GL.FramebufferRenderbuffer (FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0,
RenderbufferTarget.Renderbuffer, colorRenderBuffer);
GL.FramebufferRenderbuffer (FramebufferTarget.Framebuffer, FramebufferSlot.DepthAttachment,
RenderbufferTarget.Renderbuffer, depthBuffer);
}
void SetupDepthBuffer(){
GL.GenRenderbuffers (1, out depthBuffer);
GL.BindRenderbuffer (RenderbufferTarget.Renderbuffer, depthBuffer);
GL.RenderbufferStorage (RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.DepthComponent16, 300, 300);
}
uint CompileShader(string shaderName, ShaderType shaderType){
string prefix;
#if __IOS__
prefix = "GLDemo.iOS.";
#endif
#if __ANDROID__
prefix = "GLDemo.Android.";
#endif
var assembly = typeof(App).GetTypeInfo ().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
System.Diagnostics.Debug.WriteLine("found resource: " + res);
Stream stream = assembly.GetManifestResourceStream (prefix + shaderName + ".glsl");
string shaderString;
using (var reader = new StreamReader (stream)) {
shaderString = reader.ReadToEnd ();
}
Debug.WriteLine (shaderString);
uint shaderHandle = (uint)GL.CreateShader (shaderType);
GL.ShaderSource ((int)shaderHandle, shaderString);
GL.CompileShader (shaderHandle);
return shaderHandle;
}
void CompileShaders(){
uint vertexShader = CompileShader ("SimpleVertex", ShaderType.VertexShader);
uint fragmentShader = CompileShader ("SimpleFragment", ShaderType.FragmentShader);
uint programHandle = (uint)GL.CreateProgram ();
GL.AttachShader (programHandle, vertexShader);
GL.AttachShader (programHandle, fragmentShader);
GL.LinkProgram (programHandle);
GL.UseProgram (programHandle);
positionSlot = (uint)GL.GetAttribLocation (programHandle, "Position");
colorSlot = (uint)GL.GetAttribLocation (programHandle, "SourceColor");
projectionSlot = (uint)GL.GetUniformLocation (programHandle, "Projection");
modelViewSlot = (uint)GL.GetUniformLocation (programHandle, "Modelview");
GL.EnableVertexAttribArray (positionSlot);
GL.EnableVertexAttribArray (colorSlot);
GL.EnableVertexAttribArray (projectionSlot);
GL.EnableVertexAttribArray (modelViewSlot);
}
void SetupVBOs(){
uint vertexBuffer;
GL.GenBuffers (1, out vertexBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, vertexBuffer);
GL.BufferData (BufferTarget.ArrayBuffer,(IntPtr)(Vector3.SizeInBytes * Verticies.Length), Verticies, BufferUsage.StaticDraw);
GL.VertexAttribPointer (positionSlot, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
uint colorBuffer;
GL.GenBuffers (1, out colorBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, colorBuffer);
GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)(Vector4.SizeInBytes * Colors.Length), Colors, BufferUsage.StaticDraw);
GL.VertexAttribPointer (colorSlot, 4, VertexAttribPointerType.Float, false, Vector4.SizeInBytes, 0);
uint indexBuffer;
GL.GenBuffers (1, out indexBuffer);
GL.BindBuffer (BufferTarget.ElementArrayBuffer, indexBuffer);
GL.BufferData (BufferTarget.ElementArrayBuffer,(IntPtr)(sizeof(byte) * Indices.Length), Indices, BufferUsage.StaticDraw);
}
}
}
更新
我相信这与 Android 和 VBO 有关。已知问题?谁知道怎么解决
更新 2
更新到
void SetupVBOs(){
uint vertexBuffer;
GL.GenBuffers (1, out vertexBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, vertexBuffer);
GL.BufferData (BufferTarget.ArrayBuffer,(IntPtr)(Vector3.SizeInBytes * Verticies.Length), Verticies, BufferUsage.StaticDraw);
GL.VertexAttribPointer (positionSlot, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
uint colorBuffer;
GL.GenBuffers (1, out colorBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, colorBuffer);
GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)(Vector4.SizeInBytes * Colors.Length), Colors, BufferUsage.StaticDraw);
GL.VertexAttribPointer (colorSlot, 4, VertexAttribPointerType.Float, false, Vector4.SizeInBytes, 0);
}
我试试
GL.DrawElements(BeginMode.Triangles, Indices.Length, DrawElementsType.UnsignedByte, Indices);
它在设备上崩溃
我试试
unsafe
{
fixed (byte* ptr = Indices)
{
GL.DrawElements(BeginMode.Triangles, Indices.Length, DrawElementsType.UnsignedByte, new IntPtr(ptr));
}
}
并且没有任何错误呈现
[Adreno-EGLSUB] : 本机缓冲区无效。排队缓冲区失败 [Adreno-EGLSUB] : 本机缓冲区为 NULL
【问题讨论】:
标签: android opengl-es xamarin xamarin.android opentk