Closed JimSEOW closed 7 years ago
Hi, could you clarify what you mean when you say it "is not working"? Do you get any error messages?
the triangle example follow this I bring the c++ code to VS2015 OpenGLES XAML c++ template and it works.
SimpleTriangle::SimpleTriangle() :
mWindowWidth(0),
mWindowHeight(0)
{
// Vertex Shader source
const std::string vs = STRING
(
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
);
// Fragment Shader source
const std::string fs = STRING
(
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
);
// Set up the shader and its uniform/attribute locations.
mProgram = CompileProgram1(vs, fs);
mPositionAttribLocation = glGetAttribLocation(mProgram, "vPosition");
GLfloat vertexPositions[] =
{
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
glGenBuffers(1, &mVertexPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
}
SimpleTriangle::~SimpleTriangle()
{
if (mProgram != 0)
{
glDeleteProgram(mProgram);
mProgram = 0;
}
if (mVertexPositionBuffer != 0)
{
glDeleteBuffers(1, &mVertexPositionBuffer);
mVertexPositionBuffer = 0;
}
}
void SimpleTriangle::Draw()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
if (mProgram == 0)
return;
// Use the program object
glUseProgram(mProgram);
glBindBuffer(GL_ARRAY_BUFFER, mVertexPositionBuffer);
glEnableVertexAttribArray(mPositionAttribLocation);
glVertexAttribPointer(mPositionAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void SimpleTriangle::UpdateWindowSize(GLsizei width, GLsizei height)
{
glViewport(0, 0, width, height);
mWindowWidth = width;
mWindowHeight = height;
}
For the C#, I port the same thing. There is no error. Just no triangle.
The SimpleTriangle.cs code `
using System;
using System.Text;
using WebGL;
using Windows.Foundation;
using System.Runtime.InteropServices;
using EGLDisplay = System.IntPtr;
using GLenum = System.UInt32;
using GLuint = System.UInt32;
using GLint = System.Int32;
using GLchar = System.Byte;
using GLsizei = System.Int32;
using GLfloat = System.Single;
namespace AppForOpenGLES
{
/// <summary>
///
https://www.khronos.org/assets/uploads/books/openglr_es_20_programming_guide_sample.pdf
/// </summary>
public class SimpleTriangle : IDisposable
{
#region Private
private uint mProgram;
private float mWindowWidth;
private float mWindowHeight;
private uint mPositionAttribLocation;
private uint[] mVertexPositionBuffer;
#endregion
public SimpleTriangle()
{
string vs = @"
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}";
string fs = @"
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}";
// Set up the shader and its uniform/attribute locations.
mProgram = CompileProgram(vs, fs);
mPositionAttribLocation = (uint)GLES.glGetAttribLocation(mProgram, "vPosition");
GLfloat[] vertexPositions =
{
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
mVertexPositionBuffer = new uint[1];
GLES.glGenBuffers(1, mVertexPositionBuffer);
GLES.glBindBuffer(GLES.GL_ARRAY_BUFFER, mVertexPositionBuffer[0]);
GLES.glBufferData(GLES.GL_ARRAY_BUFFER, vertexPositions.Length, InPtr(vertexPositions), GLES.GL_STATIC_DRAW);
}
public void Dispose()
{
if (mProgram != 0)
{
GLES.glDeleteProgram(mProgram);
mProgram = 0;
}
if (mVertexPositionBuffer.Length != 0)
{
GLES.glDeleteBuffers(1, mVertexPositionBuffer);
mVertexPositionBuffer = null;
}
}
public void Draw()
{
GLES.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Clear the color buffer
GLES.glClear(GLES.GL_COLOR_BUFFER_BIT);
if (mProgram == 0)
return;
// Use the program object
GLES.glUseProgram(mProgram);
// Load the vertex data
GLES.glBindBuffer(GLES.GL_ARRAY_BUFFER, mVertexPositionBuffer[0]);
GLES.glEnableVertexAttribArray(mPositionAttribLocation);
GLES.glVertexAttribPointer(mPositionAttribLocation, 3, GLES.GL_FLOAT, (byte)GLES.GL_FALSE, 0, EGLDisplay.Zero);
GLES.glDrawArrays(GLES.GL_TRIANGLES, 0, 3);
}
public void UpdateWindowSize(Size size)
{
GLES.glViewport(0, 0, (int)size.Width, (int)size.Height);
mWindowWidth = (int)size.Width;
mWindowHeight = (int)size.Height;
}
GLuint LoadShader(GLenum type, string shaderSrc )
{
GLuint shader;
GLint compiled;
// Create the shader object
shader = GLES.glCreateShader(type);
if (shader == 0)
{
return 0;
}
// Load the shader source
GLES.glShaderSource(shader, 1, new string[] { @shaderSrc }, null);
// Compile the shader
GLES.glCompileShader(shader);
// Check the compile status
GLES.glGetShaderiv(shader, GLES.GL_COMPILE_STATUS,out compiled);
if (compiled != 0)
{
GLint infoLen = 0;
GLES.glGetShaderiv(shader, GLES.GL_INFO_LOG_LENGTH, out infoLen);
if (infoLen > 1)
{
int size;
var infolog = new StringBuilder(infoLen);
GLES.glGetShaderInfoLog(shader, infoLen, out size, infolog);
var errorMessage = "Error compiling shader: ";
errorMessage += infolog.ToString();
infolog = null;
throw new Exception(errorMessage);
}
GLES.glDeleteShader(shader);
return 0;
}
return shader;
}
#region Compile Shader
private GLuint CompileShader(GLenum type, string shaderSrc)
{
GLuint shader = GLES.glCreateShader(type);
GLES.glShaderSource(shader, 1, new[] { @shaderSrc }, null);
GLES.glCompileShader(shader);
GLint compileResult;
GLES.glGetShaderiv(shader, GLES.GL_COMPILE_STATUS, out compileResult);
if (compileResult == 0)
{
int infoLogLength;
GLES.glGetShaderiv(shader, GLES.GL_INFO_LOG_LENGTH, out infoLogLength);
if (infoLogLength != 0)
{
int size;
var infolog = new StringBuilder(infoLogLength);
GLES.glGetShaderInfoLog(shader, infoLogLength, out size, infolog);
var errorMessage = "Shader compilation failed: ";
errorMessage += infolog.ToString();
throw new Exception(errorMessage);
}
}
return shader;
}
private GLuint CompileProgram(string vsSource, string fsSource)
{
GLuint program = GLES.glCreateProgram();
if (program == 0)
{
throw new Exception("Program creation failed.");
}
GLuint vs = CompileShader(GLES.GL_VERTEX_SHADER, vsSource);
GLuint fs = CompileShader(GLES.GL_FRAGMENT_SHADER, fsSource);
if (vs == 0 || fs == 0)
{
GLES.glDeleteShader(fs);
GLES.glDeleteShader(vs);
GLES.glDeleteProgram(program);
return 0;
}
GLES.glAttachShader(program, vs);
GLES.glDeleteShader(vs);
GLES.glAttachShader(program, fs);
GLES.glDeleteShader(fs);
GLES.glLinkProgram(program);
GLint linkStatus;
GLES.glGetProgramiv(program, GLES.GL_LINK_STATUS, out linkStatus);
if (linkStatus == 0)
{
GLint infoLogLength;
GLES.glGetProgramiv(program, GLES.GL_INFO_LOG_LENGTH, out infoLogLength);
int size;
var infolog = new StringBuilder(infoLogLength);
GLES.glGetProgramInfoLog(program, infoLogLength, out size, infolog);
var errorMessage = "Program link failed: ";
errorMessage += infolog.ToString();
throw new Exception(errorMessage);
}
return program;
}
#endregion
public IntPtr InPtr(float[] FloatArray)
{
var handle = default(GCHandle);
IntPtr pointer = IntPtr.Zero;
try
{
handle = GCHandle.Alloc(FloatArray, GCHandleType.Pinned);
pointer = handle.AddrOfPinnedObject();
}
finally
{
if (handle.IsAllocated)
handle.Free();
}
return pointer;
}
}
}
`
There are 2 types of C++ OpenGL ES templates for VS2015 [1] XAML App for OpenGL ES (Universal Windows) [2] Visual Studio template for cross-platform OpenGL development The approach used here follow [1]: How to combine OpenGL graphics with XAML controls in a single window
@austinkinross The concept of just using PInvoke to allow C# binding to Angle is straight forwards. However, the lack of users trying this reveal many challenges
For people interested at OpenGLES for UWP XAML Interop in C#, please also take a look at SkiaSharp.View.UWP, particularly OpenGLESContext in SkiaSharp.View.UWP
bringing OpenGL ES (Angle) to XAML Standard for 3D
Solved!!!
I am working on a AppForOpenGLES c# template based on the C++ OpenGLES template that comes with VS2015
It is based on the latest ANGLE.WINDOWSTORE nuget
The SimpleText works in W10 and W10M (950XL)
=> Could someone with experience doing ANGLE in C# to take a look why the SimpleTriangle Renderer is not working.
If someone has port the C++ template to C#, please share a link.
relevant issue1 and issue2