Commit 7497ac2b authored by pcy's avatar pcy
Browse files

marshal strings correctly

parent d8e1eb46
......@@ -89,14 +89,7 @@ namespace PoroCYon.FNAGLSL {
uint sh = GL.CreateShader(kvp.Key);
if (sh == 0) GL.Throw();
byte[] utf8src = Encoding.UTF8.GetBytes(kvp.Value);
fixed (byte* sbuf = utf8src) {
sbyte** uurgh = stackalloc sbyte*[1];
*uurgh = (sbyte*)sbuf;
int* uurgh2 = stackalloc int[1];
*uurgh2 = utf8src.Length;
GL.ShaderSource(sh, 1, uurgh, uurgh2);
}
GL.ShaderSource(sh, kvp.Value);
GL.Throw();
GL.CompileShader(sh);
......
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SDL2;
......@@ -11,6 +12,52 @@ using static SDL2.SDL;
namespace PoroCYon.FNAGLSL {
public static unsafe partial class GL {
internal readonly static UTF8Encoding utf8 = new UTF8Encoding(false, true);
static byte[] utf8buf = new byte[64];
internal static byte[] GetNullTermUTF8(string s, bool newarr = false) {
int nbytes = utf8.GetByteCount(s);
byte[] ret;
if (newarr) {
ret = new byte[nbytes + 1];
} else {
if (utf8buf.Length < nbytes + 1)
Array.Resize<byte>(ref utf8buf, nbytes + 1);
ret = utf8buf;
}
utf8.GetBytes(s, 0, s.Length, ret, 0);
ret[nbytes] = 0;
return ret;
}
internal static string StrFromNullTermUTF8(byte[] s) {
fixed (byte* b = s) {
return StrFromNullTermUTF8((sbyte*)b, s.Length);
}
}
internal static string StrFromNullTermUTF8(sbyte[] s) {
fixed (sbyte* b = s) {
return StrFromNullTermUTF8(b, s.Length);
}
}
static long strlen(sbyte* s) {
long r = 0;
for (; *s != 0; ++s, ++r) ;
return r;
}
internal static string StrFromNullTermUTF8(sbyte* s, int nbytes = -1) {
if (nbytes < 0) {
nbytes = (int)strlen(s);;
} /*else {
long sl = strlen(s);
if (nbytes > sl) nbytes = (int)sl;
}*/
return new String(s, 0, nbytes, utf8);
}
public static void Throw() {
GLError err = GetError();
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using GLenum = System.UInt32;
......@@ -87,9 +88,43 @@ namespace PoroCYon.FNAGLSL {
delegate void ShaderSource_T(GLuint sh, GLsizei count,
GLchar** str, GLint* len);
static ShaderSource_T _ShaderSource;
public static void ShaderSource(GLuint sh, GLsizei count,
GLchar** str, GLint* len) {
_ShaderSource(sh, count, str, len);
public static void ShaderSource(GLuint sh, string[] srcs) {
int count = srcs.Length;
// marshal the string array...
byte[][] strs = new byte[count][];
GLint[] lens = new GLint[count];
// convert all the strings to utf8
int totallen = 0;
for (int i = 0; i < count; ++i) {
strs[i] = GetNullTermUTF8(srcs[i]);
totallen += (lens[i] = strs[i].Length);
}
// rearrange pointer crap so that GL can use it
byte[] bytesbytes = new byte[totallen];
GLchar*[] ptrs = new GLchar*[count];
fixed (byte* bbp = bytesbytes) {
int totalidx = 0;
for (int i = 0; i < count; ++i) {
Array.Copy(strs[i], 0, bytesbytes, totalidx, lens[i]);
ptrs[i] = (GLchar*)&bbp[totalidx];
totalidx += lens[i];
}
// now we can actually call the function
fixed (GLchar** strp = ptrs) {
fixed (GLint* lenp = lens) {
_ShaderSource(sh, count, strp, lenp);
}
}
}
}
readonly static string[] strarr = new string[1];
public static void ShaderSource(GLuint sh, string src) {
strarr[0] = src;
ShaderSource(sh, strarr);
}
delegate void CompileShader_T(GLuint sh);
......@@ -113,7 +148,7 @@ namespace PoroCYon.FNAGLSL {
GLsizei len = 0;
fixed (GLchar* logp = logbuf) {
_GetShaderInfoLog(sh, maxl, &len, logp);
return new String(logp, 0, len, Encoding.UTF8);
return StrFromNullTermUTF8(logp, len);
}
}
......@@ -145,7 +180,7 @@ namespace PoroCYon.FNAGLSL {
GLsizei len = 0;
fixed (GLchar* logp = logbuf) {
_GetProgramInfoLog(prgm, maxl, &len, logp);
return new String(logp, 0, len, Encoding.UTF8);
return StrFromNullTermUTF8(logp, len);
}
}
......@@ -189,14 +224,14 @@ namespace PoroCYon.FNAGLSL {
(GLsizei)(NAMEBUF_MAX_LEN*sizeof(GLchar)),
&namelen, psize, &_typ, namebuf);
}
name = new String(namebuf, 0, namelen, Encoding.UTF8);
name = StrFromNullTermUTF8(namebuf, namelen);
type = (GLSLType)_typ;
}
delegate GLint GetAttribLocation_T(GLuint prgm, GLchar* name);
static GetAttribLocation_T _GetAttribLocation;
public static GLint GetAttribLocation(GLuint prgm, string name) {
byte[] blargh = Encoding.UTF8.GetBytes(name);
byte[] blargh = GetNullTermUTF8(name);
fixed (byte* bb = blargh) {
return _GetAttribLocation(prgm, (GLchar*)bb);
......@@ -214,14 +249,14 @@ namespace PoroCYon.FNAGLSL {
// marshal the string array...
// convert all the string to utf8
// convert all the strings to utf8
int totallen = 0;
byte[][] bytes = new byte[names.Length][];
for (int i = 0; i < names.Length; ++i) {
bytes[i] = Encoding.UTF8.GetBytes(names[i]);
bytes[i] = GetNullTermUTF8(names[i], true);
totallen += bytes[i].Length;
}
// rearrange pointer crap to that glGetUniformIndices can read it
// rearrange pointer crap so that glGetUniformIndices can read it
byte[] bytesbytes = new byte[totallen];
GLchar*[] ptrs = new GLchar*[names.Length];
fixed (byte* bbp = bytesbytes) {
......@@ -285,7 +320,7 @@ namespace PoroCYon.FNAGLSL {
(GLsizei)(NAMEBUF_MAX_LEN*sizeof(GLchar)),
&namelen, psize, &_typ, namebuf);
}
name = new String(namebuf, 0, namelen, Encoding.UTF8);
name = StrFromNullTermUTF8(namebuf, namelen);
type = (GLSLType)_typ;
}
......@@ -294,7 +329,7 @@ namespace PoroCYon.FNAGLSL {
public static GLint GetUniformLocation(GLuint prgm, string name) {
if (name == null) throw new ArgumentNullException("name");
byte[] bytes = Encoding.UTF8.GetBytes(name);
byte[] bytes = GetNullTermUTF8(name);
fixed (byte* bp = bytes) {
return _GetUniformLocation(prgm, (GLchar*)bp);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment