我想创建一个iOS/Android演示应用程序,显示Xamarin OpenTK/OpenGl在屏幕上呈现一些多维数据集。一切工作在iOS,但在Android相同的代码只是崩溃。这是完全基于他们的一些演示代码的共享代码。Xamarin:OpenTK OpenGL 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);
}
}
}
UPDATE
我认为这是一件与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));
}
}
并没有什么渲染错误
[肾上腺EGLSUB]:无效的本地缓存。未能queueBuffer [肾上腺EGLSUB]:本地缓冲区为NULL
我得到[肾上腺EGLSUB] :本机缓冲区为NULL [Adreno-EGLSUB] :无效的本机缓冲区呃。无法将缓冲队列为错误并且没有渲染 –
Burf2000
在模拟器中尝试它,即时通讯很确定您获取的错误与实际的物理设备有关,并且是单独的问题 –
我刚刚得到垃圾 – Burf2000