如何解决无法获得要在GLSL Xamarin OpenGLView控制中渲染的颜色
任何人都可以提供以下帮助吗?
使用Visual Studio 2019 Xamarin Forms项目,我试图在Android模拟器中显示旋转的红色正方形。我可以用,但是我的正方形是黑色的:
这是我的MainPage.xaml.cs的代码(将ES20用作ES10的代码没有我需要的OpenGL函数):
using OpenTK.Graphics.ES20;
using System;
using Xamarin.Forms;
namespace OGLMobile
{
public partial class MainPage : ContentPage
{
private float red = 1.0f;
private float green = 0.0f;
private float blue = 0.0f;
private const float halfWidth = 0.2f;
private float[] m_vertex_buffer_data = { 0.5f - halfWidth,0.5f - halfWidth,0.0f,0.5f + halfWidth,0.0f };
private string[] m_szVertexShader = null;
private string[] m_szFragmentShader = null;
private int m_nProgram = -1;
private int m_nVertexShaderHandle = -1;
private int m_nFragmentShaderHandle = -1;
private uint[] indices = { 0,1,2,3 };
private int m_nVertexBuffer = -1;
bool m_bOGLParameteRSSet = false;
private void RotateSquare(float radians,float xRotationCentre,float yRotationCentre)
{
int[] nBaseIndices = { 0,3,6,9 };
for (int nVertex = 0; nVertex <= 3 ; nVertex++)
{
int nIndex1 = nBaseIndices[nVertex];
int nIndex2 = nIndex1 + 1;
float offsetX = m_vertex_buffer_data[nIndex1] - xRotationCentre;
float offsetY = m_vertex_buffer_data[nIndex2] - yRotationCentre;
double xRotated = offsetX * Math.Cos(radians) - offsetY * Math.Sin(radians);
double yRotated = offsetX * Math.Sin(radians) + offsetY * Math.Cos(radians);
m_vertex_buffer_data[nIndex1] = (float)xRotated + xRotationCentre;
m_vertex_buffer_data[nIndex2] = (float)yRotated + yRotationCentre;
}
GL.BindBuffer(BufferTarget.ArrayBuffer,m_nVertexBuffer);
GL.BufferSubData(BufferTarget.ArrayBuffer,IntPtr.Zero,new IntPtr(m_vertex_buffer_data.Length * sizeof(float)),m_vertex_buffer_data);
}
public MainPage()
{
Title = "OpenGL";
var view = new OpenGLView { HasRenderLoop = true };
var toggle = new Switch { IsToggled = true };
m_szVertexShader = new string[1];
m_szFragmentShader = new string[1];
view.HeightRequest = 300;
view.WidthRequest = 300;
GL.Viewport(0,300,300);
view.Ondisplay = r =>
{
if(!m_bOGLParameteRSSet) // Do this only on first rendering
{
CreateShader();
m_bOGLParameteRSSet = true;
GL.UseProgram(m_nProgram);
GL.GenBuffers(1,out m_nVertexBuffer);
GL.BindBuffer(BufferTarget.ArrayBuffer,m_nVertexBuffer);
GL.BufferData(BufferTarget.ArrayBuffer,m_vertex_buffer_data,BufferUsage.StaticDraw);
}
GL.ClearColor(0.0f,1.0f,1.0f);
GL.Clear((ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit));
RotateSquare(0.0174533f,0.5f,0.5f);
GL.EnabLevertexAttribArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer,m_nVertexBuffer);
GL.VertexAttribPointer(0,VertexAttribPointerType.Float,false,0);
GL.DrawElements(BeginMode.Triangles,indices.Length,DrawElementsType.UnsignedInt,indices);
GL.disabLevertexAttribArray(0);
};
toggle.Toggled += (s,a) =>
{
view.HasRenderLoop = toggle.IsToggled;
};
var stack = new StackLayout
{
Padding = new Size(20,20),Children = { view,toggle}
};
Content = stack;
}
private void SetShaderSource()
{
m_szVertexShader[0] = "void main()" +
"{" +
"gl_Position = ftransform();" +
"}";
m_szFragmentShader[0] = "void main()" +
"{" +
"gl_FragColor = vec4(1.0,0.0,1.0);" +
"}";
}
private void CreateShader()
{
SetShaderSource();
int nVertexShaderSourceLength = m_szVertexShader[0].Length;
int nFragmentShaderLength = m_szFragmentShader[0].Length;
m_nVertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
m_nFragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(m_nVertexShaderHandle,m_szVertexShader,new int[] { nVertexShaderSourceLength });
GL.ShaderSource(m_nFragmentShaderHandle,m_szFragmentShader,new int[] { nVertexShaderSourceLength });
GL.CompileShader(m_nVertexShaderHandle);
GL.CompileShader(m_nFragmentShaderHandle);
string szVertexShaderLog = GL.GetShaderInfoLog(m_nVertexShaderHandle);
string szFragmentShaderLog = GL.GetShaderInfoLog(m_nFragmentShaderHandle);
m_nProgram = GL.CreateProgram();
GL.AttachShader(m_nProgram,m_nVertexShaderHandle);
GL.AttachShader(m_nProgram,m_nFragmentShaderHandle);
GL.LinkProgram(m_nProgram);
}
}
}
我的着色器一定不正确,如果用垃圾字符串替换它们,我将得到相同的输出,因此系统必须默认使用某种东西。
调用GetShaderInfoLog时确实存在编译错误,但是我的着色器太琐碎,以至于我看不到这个问题:
非常感谢您的帮助(暂时停滞了一段时间。之前已经在台式机和WebGL上完成了很多OpenGL,但在移动方面还没有运气)。
添加:非常感谢您的答复。我已经用兼容的着色器替换了着色器,不幸的是我仍然有一个黑色正方形:
(在图中显示为mediump的图像中,我也尝试过highp和lowp,但仍然得到相同的结果)。
我现在在编译顶点着色器时遇到了不同的错误,片段着色器也没有错误-尽管我确实对后者提出了一个警告:
感谢您可能提供的其他建议。
解决方法
这些着色器不符合任何GLSL ES规范。分别参见OpenGL ES Shading Language 1.00 Specification。 OpenGL ES Shading Language 3.00 Specification。
查看具有顶点着色器的有效着色器:
attribute vec3 a_position;
void main()
{
gl_Position = vec4(a_position,1.0);
}
和片段着色器
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0,0.0,1.0);
}
我建议验证着色器是否正确编译:
GL.CompileShader(m_nVertexShaderHandle);
string infoLogFrag = GL.GetShaderInfoLog(m_nVertexShaderHandle);
if (infoLogFrag != System.String.Empty)
{
System.Console.WriteLine(infoLogFrag);
}
GL.CompileShader(m_nFragmentShaderHandle);
string infoLogVert = GL.GetShaderInfoLog(m_nFragmentShaderHandle);
if (infoLogVert != System.String.Empty)
{
System.Console.WriteLine(infoLogVert);
}
程序链接没有错误:
GL.LinkProgram(m_nProgram);
string infoLogProg = GL.GetProgramInfoLog(m_nProgram );
if (infoLogProg != System.String.Empty)
{
System.Console.WriteLine(infoLogProg);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。