Hi all, I have a bit of code here that runs very well on iOS, and in the Android simulator (all is displayed properly). However, I have tried to run it on two different devices (Nexus 5, and SM-P900) both of which will not display the OpenGL render, rather just a black box.
Here is my OpenTK code that is put into the OnDisplay method
using System;
using OpenTK.Graphics.ES20;
using OpenTK.Graphics;
using OpenTK;
using Xamarin.Forms;
using CubeCrack.Shared;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
#if __ANDROID__
using Android.Util;
#endif
[assembly: Dependency(typeof(GLEngineShared))]
namespace CubeCrack.Shared
{
public class GLEngineShared : GLEngine
{
uint frameBuffer;
uint indexBuffer;
uint colorRenderBuffer;
uint depthRenderBuffer;
int positionSlot;
int colorSlot;
int projectionSlot;
int modelViewSlot;
int cubieViewSlot;
int width_pixels, height_pixels;
float rotate = 0.0f;
static readonly float offset = 2.05f;
public OpenGLView View { get; set; }
public CubeViewModel ViewModel { get; set; }
Matrix4 animationMatrix;
public GLEngineShared () { }
void SetupRenderBuffers(){
#if __ANDROID__
width_pixels = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, (float) View.Width, Xamarin.Forms.Forms.Context.Resources.DisplayMetrics);
height_pixels = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, (float) View.Height, Xamarin.Forms.Forms.Context.Resources.DisplayMetrics);
Debug.WriteLine("width: " + width_pixels + " height: " + height_pixels);
#else
width_pixels = (int)View.Width;
height_pixels = (int)View.Height;
#endif
GL.GenRenderbuffers (1, out depthRenderBuffer);
GL.BindRenderbuffer (RenderbufferTarget.Renderbuffer, depthRenderBuffer);
GL.RenderbufferStorage (RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.DepthComponent16,
width_pixels, height_pixels);
GL.GenRenderbuffers (1, out colorRenderBuffer);
GL.BindRenderbuffer (RenderbufferTarget.Renderbuffer, colorRenderBuffer);
GL.RenderbufferStorage (RenderbufferTarget.Renderbuffer, RenderbufferInternalFormat.Rgba4,
width_pixels, height_pixels);
}
void SetupFrameBuffer(){
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, depthRenderBuffer);
}
int CompileShader(string shaderName, ShaderType shaderType){
string prefix;
#if __IOS__
prefix = "CubeCrack.iOS.";
#elif __ANDROID__
prefix = "CubeCrack.Droid.";
#endif
var assembly = typeof(GLEngineShared).GetTypeInfo ().Assembly;
Stream stream = assembly.GetManifestResourceStream (prefix + "Shaders." + shaderName + ".glsl");
string shaderString;
using (var reader = new StreamReader (stream)) {
shaderString = reader.ReadToEnd ();
}
int shaderHandle = GL.CreateShader (shaderType);
GL.ShaderSource (shaderHandle, shaderString);
GL.CompileShader (shaderHandle);
return shaderHandle;
}
void CompileShaders(){
int vertexShader = CompileShader ("SimpleVertex", ShaderType.VertexShader);
int fragmentShader = CompileShader ("SimpleFragment", ShaderType.FragmentShader);
int programHandle = GL.CreateProgram ();
GL.AttachShader (programHandle, vertexShader);
GL.AttachShader (programHandle, fragmentShader);
GL.LinkProgram (programHandle);
GL.UseProgram (programHandle);
positionSlot = GL.GetAttribLocation (programHandle, "Position");
colorSlot = GL.GetAttribLocation (programHandle, "SourceColor");
projectionSlot = GL.GetUniformLocation (programHandle, "Projection");
modelViewSlot = GL.GetUniformLocation (programHandle, "Modelview");
cubieViewSlot = GL.GetUniformLocation (programHandle, "CubieView");
GL.EnableVertexAttribArray (positionSlot);
GL.EnableVertexAttribArray (colorSlot);
}
void SetupVBOs(){
uint vertexBuffer;
GL.GenBuffers (1, out vertexBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, vertexBuffer);
GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)(Vector3.SizeInBytes * CubeData.Verticies.Length), CubeData.Verticies, BufferUsage.StaticDraw);
GL.VertexAttribPointer (positionSlot, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
// GL.GenBuffers (1, out indexBuffer);
// GL.BindBuffer (BufferTarget.ElementArrayBuffer, indexBuffer);
// GL.BufferData (BufferTarget.ElementArrayBuffer, (IntPtr)(sizeof(byte) * CubeData.Indices.Length), CubeData.Indices, BufferUsage.StaticDraw);
}
#region GLEngine implementation
public void Initialize ()
{
// GL.Viewport (0, 0, (int)View.Width, (int)View.Height);
SetupRenderBuffers ();
SetupFrameBuffer ();
CompileShaders ();
SetupVBOs ();
}
public void DrawCornerCubes(){
for (int i = 0; i < 8; i++) {
var colorData = new List ();
var colors = ViewModel.GetCornerColors (i);
foreach (var color in colors) {
colorData.Add (CubeData.GetVectorFromColor (color));
}
var ColorData = new Vector4[24];
for(int j = 0; j < 24; j++){
ColorData[j] = new Vector4(0,0,0,1);
}
for(int j = 4; j <= 7; j++){
ColorData [j] = colorData [0];
}
for(int j = 16; j <= 19; j++){
ColorData [j] = colorData [1];
}
for (int j = 8; j <= 11; j++) {
ColorData [j] = colorData [2];
}
uint colorBuffer;
GL.GenBuffers (1, out colorBuffer);
GL.BindBuffer (BufferTarget.ArrayBuffer, colorBuffer);
GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)(Vector4.SizeInBytes * ColorData.Length), ColorData, BufferUsage.StaticDraw);
GL.VertexAttribPointer (colorSlot, 4, VertexAttribPointerType.Float, false, Vector4.SizeInBytes, 0);
Matrix4 animateMatrix;
if (ViewModel.IsCornerAnimating (i))
animateMatrix = animationMatrix;
else
animateMatrix = Matrix4.Identity;
Matrix4 rotationMatrix = Matrix4.CreateRotationX (CubeViewModel.CornerRotationTable [i][0]) *
Matrix4.CreateRotationY (CubeViewModel.CornerRotationTable [i][1]) *
Matrix4.CreateRotationZ (CubeViewModel.CornerRotationTable [i][2]);
Matrix4 translationMatrix = Matrix4.CreateTranslation (offset * CubeViewModel.CornerTranslationTable [i] [0],
offset * CubeViewModel.CornerTranslationTable [i] [1], offset * CubeViewModel.CornerTranslationTable [i] [2]);
Matrix4[] cubieView = { rotationMatrix * translationMatrix * animateMatrix };
GL.UniformMatrix4 (cubieViewSlot, false, ref cubieView [0]);
GL.DrawElements(BeginMode.Triangles, CubeData.Indices.Length, DrawElementsType.UnsignedByte, CubeData.Indices);
colorData.Clear ();
GL.DeleteBuffers (1, ref colorBuffer);
}
}
public void DrawEdgeCubes(){
for (int i = 0; i < 12; i++) {
var colorData = new List<Vector4> ();
var colors = ViewModel.GetEdgeColors (i);
foreach (var color in colors) {
colorData.Add (CubeData.GetVectorFromColor (color));
}
var ColorData = new Vector4[24];
for(int j = 0; j < 24; j++){
ColorData[j] = new Vector4(0,0,0,1);
}
for(int j = 4; j
The error I with the Nexus 5 is
[Adreno-EGLSUB] : Invalid native buffer. Failed to queueBuffer
[Adreno-EGLSUB] : native buffer is NULL
And over with my Samsung Note 12.2 (SM-P900)
I noticed this line, which I believe is relevant
[mali_winsys] new_window_surface returns 0x3000
Neither of the applications crash, but just display a black box where I should have OpenGL code rendering.
Any advice on how to debug or find the problem and solution would be much appreciated.