我想創建一個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