Auto-formatting with clang-format

This commit is contained in:
Martin Fouilleul 2023-08-19 14:49:23 +02:00
parent 0d920670a2
commit 94b9cb2bbf
168 changed files with 42897 additions and 40823 deletions

View File

@ -1,14 +1,17 @@
AllowAllArgumentsOnNextLine: false
BreakBeforeBraces: Allman
ColumnLimit: 0
Cpp11BracedListStyle: false
ColumnLimit: 0
BreakBeforeBinaryOperators: NonAssignment
AlignOperands: AlignAfterOperator
IndentPPDirectives: BeforeHash
IndentCaseLabels: true
IndentWidth: 4
TabWidth: 4
UseTab: Never
LineEnding: LF
MaxEmptyLinesToKeep: 1
PointerAlignment: Left
SeparateDefinitionBlocks: Always
SpaceBeforeParens: Never
TabWidth: 4
UseTab: Never
ReflowComments: false

1
ext/.clang-format Normal file
View File

@ -0,0 +1 @@
DisableFormat: true

File diff suppressed because it is too large Load Diff

View File

@ -13,44 +13,44 @@ uniform float dissipation;
vec2 u(ivec2 coord)
{
return(texelFetch(velocity, coord, 0).xy);
return (texelFetch(velocity, coord, 0).xy);
}
vec4 q(ivec2 coord)
{
if( coord.x < 0
|| coord.x >= textureSize(src, 0).x
|| coord.y < 0
|| coord.y >= textureSize(src, 0).y)
{
return(vec4(0.));
}
return(texelFetch(src, coord, 0));
if(coord.x < 0
|| coord.x >= textureSize(src, 0).x
|| coord.y < 0
|| coord.y >= textureSize(src, 0).y)
{
return (vec4(0.));
}
return (texelFetch(src, coord, 0));
}
vec4 bilerpSrc(vec2 pos)
{
vec2 offset = fract(pos);
vec2 offset = fract(pos);
ivec2 bl = ivec2(floor(pos));
ivec2 bl = ivec2(floor(pos));
ivec2 br = bl + ivec2(1, 0);
ivec2 tl = bl + ivec2(0, 1);
ivec2 tr = bl + ivec2(1, 1);
ivec2 br = bl + ivec2(1, 0);
ivec2 tl = bl + ivec2(0, 1);
ivec2 tr = bl + ivec2(1, 1);
vec4 lerpTop = (1.-offset.x)*q(tl) + offset.x*q(tr);
vec4 lerpBottom = (1.-offset.x)*q(bl) + offset.x*q(br);
vec4 result = (1.-offset.y)*lerpBottom + offset.y*lerpTop;
vec4 lerpTop = (1. - offset.x) * q(tl) + offset.x * q(tr);
vec4 lerpBottom = (1. - offset.x) * q(bl) + offset.x * q(br);
vec4 result = (1. - offset.y) * lerpBottom + offset.y * lerpTop;
return(result);
return (result);
}
void main()
{
float texWidth = float(textureSize(velocity, 0).x);
float texWidth = float(textureSize(velocity, 0).x);
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
vec2 samplePos = vec2(pixelCoord) - texWidth * delta * u(pixelCoord);
fragColor = bilerpSrc(samplePos) / (1. + dissipation*delta);
vec2 samplePos = vec2(pixelCoord) - texWidth * delta * u(pixelCoord);
fragColor = bilerpSrc(samplePos) / (1. + dissipation * delta);
}

View File

@ -10,25 +10,34 @@ uniform sampler2D tex;
vec3 color_map(float v)
{
float logv = log(abs(v))/log(10.0);
float f = floor(logv + 7.0);
float i = floor(4.0*(logv + 7.0 - f));
float logv = log(abs(v)) / log(10.0);
float f = floor(logv + 7.0);
float i = floor(4.0 * (logv + 7.0 - f));
if(f < 0.0) return vec3(0.0);
if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0);
if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 4.0) return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 6.0) return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i/4.0);
if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0);
if(f < 8.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0);
return vec3(1.0);
if(f < 0.0)
return vec3(0.0);
if(f < 1.0)
return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i / 4.0);
if(f < 2.0)
return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i / 4.0);
if(f < 3.0)
return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i / 4.0);
if(f < 4.0)
return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i / 4.0);
if(f < 5.0)
return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i / 4.0);
if(f < 6.0)
return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i / 4.0);
if(f < 7.0)
return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i / 4.0);
if(f < 8.0)
return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i / 4.0);
return vec3(1.0);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(tex, 0).xy)));
float f = texelFetch(tex, pixelCoord, 0).x;
fragColor = vec4(color_map(f), 1.0);
ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(tex, 0).xy)));
float f = texelFetch(tex, pixelCoord, 0).x;
fragColor = vec4(color_map(f), 1.0);
}

View File

@ -9,6 +9,6 @@ uniform mat4 mvp;
void main()
{
texCoord = 0.5*(pos + vec2(1,1));
gl_Position = mvp * vec4(pos, 0, 1);
texCoord = 0.5 * (pos + vec2(1, 1));
gl_Position = mvp * vec4(pos, 0, 1);
}

View File

@ -10,6 +10,6 @@ uniform sampler2D tex;
void main()
{
fragColor = texture(tex, texCoord);
fragColor.a = 1.0;
fragColor = texture(tex, texCoord);
fragColor.a = 1.0;
}

View File

@ -11,55 +11,64 @@ uniform sampler2D bTex;
float x(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return(0.);
}
return(texelFetch(xTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return (0.);
}
return (texelFetch(xTex, coord, 0).x);
}
float b(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return(0.);
}
return(texelFetch(bTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return (0.);
}
return (texelFetch(bTex, coord, 0).x);
}
vec3 color_map(float v)
{
float logv = log(abs(v))/log(10.0);
float f = floor(logv + 7.0);
float i = floor(4.0*(logv + 7.0 - f));
float logv = log(abs(v)) / log(10.0);
float f = floor(logv + 7.0);
float i = floor(4.0 * (logv + 7.0 - f));
if(f < 0.0) return vec3(0.0);
if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0);
if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 4.0) return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i/4.0);
if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0);
if(f < 6.0) return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i/4.0);
if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0);
if(f < 8.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0);
return vec3(1.0);
if(f < 0.0)
return vec3(0.0);
if(f < 1.0)
return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i / 4.0);
if(f < 2.0)
return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i / 4.0);
if(f < 3.0)
return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i / 4.0);
if(f < 4.0)
return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i / 4.0);
if(f < 5.0)
return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i / 4.0);
if(f < 6.0)
return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i / 4.0);
if(f < 7.0)
return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i / 4.0);
if(f < 8.0)
return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i / 4.0);
return vec3(1.0);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(xTex, 0).xy)));
ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(xTex, 0).xy)));
float tl = x(pixelCoord + ivec2(-1, 1));
float tr = x(pixelCoord + ivec2(1, 1));
float bl = x(pixelCoord + ivec2(-1, -1));
float br = x(pixelCoord + ivec2(1, -1));
float tl = x(pixelCoord + ivec2(-1, 1));
float tr = x(pixelCoord + ivec2(1, 1));
float bl = x(pixelCoord + ivec2(-1, -1));
float br = x(pixelCoord + ivec2(1, -1));
float residue = b(pixelCoord) - (-tl - tr - bl - br + 4.*x(pixelCoord));
fragColor = vec4(color_map(residue), 1);
float residue = b(pixelCoord) - (-tl - tr - bl - br + 4. * x(pixelCoord));
fragColor = vec4(color_map(residue), 1);
}

View File

@ -10,9 +10,9 @@ uniform ivec2 gridSize;
void main()
{
float margin = 32.;
float ratio = 1. - 2.*margin/float(gridSize.x);
float margin = 32.;
float ratio = 1. - 2. * margin / float(gridSize.x);
texCoord = margin/float(gridSize.x) + ratio*(0.5*(pos + vec2(1,1)));
gl_Position = mvp * vec4(pos, 0, 1);
texCoord = margin / float(gridSize.x) + ratio * (0.5 * (pos + vec2(1, 1)));
gl_Position = mvp * vec4(pos, 0, 1);
}

View File

@ -7,6 +7,6 @@ out vec2 texCoord;
void main()
{
texCoord = 0.5*(pos + vec2(1,1));
gl_Position = vec4(pos, 0, 1);
texCoord = 0.5 * (pos + vec2(1, 1));
gl_Position = vec4(pos, 0, 1);
}

View File

@ -10,32 +10,32 @@ uniform sampler2D src;
vec2 u(ivec2 coord)
{
return(texelFetch(src, coord, 0).xy);
return (texelFetch(src, coord, 0).xy);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
if( pixelCoord.x <= 0
|| pixelCoord.x >= textureSize(src, 0).x
|| pixelCoord.y <= 0
|| pixelCoord.y >= textureSize(src, 0).y)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
vec2 tl = u(pixelCoord + ivec2(-1, 0));
vec2 tr = u(pixelCoord);
vec2 bl = u(pixelCoord + ivec2(-1, -1));
vec2 br = u(pixelCoord + ivec2(0, -1));
if(pixelCoord.x <= 0
|| pixelCoord.x >= textureSize(src, 0).x
|| pixelCoord.y <= 0
|| pixelCoord.y >= textureSize(src, 0).y)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
vec2 tl = u(pixelCoord + ivec2(-1, 0));
vec2 tr = u(pixelCoord);
vec2 bl = u(pixelCoord + ivec2(-1, -1));
vec2 br = u(pixelCoord + ivec2(0, -1));
float r = (tr.x + br.x)/2.;
float l = (tl.x + bl.x)/2.;
float t = (tl.y + tr.y)/2.;
float b = (bl.y + br.y)/2.;
float r = (tr.x + br.x) / 2.;
float l = (tl.x + bl.x) / 2.;
float t = (tl.y + tr.y) / 2.;
float b = (bl.y + br.y) / 2.;
fragColor = vec4(-2.*(r - l + t - b), 0, 0, 1);
}
fragColor = vec4(-2. * (r - l + t - b), 0, 0, 1);
}
}

View File

@ -11,45 +11,45 @@ uniform sampler2D bTex;
float x(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return(0.);
}
return(texelFetch(xTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return (0.);
}
return (texelFetch(xTex, coord, 0).x);
}
float b(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return(0.);
}
return(texelFetch(bTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return (0.);
}
return (texelFetch(bTex, coord, 0).x);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
if( pixelCoord.x <= 0
|| pixelCoord.y <= 0)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
float tl = x(pixelCoord + ivec2(-1, 1));
float tr = x(pixelCoord + ivec2(1, 1));
float bl = x(pixelCoord + ivec2(-1, -1));
float br = x(pixelCoord + ivec2(1, -1));
if(pixelCoord.x <= 0
|| pixelCoord.y <= 0)
{
fragColor = vec4(0, 0, 0, 1);
}
else
{
float tl = x(pixelCoord + ivec2(-1, 1));
float tr = x(pixelCoord + ivec2(1, 1));
float bl = x(pixelCoord + ivec2(-1, -1));
float br = x(pixelCoord + ivec2(1, -1));
float jacobi = (tl + tr + bl + br + b(pixelCoord))/4.;
fragColor = vec4(jacobi, 0, 0, 1);
}
float jacobi = (tl + tr + bl + br + b(pixelCoord)) / 4.;
fragColor = vec4(jacobi, 0, 0, 1);
}
}

View File

@ -12,42 +12,42 @@ uniform float invGridSize;
float e(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(error, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(error, 0).y)
{
return(0.);
}
return(texelFetch(error, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(error, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(error, 0).y)
{
return (0.);
}
return (texelFetch(error, coord, 0).x);
}
float p(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(src, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(src, 0).y)
{
return(0.);
}
return(texelFetch(src, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(src, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(src, 0).y)
{
return (0.);
}
return (texelFetch(src, coord, 0).x);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
vec2 coarseCoord = vec2(pixelCoord)/2.;
vec2 offset = fract(coarseCoord);
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
vec2 coarseCoord = vec2(pixelCoord) / 2.;
vec2 offset = fract(coarseCoord);
ivec2 bl = ivec2(floor(coarseCoord));
ivec2 br = bl + ivec2(1, 0);
ivec2 tl = bl + ivec2(0, 1);
ivec2 tr = bl + ivec2(1, 1);
ivec2 bl = ivec2(floor(coarseCoord));
ivec2 br = bl + ivec2(1, 0);
ivec2 tl = bl + ivec2(0, 1);
ivec2 tr = bl + ivec2(1, 1);
float topLerp = (1.-offset.x)*e(tl)+ offset.x*e(tr);
float bottomLerp = (1.-offset.x)*e(bl) + offset.x*e(br);
float bilerpError = (1.-offset.y)*bottomLerp + offset.y*topLerp;
float topLerp = (1. - offset.x) * e(tl) + offset.x * e(tr);
float bottomLerp = (1. - offset.x) * e(bl) + offset.x * e(br);
float bilerpError = (1. - offset.y) * bottomLerp + offset.y * topLerp;
fragColor = vec4(p(pixelCoord) + bilerpError, 0, 0, 1);
fragColor = vec4(p(pixelCoord) + bilerpError, 0, 0, 1);
}

View File

@ -11,51 +11,51 @@ uniform sampler2D bTex;
float x(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return(0.);
}
return(texelFetch(xTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y)
{
return (0.);
}
return (texelFetch(xTex, coord, 0).x);
}
float b(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return(0.);
}
return(texelFetch(bTex, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y)
{
return (0.);
}
return (texelFetch(bTex, coord, 0).x);
}
float residual(ivec2 coord)
{
ivec2 vr = coord + ivec2(1, 0);
ivec2 vl = coord - ivec2(1, 0);
ivec2 vt = coord + ivec2(0, 1);
ivec2 vb = coord - ivec2(0, 1);
ivec2 vr = coord + ivec2(1, 0);
ivec2 vl = coord - ivec2(1, 0);
ivec2 vt = coord + ivec2(0, 1);
ivec2 vb = coord - ivec2(0, 1);
return((x(vl) + x(vr) + x(vt) + x(vb) + b(coord) - 4.*x(coord))*4.);
return ((x(vl) + x(vr) + x(vt) + x(vb) + b(coord) - 4. * x(coord)) * 4.);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
float restricted = residual(2*pixelCoord + ivec2(-1, -1))
+ residual(2*pixelCoord + ivec2(1, -1))
+ residual(2*pixelCoord + ivec2(1, 1))
+ residual(2*pixelCoord + ivec2(-1, 1))
+ 2.*residual(2*pixelCoord + ivec2(-1, 0))
+ 2.*residual(2*pixelCoord + ivec2(1, 0))
+ 2.*residual(2*pixelCoord + ivec2(0, -1))
+ 2.*residual(2*pixelCoord + ivec2(0, 1))
+ 4.*residual(2*pixelCoord);
restricted /= 16.;
fragColor = vec4(restricted, 0, 0, 1);
float restricted = residual(2 * pixelCoord + ivec2(-1, -1))
+ residual(2 * pixelCoord + ivec2(1, -1))
+ residual(2 * pixelCoord + ivec2(1, 1))
+ residual(2 * pixelCoord + ivec2(-1, 1))
+ 2. * residual(2 * pixelCoord + ivec2(-1, 0))
+ 2. * residual(2 * pixelCoord + ivec2(1, 0))
+ 2. * residual(2 * pixelCoord + ivec2(0, -1))
+ 2. * residual(2 * pixelCoord + ivec2(0, 1))
+ 4. * residual(2 * pixelCoord);
restricted /= 16.;
fragColor = vec4(restricted, 0, 0, 1);
}

View File

@ -17,13 +17,13 @@ uniform float randomize;
void main()
{
float d2 = dot(texCoord - splatPos, texCoord - splatPos);
float intensity = exp(-10.*d2/radius);
vec2 force = splatColor.xy;
float d2 = dot(texCoord - splatPos, texCoord - splatPos);
float intensity = exp(-10. * d2 / radius);
vec2 force = splatColor.xy;
vec3 u = texture(src, texCoord).xyz;
vec3 uAdd = u + intensity*splatColor.xyz;
vec3 uBlend = u*(1.-intensity) + intensity * splatColor;
vec3 u = texture(src, texCoord).xyz;
vec3 uAdd = u + intensity * splatColor.xyz;
vec3 uBlend = u * (1. - intensity) + intensity * splatColor;
fragColor = vec4(uAdd*additive + uBlend*blending, 1);
fragColor = vec4(uAdd * additive + uBlend * blending, 1);
}

View File

@ -12,36 +12,36 @@ uniform float invGridSize;
vec2 u(ivec2 coord)
{
return(texelFetch(src, coord, 0).xy);
return (texelFetch(src, coord, 0).xy);
}
float p(ivec2 coord)
{
if( coord.x <= 0
|| coord.x >= textureSize(pressure, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(pressure, 0).y)
{
return(0.);
}
return(texelFetch(pressure, coord, 0).x);
if(coord.x <= 0
|| coord.x >= textureSize(pressure, 0).x
|| coord.y <= 0
|| coord.y >= textureSize(pressure, 0).y)
{
return (0.);
}
return (texelFetch(pressure, coord, 0).x);
}
void main()
{
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy));
float tl = p(pixelCoord + ivec2(0, 1));
float tr = p(pixelCoord + ivec2(1, 1));
float bl = p(pixelCoord);
float br = p(pixelCoord + ivec2(1, 0));
float tl = p(pixelCoord + ivec2(0, 1));
float tr = p(pixelCoord + ivec2(1, 1));
float bl = p(pixelCoord);
float br = p(pixelCoord + ivec2(1, 0));
float r = (tr + br)/2.;
float l = (tl + bl)/2.;
float t = (tl + tr)/2.;
float b = (bl + br)/2.;
float r = (tr + br) / 2.;
float l = (tl + bl) / 2.;
float t = (tl + tr) / 2.;
float b = (bl + br) / 2.;
vec2 gradP = vec2(r - l, t - b);
vec2 gradP = vec2(r - l, t - b);
fragColor = vec4(u(pixelCoord) - gradP, 0, 1);
fragColor = vec4(u(pixelCoord) - gradP, 0, 1);
}

View File

@ -2,37 +2,37 @@
#include <orca.h>
oc_vec2 frameSize = {100, 100};
oc_vec2 frameSize = { 100, 100 };
oc_surface surface;
unsigned int program;
const char* vshaderSource =
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
oc_log_info("gl error");
}
int err = glGetError();
if(err)
{
oc_log_info("gl error");
}
}
ORCA_EXPORT void oc_on_init(void)
@ -45,32 +45,32 @@ ORCA_EXPORT void oc_on_init(void)
int extensionCount = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
for(int i=0; i<extensionCount; i++)
for(int i = 0; i < extensionCount; i++)
{
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
oc_log_info("GLES extension %i: %s\n", i, extension);
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
oc_log_info("GLES extension %i: %s\n", i, extension);
}
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glUseProgram(program);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glUseProgram(program);
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
@ -85,22 +85,22 @@ ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
ORCA_EXPORT void oc_on_frame_refresh(void)
{
f32 aspect = frameSize.x/frameSize.y;
f32 aspect = frameSize.x / frameSize.y;
oc_surface_select(surface);
glClearColor(0, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
static float alpha = 0;
glViewport(0, 0, frameSize.x * 2, frameSize.y * 2);
glViewport(0, 0, frameSize.x * 2, frameSize.y * 2);
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
alpha += 2*M_PI/120;
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
alpha += 2 * M_PI / 120;
glUniformMatrix4fv(0, 1, false, matrix);

View File

@ -224,24 +224,24 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
switch(result)
{
case 1:
case 5:
velocity.y = -vy;
break;
case 3:
case 7:
velocity.x = -vx;
break;
case 2:
case 6:
velocity.x = -vy;
velocity.y = -vx;
break;
case 4:
case 8:
velocity.x = vy;
velocity.y = vx;
break;
case 1:
case 5:
velocity.y = -vy;
break;
case 3:
case 7:
velocity.x = -vx;
break;
case 2:
case 6:
velocity.x = -vy;
velocity.y = -vx;
break;
case 4:
case 8:
velocity.x = vy;
velocity.y = vx;
break;
}
}
}

View File

@ -1,400 +1,396 @@
#include"orca.h"
#include "orca.h"
oc_vec2 frameSize = {100, 100};
oc_vec2 frameSize = { 100, 100 };
oc_surface surface;
oc_canvas canvas;
oc_font font;
oc_ui_context ui;
oc_arena textArena = {0};
oc_arena textArena = { 0 };
ORCA_EXPORT void oc_on_init(void)
{
surface = oc_surface_canvas();
canvas = oc_canvas_create();
oc_ui_init(&ui);
surface = oc_surface_canvas();
canvas = oc_canvas_create();
oc_ui_init(&ui);
//NOTE: load font
{
oc_file file = oc_file_open(OC_STR8("/OpenSansLatinSubset.ttf"), OC_FILE_ACCESS_READ, 0);
if(oc_file_last_error(file) != OC_IO_OK)
{
oc_log_error("Couldn't open file OpenSansLatinSubset.ttf\n");
}
u64 size = oc_file_size(file);
char* buffer = oc_arena_push(oc_scratch(), size);
oc_file_read(file, size, buffer);
oc_file_close(file);
oc_unicode_range ranges[5] = {OC_UNICODE_BASIC_LATIN,
OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
OC_UNICODE_LATIN_EXTENDED_A,
OC_UNICODE_LATIN_EXTENDED_B,
OC_UNICODE_SPECIALS};
// TODO: Decide whether we're using strings or explicit pointer + length
font = oc_font_create_from_memory(oc_str8_from_buffer(size, buffer), 5, ranges);
}
//NOTE: load font
{
oc_file file = oc_file_open(OC_STR8("/OpenSansLatinSubset.ttf"), OC_FILE_ACCESS_READ, 0);
if(oc_file_last_error(file) != OC_IO_OK)
{
oc_log_error("Couldn't open file OpenSansLatinSubset.ttf\n");
}
u64 size = oc_file_size(file);
char* buffer = oc_arena_push(oc_scratch(), size);
oc_file_read(file, size, buffer);
oc_file_close(file);
oc_unicode_range ranges[5] = { OC_UNICODE_BASIC_LATIN,
OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
OC_UNICODE_LATIN_EXTENDED_A,
OC_UNICODE_LATIN_EXTENDED_B,
OC_UNICODE_SPECIALS };
// TODO: Decide whether we're using strings or explicit pointer + length
font = oc_font_create_from_memory(oc_str8_from_buffer(size, buffer), 5, ranges);
}
oc_arena_clear(oc_scratch());
oc_arena_init(&textArena);
oc_arena_clear(oc_scratch());
oc_arena_init(&textArena);
}
ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
{
oc_log_info("frame resize %u, %u", width, height);
frameSize.x = width;
frameSize.y = height;
oc_log_info("frame resize %u, %u", width, height);
frameSize.x = width;
frameSize.y = height;
}
ORCA_EXPORT void oc_on_raw_event(oc_event *event)
ORCA_EXPORT void oc_on_raw_event(oc_event* event)
{
oc_ui_process_event(event);
oc_ui_process_event(event);
}
void widget_begin_view(char* str)
{
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_Y,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START},
OC_UI_STYLE_LAYOUT);
oc_ui_box_begin(str, OC_UI_FLAG_DRAW_BORDER);
oc_ui_label(str);
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_Y,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START },
OC_UI_STYLE_LAYOUT);
oc_ui_box_begin(str, OC_UI_FLAG_DRAW_BORDER);
oc_ui_label(str);
}
void widget_end_view(void)
{
oc_ui_box_end();
oc_ui_box_end();
}
#define widget_view(s) oc_defer_loop(widget_begin_view(s), widget_end_view())
ORCA_EXPORT void oc_on_frame_refresh(void)
{
oc_ui_style defaultStyle = {.bgColor = {0},
.color = {1, 1, 1, 1},
.font = font,
.fontSize = 16,
.borderColor = {0.278, 0.333, 0.412, 1},
.borderSize = 2};
oc_ui_style defaultStyle = { .bgColor = { 0 },
.color = { 1, 1, 1, 1 },
.font = font,
.fontSize = 16,
.borderColor = { 0.278, 0.333, 0.412, 1 },
.borderSize = 2 };
oc_ui_style_mask defaultMask = OC_UI_STYLE_BG_COLOR
| OC_UI_STYLE_COLOR
| OC_UI_STYLE_BORDER_COLOR
| OC_UI_STYLE_BORDER_SIZE
| OC_UI_STYLE_FONT
| OC_UI_STYLE_FONT_SIZE;
oc_ui_style_mask defaultMask = OC_UI_STYLE_BG_COLOR
| OC_UI_STYLE_COLOR
| OC_UI_STYLE_BORDER_COLOR
| OC_UI_STYLE_BORDER_SIZE
| OC_UI_STYLE_FONT
| OC_UI_STYLE_FONT_SIZE;
oc_ui_frame(frameSize, &defaultStyle, defaultMask)
{
oc_ui_style_match_before(oc_ui_pattern_all(), &defaultStyle, defaultMask);
oc_ui_frame(frameSize, &defaultStyle, defaultMask)
{
oc_ui_style_match_before(oc_ui_pattern_all(), &defaultStyle, defaultMask);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 1},
.layout.axis = OC_UI_AXIS_Y,
.layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.bgColor = {0.11, 0.11, 0.11, 1}},
OC_UI_STYLE_SIZE
| OC_UI_STYLE_LAYOUT
| OC_UI_STYLE_BG_COLOR);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 1 },
.layout.axis = OC_UI_AXIS_Y,
.layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.bgColor = { 0.11, 0.11, 0.11, 1 } },
OC_UI_STYLE_SIZE
| OC_UI_STYLE_LAYOUT
| OC_UI_STYLE_BG_COLOR);
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_CHILDREN},
.layout.align.x = OC_UI_ALIGN_CENTER},
OC_UI_STYLE_SIZE
|OC_UI_STYLE_LAYOUT_ALIGN_X);
oc_ui_container("title", 0)
{
oc_ui_style_next(&(oc_ui_style){.fontSize = 26}, OC_UI_STYLE_FONT_SIZE);
oc_ui_label("Orca UI Demo");
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_CHILDREN },
.layout.align.x = OC_UI_ALIGN_CENTER },
OC_UI_STYLE_SIZE
| OC_UI_STYLE_LAYOUT_ALIGN_X);
oc_ui_container("title", 0)
{
oc_ui_style_next(&(oc_ui_style){ .fontSize = 26 }, OC_UI_STYLE_FONT_SIZE);
oc_ui_label("Orca UI Demo");
if(oc_ui_box_sig(oc_ui_box_top()).hovering)
{
oc_ui_tooltip("tooltip")
{
oc_ui_style_next(&(oc_ui_style){.bgColor = {1, 0.99, 0.82, 1}},
OC_UI_STYLE_BG_COLOR);
if(oc_ui_box_sig(oc_ui_box_top()).hovering)
{
oc_ui_tooltip("tooltip")
{
oc_ui_style_next(&(oc_ui_style){ .bgColor = { 1, 0.99, 0.82, 1 } },
OC_UI_STYLE_BG_COLOR);
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{
oc_ui_style_next(&(oc_ui_style){.color = {0, 0, 0, 1}},
OC_UI_STYLE_COLOR);
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{
oc_ui_style_next(&(oc_ui_style){ .color = { 0, 0, 0, 1 } },
OC_UI_STYLE_COLOR);
oc_ui_label("That is a tooltip!");
}
}
}
}
oc_ui_label("That is a tooltip!");
}
}
}
}
oc_ui_menu_bar("Menu bar")
{
oc_ui_menu("Menu 1")
{
if(oc_ui_menu_button("Option 1.1").pressed)
{
oc_log_info("Pressed option 1.1\n");
}
oc_ui_menu_button("Option 1.2");
oc_ui_menu_button("Option 1.3");
oc_ui_menu_button("Option 1.4");
}
oc_ui_menu_bar("Menu bar")
{
oc_ui_menu("Menu 1")
{
if(oc_ui_menu_button("Option 1.1").pressed)
{
oc_log_info("Pressed option 1.1\n");
}
oc_ui_menu_button("Option 1.2");
oc_ui_menu_button("Option 1.3");
oc_ui_menu_button("Option 1.4");
}
oc_ui_menu("Menu 2")
{
oc_ui_menu_button("Option 2.1");
oc_ui_menu_button("Option 2.2");
oc_ui_menu_button("Option 2.3");
oc_ui_menu_button("Option 2.4");
}
oc_ui_menu("Menu 2")
{
oc_ui_menu_button("Option 2.1");
oc_ui_menu_button("Option 2.2");
oc_ui_menu_button("Option 2.3");
oc_ui_menu_button("Option 2.4");
}
oc_ui_menu("Menu 3")
{
oc_ui_menu_button("Option 3.1");
oc_ui_menu_button("Option 3.2");
oc_ui_menu_button("Option 3.3");
oc_ui_menu_button("Option 3.4");
}
}
oc_ui_menu("Menu 3")
{
oc_ui_menu_button("Option 3.1");
oc_ui_menu_button("Option 3.2");
oc_ui_menu_button("Option 3.3");
oc_ui_menu_button("Option 3.4");
}
}
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 1, 1}},
OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 1, 1 } },
OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X}, OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5},
.size.height = {OC_UI_SIZE_PARENT, 1}},
OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X }, OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE);
oc_ui_container("left", 0)
{
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.5}},
OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_LAYOUT_SPACING
|OC_UI_STYLE_LAYOUT_MARGIN_X
|OC_UI_STYLE_LAYOUT_MARGIN_Y
|OC_UI_STYLE_SIZE);
oc_ui_container("left", 0)
{
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10,
.layout.margin.x = 10,
.layout.margin.y = 10,
.size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.5 } },
OC_UI_STYLE_LAYOUT_AXIS
| OC_UI_STYLE_LAYOUT_SPACING
| OC_UI_STYLE_LAYOUT_MARGIN_X
| OC_UI_STYLE_LAYOUT_MARGIN_Y
| OC_UI_STYLE_SIZE);
oc_ui_container("up", 0)
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5},
.size.height = {OC_UI_SIZE_PARENT, 1}},
OC_UI_STYLE_SIZE);
widget_view("Buttons")
{
if(oc_ui_button("Button A").clicked)
{
oc_log_info("A clicked");
}
oc_ui_container("up", 0)
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE);
widget_view("Buttons")
{
if(oc_ui_button("Button A").clicked)
{
oc_log_info("A clicked");
}
if(oc_ui_button("Button B").clicked)
{
oc_log_info("B clicked");
}
if(oc_ui_button("Button B").clicked)
{
oc_log_info("B clicked");
}
if(oc_ui_button("Button C").clicked)
{
oc_log_info("C clicked");
}
}
if(oc_ui_button("Button C").clicked)
{
oc_log_info("C clicked");
}
}
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5},
.size.height = {OC_UI_SIZE_PARENT, 1}},
OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE);
oc_ui_pattern pattern = { 0 };
oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_TAG, .tag = oc_ui_tag_make("checkbox") });
oc_ui_style_match_after(pattern,
&(oc_ui_style){ .bgColor = { 0, 1, 0, 1 },
.color = { 1, 1, 1, 1 } },
OC_UI_STYLE_COLOR | OC_UI_STYLE_BG_COLOR);
oc_ui_pattern pattern = {0};
oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){.kind = OC_UI_SEL_TAG, .tag = oc_ui_tag_make("checkbox")});
oc_ui_style_match_after(pattern,
&(oc_ui_style){.bgColor = {0, 1, 0, 1},
.color = {1, 1, 1, 1}},
OC_UI_STYLE_COLOR | OC_UI_STYLE_BG_COLOR);
widget_view("checkboxes")
{
static bool check1 = true;
static bool check2 = false;
static bool check3 = false;
widget_view("checkboxes")
{
static bool check1 = true;
static bool check2 = false;
static bool check3 = false;
oc_ui_checkbox("check1", &check1);
oc_ui_checkbox("check2", &check2);
oc_ui_checkbox("check3", &check3);
}
}
oc_ui_checkbox("check1", &check1);
oc_ui_checkbox("check2", &check2);
oc_ui_checkbox("check3", &check3);
}
}
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.5 } },
OC_UI_STYLE_LAYOUT_AXIS
| OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X,
.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.5}},
OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_SIZE);
oc_ui_container("down", 0)
{
widget_view("Vertical Sliders")
{
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10 },
OC_UI_STYLE_LAYOUT_AXIS
| OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE);
static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1);
oc_ui_container("down", 0)
{
widget_view("Vertical Sliders")
{
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10},
OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20},
.size.height = {OC_UI_SIZE_PIXELS, 200}},
OC_UI_STYLE_SIZE);
static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE);
static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20},
.size.height = {OC_UI_SIZE_PIXELS, 200}},
OC_UI_STYLE_SIZE);
static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE);
static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3);
}
}
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20},
.size.height = {OC_UI_SIZE_PIXELS, 200}},
OC_UI_STYLE_SIZE);
static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3);
}
}
widget_view("Horizontal Sliders")
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE);
static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1);
widget_view("Horizontal Sliders")
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200},
.size.height = {OC_UI_SIZE_PIXELS, 20}},
OC_UI_STYLE_SIZE);
static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE);
static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200},
.size.height = {OC_UI_SIZE_PIXELS, 20}},
OC_UI_STYLE_SIZE);
static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE);
static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3);
}
}
}
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200},
.size.height = {OC_UI_SIZE_PIXELS, 20}},
OC_UI_STYLE_SIZE);
static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3);
}
}
}
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5},
.size.height = {OC_UI_SIZE_PARENT, 1}},
OC_UI_STYLE_SIZE);
oc_ui_container("right", 0)
{
oc_ui_container("right", 0)
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE);
widget_view("Text box")
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 300 },
.size.height = { OC_UI_SIZE_TEXT } },
OC_UI_STYLE_SIZE);
static oc_str8 text = { 0 };
oc_ui_text_box_result res = oc_ui_text_box("textbox", oc_scratch(), text);
if(res.changed)
{
oc_arena_clear(&textArena);
text = oc_str8_push_copy(&textArena, res.text);
}
}
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.33}},
OC_UI_STYLE_SIZE);
widget_view("Text box")
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 300},
.size.height = {OC_UI_SIZE_TEXT}},
OC_UI_STYLE_SIZE);
static oc_str8 text = {0};
oc_ui_text_box_result res = oc_ui_text_box("textbox", oc_scratch(), text);
if(res.changed)
{
oc_arena_clear(&textArena);
text = oc_str8_push_copy(&textArena, res.text);
}
}
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE);
widget_view("Test")
{
oc_ui_pattern pattern = { 0 };
oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_TEXT, .text = OC_STR8("panel") });
oc_ui_style_match_after(pattern, &(oc_ui_style){ .bgColor = { 0.3, 0.3, 1, 1 } }, OC_UI_STYLE_BG_COLOR);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.33}},
OC_UI_STYLE_SIZE);
widget_view("Test")
{
oc_ui_pattern pattern = {0};
oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){.kind = OC_UI_SEL_TEXT, .text = OC_STR8("panel")});
oc_ui_style_match_after(pattern, &(oc_ui_style){.bgColor = {0.3, 0.3, 1, 1}}, OC_UI_STYLE_BG_COLOR);
static int selected = 0;
oc_str8 options[] = { OC_STR8("option 1"),
OC_STR8("option 2"),
OC_STR8("long option 3"),
OC_STR8("option 4"),
OC_STR8("option 5") };
oc_ui_select_popup_info info = { .selectedIndex = selected,
.optionCount = 5,
.options = options };
static int selected = 0;
oc_str8 options[] = {OC_STR8("option 1"),
OC_STR8("option 2"),
OC_STR8("long option 3"),
OC_STR8("option 4"),
OC_STR8("option 5")};
oc_ui_select_popup_info info = {.selectedIndex = selected,
.optionCount = 5,
.options = options};
oc_ui_select_popup_info result = oc_ui_select_popup("popup", &info);
selected = result.selectedIndex;
}
oc_ui_select_popup_info result = oc_ui_select_popup("popup", &info);
selected = result.selectedIndex;
}
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE);
widget_view("Color")
{
oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = { OC_UI_SIZE_PARENT, 0.7 },
.layout.axis = OC_UI_AXIS_X },
OC_UI_STYLE_SIZE
| OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.33}},
OC_UI_STYLE_SIZE);
widget_view("Color")
{
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1},
.size.height = {OC_UI_SIZE_PARENT, 0.7},
.layout.axis = OC_UI_AXIS_X},
OC_UI_STYLE_SIZE
|OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_panel("Panel", OC_UI_FLAG_DRAW_BORDER)
{
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X },
OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){ .layout.spacing = 20 },
OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("buttons", 0)
{
oc_ui_button("Button A");
oc_ui_button("Button B");
oc_ui_button("Button C");
oc_ui_button("Button D");
}
oc_ui_panel("Panel", OC_UI_FLAG_DRAW_BORDER)
{
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X},
OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("contents", 0)
{
oc_ui_style_next(&(oc_ui_style){.layout.spacing = 20},
OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("buttons", 0)
{
oc_ui_button("Button A");
oc_ui_button("Button B");
oc_ui_button("Button C");
oc_ui_button("Button D");
}
oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 20 },
OC_UI_STYLE_LAYOUT_SPACING
| OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X,
.layout.spacing = 20},
OC_UI_STYLE_LAYOUT_SPACING
|OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("buttons2", 0)
{
oc_ui_button("Button A");
oc_ui_button("Button B");
oc_ui_button("Button C");
oc_ui_button("Button D");
}
}
}
}
}
}
}
}
oc_ui_container("buttons2", 0)
{
oc_ui_button("Button A");
oc_ui_button("Button B");
oc_ui_button("Button C");
oc_ui_button("Button D");
}
}
}
}
}
}
}
}
oc_canvas_set_current(canvas);
oc_canvas_set_current(canvas);
oc_surface_select(surface);
oc_ui_draw();
oc_ui_draw();
oc_render(surface, canvas);
oc_surface_present(surface);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,101 +6,102 @@
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#include"milepost.h"
#include "milepost.h"
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
//NOTE: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
log_error("Error: couldn't create canvas\n");
return(-1);
}
//NOTE: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
log_error("Error: couldn't create canvas\n");
return (-1);
}
//NOTE: create atlas
mem_arena permanentArena = {0};
mem_arena_init(&permanentArena);
//NOTE: create atlas
mem_arena permanentArena = { 0 };
mem_arena_init(&permanentArena);
mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000);
mg_image atlasImage = mg_image_create(surface, 16000, 16000);
mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000);
mg_image atlasImage = mg_image_create(surface, 16000, 16000);
str8 path1 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png"));
str8 path2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png"));
str8 path1 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png"));
str8 path2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png"));
mg_image_region image1 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path1, false);
mg_image_region image2 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path2, false);
mg_image_region image1 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path1, false);
mg_image_region image2 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path2, false);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_prepare(surface);
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(1, 1, 1, 1);
mg_set_color_rgba(1, 1, 1, 1);
mg_image_draw_region(image1.image, image1.rect, (mp_rect){100, 100, 300, 300});
mg_image_draw_region(image2.image, image2.rect, (mp_rect){300, 200, 300, 300});
mg_image_draw_region(image1.image, image1.rect, (mp_rect){ 100, 100, 300, 300 });
mg_image_draw_region(image2.image, image2.rect, (mp_rect){ 300, 200, 300, 300 });
mg_render(surface, canvas);
mg_surface_present(surface);
mg_render(surface, canvas);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
}
mem_arena_clear(mem_scratch());
}
mg_image_atlas_recycle(atlas, image1);
mg_image_atlas_recycle(atlas, image2);
mg_image_atlas_recycle(atlas, image1);
mg_image_atlas_recycle(atlas, image2);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -1,218 +1,219 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
* @date: 30/07/2022
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include"milepost.h"
#define LOG_SUBSYSTEM "Main"
mg_font create_font()
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf"));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS};
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return(font);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return(-1);
}
mg_font font = create_font();
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
f32 x = 400, y = 300;
f32 speed = 0;
f32 dx = speed, dy = speed;
f64 frameTime = 0;
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT)
{
f32 factor = (event->key.mods & MP_KEYMOD_SHIFT) ? 10 : 1;
if(event->key.code == MP_KEY_LEFT)
{
x-=0.3*factor;
}
else if(event->key.code == MP_KEY_RIGHT)
{
x+=0.3*factor;
}
else if(event->key.code == MP_KEY_UP)
{
y-=0.3*factor;
}
else if(event->key.code == MP_KEY_DOWN)
{
y+=0.3*factor;
}
}
} break;
default:
break;
}
}
if(x-200 < 0)
{
x = 200;
dx = speed;
}
if(x+200 > contentRect.w)
{
x = contentRect.w - 200;
dx = -speed;
}
if(y-200 < 0)
{
y = 200;
dy = speed;
}
if(y+200 > contentRect.h)
{
y = contentRect.h - 200;
dy = -speed;
}
x += dx;
y += dy;
// background
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(1, 0, 1, 1);
mg_rectangle_fill(0, 0, 100, 100);
// head
mg_set_color_rgba(1, 1, 0, 1);
mg_circle_fill(x, y, 200);
// smile
f32 frown = frameTime > 0.033 ? -100 : 0;
mg_set_color_rgba(0, 0, 0, 1);
mg_set_width(20);
mg_move_to(x-100, y+100);
mg_cubic_to(x-50, y+150+frown, x+50, y+150+frown, x+100, y+100);
mg_stroke();
// eyes
mg_ellipse_fill(x-70, y-50, 30, 50);
mg_ellipse_fill(x+70, y-50, 30, 50);
// text
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font);
mg_set_font_size(12);
mg_move_to(50, 600-50);
str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime,
1./frameTime);
mg_text_outlines(text);
mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1./frameTime);
mg_surface_prepare(surface);
mg_render(surface, canvas);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mg_font_destroy(font);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return(0);
}
*****************************************************************/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include <math.h>
#include "milepost.h"
#define LOG_SUBSYSTEM "Main"
mg_font create_font()
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf"));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return (mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return (font);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return (-1);
}
mg_font font = create_font();
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
f32 x = 400, y = 300;
f32 speed = 0;
f32 dx = speed, dy = speed;
f64 frameTime = 0;
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT)
{
f32 factor = (event->key.mods & MP_KEYMOD_SHIFT) ? 10 : 1;
if(event->key.code == MP_KEY_LEFT)
{
x -= 0.3 * factor;
}
else if(event->key.code == MP_KEY_RIGHT)
{
x += 0.3 * factor;
}
else if(event->key.code == MP_KEY_UP)
{
y -= 0.3 * factor;
}
else if(event->key.code == MP_KEY_DOWN)
{
y += 0.3 * factor;
}
}
}
break;
default:
break;
}
}
if(x - 200 < 0)
{
x = 200;
dx = speed;
}
if(x + 200 > contentRect.w)
{
x = contentRect.w - 200;
dx = -speed;
}
if(y - 200 < 0)
{
y = 200;
dy = speed;
}
if(y + 200 > contentRect.h)
{
y = contentRect.h - 200;
dy = -speed;
}
x += dx;
y += dy;
// background
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(1, 0, 1, 1);
mg_rectangle_fill(0, 0, 100, 100);
// head
mg_set_color_rgba(1, 1, 0, 1);
mg_circle_fill(x, y, 200);
// smile
f32 frown = frameTime > 0.033 ? -100 : 0;
mg_set_color_rgba(0, 0, 0, 1);
mg_set_width(20);
mg_move_to(x - 100, y + 100);
mg_cubic_to(x - 50, y + 150 + frown, x + 50, y + 150 + frown, x + 100, y + 100);
mg_stroke();
// eyes
mg_ellipse_fill(x - 70, y - 50, 30, 50);
mg_ellipse_fill(x + 70, y - 50, 30, 50);
// text
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font);
mg_set_font_size(12);
mg_move_to(50, 600 - 50);
str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime,
1. / frameTime);
mg_text_outlines(text);
mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1. / frameTime);
mg_surface_prepare(surface);
mg_render(surface, canvas);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mg_font_destroy(font);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return (0);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,81 +6,82 @@
* @revision:
*
*****************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#include"milepost.h"
#include "milepost.h"
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
//NOTE: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return(-1);
}
//NOTE: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return (-1);
}
//NOTE: create image
str8 imagePath = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png"));
mg_image image = mg_image_create_from_file(surface, imagePath, false);
vec2 imageSize = mg_image_size(image);
//NOTE: create image
str8 imagePath = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png"));
mg_image image = mg_image_create_from_file(surface, imagePath, false);
vec2 imageSize = mg_image_size(image);
str8 imagePath2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png"));
mg_image image2 = mg_image_create_from_file(surface, imagePath2, false);
vec2 imageSize2 = mg_image_size(image2);
str8 imagePath2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png"));
mg_image image2 = mg_image_create_from_file(surface, imagePath2, false);
vec2 imageSize2 = mg_image_size(image2);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_prepare(surface);
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_set_color_rgba(1, 1, 1, 1);
/*
mg_set_color_rgba(1, 1, 1, 1);
/*
mg_matrix_push((mg_mat2x3){0.707, -0.707, 200,
0.707, 0.707, 100});
mg_set_image(image);
@ -99,23 +100,21 @@ int main()
mg_image_draw(image2, (mp_rect){300, 200, 300, 300});
*/
mg_image_draw(image, (mp_rect){100, 100, 300, 300});
mg_image_draw(image2, (mp_rect){300, 200, 300, 300});
mg_image_draw(image, (mp_rect){ 100, 100, 300, 300 });
mg_image_draw(image2, (mp_rect){ 300, 200, 300, 300 });
mg_render(surface, canvas);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
}
mg_render(surface, canvas);
mg_surface_present(surface);
mg_image_destroy(image);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mem_arena_clear(mem_scratch());
}
mp_terminate();
mg_image_destroy(image);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return(0);
return (0);
}

View File

@ -1,114 +1,115 @@
#include<stdlib.h>
#include<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#define MG_INCLUDE_GL_API 1
#include"milepost.h"
#include "milepost.h"
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface1 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface1))
{
printf("Error: couldn't create surface 1\n");
return(-1);
}
mg_surface_swap_interval(surface1, 0);
//*
mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface2))
{
printf("Error: couldn't create surface 2\n");
return(-1);
}
mg_surface_swap_interval(surface2, 0);
//*/
mg_canvas canvas1 = mg_canvas_create();
if(mg_canvas_is_nil(canvas1))
{
printf("Error: couldn't create canvas 1\n");
return(-1);
}
//*
mg_canvas canvas2 = mg_canvas_create();
if(mg_canvas_is_nil(canvas2))
{
printf("Error: couldn't create canvas 2\n");
return(-1);
}
//*/
// start app
mp_window_center(window);
mp_window_bring_to_front(window);
mp_window_focus(window);
//NOTE: create surface
mg_surface surface1 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface1))
{
printf("Error: couldn't create surface 1\n");
return (-1);
}
mg_surface_swap_interval(surface1, 0);
//*
mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface2))
{
printf("Error: couldn't create surface 2\n");
return (-1);
}
mg_surface_swap_interval(surface2, 0);
//*/
mg_canvas canvas1 = mg_canvas_create();
if(mg_canvas_is_nil(canvas1))
{
printf("Error: couldn't create canvas 1\n");
return (-1);
}
//*
mg_canvas canvas2 = mg_canvas_create();
if(mg_canvas_is_nil(canvas2))
{
printf("Error: couldn't create canvas 2\n");
return (-1);
}
//*/
// start app
mp_window_center(window);
mp_window_bring_to_front(window);
mp_window_focus(window);
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface1);
mg_canvas_set_current(canvas1);
mg_surface_prepare(surface1);
mg_canvas_set_current(canvas1);
mg_set_color_rgba(0, 0, 0.5, 0.5);
mg_clear();
mg_set_color_rgba(0, 0, 0.5, 0.5);
mg_clear();
mg_set_color_rgba(1, 0, 0, 1);
mg_rectangle_fill(100, 100, 300, 150);
mg_set_color_rgba(1, 0, 0, 1);
mg_rectangle_fill(100, 100, 300, 150);
mg_render(surface1, canvas1);
mg_render(surface1, canvas1);
//*
mg_surface_prepare(surface2);
mg_canvas_set_current(canvas2);
//*
mg_surface_prepare(surface2);
mg_canvas_set_current(canvas2);
mg_set_color_rgba(0, 0, 0, 0);
mg_clear();
mg_set_color_rgba(0, 0, 0, 0);
mg_clear();
mg_set_color_rgba(0, 0, 1, 1);
mg_rectangle_fill(300, 300, 300, 200);
mg_set_color_rgba(0, 0, 1, 1);
mg_rectangle_fill(300, 300, 300, 200);
mg_render(surface2, canvas2);
//*/
mg_render(surface2, canvas2);
//*/
mg_surface_present(surface1);
mg_surface_present(surface2);
mg_surface_present(surface1);
mg_surface_present(surface2);
mem_arena_clear(mem_scratch());
}
mem_arena_clear(mem_scratch());
}
mg_canvas_destroy(canvas1);
mg_surface_destroy(surface1);
mg_canvas_destroy(canvas2);
mg_surface_destroy(surface2);
mg_canvas_destroy(canvas1);
mg_surface_destroy(surface1);
mg_canvas_destroy(canvas2);
mg_surface_destroy(surface2);
mp_window_destroy(window);
mp_window_destroy(window);
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -1,237 +1,243 @@
#include<stdio.h>
#include<stdlib.h>
#define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE
#define LOG_COMPILE_DEBUG
#include"milepost.h"
#define LOG_SUBSYSTEM "Main"
static const char* TEST_STRING =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam enim, aliquam in placerat luctus, rutrum in quam. "
"Cras urna elit, pellentesque ac ipsum at, lobortis scelerisque eros. Aenean et turpis nibh. Maecenas lectus augue, eleifend "
"nec efficitur eu, faucibus eget turpis. Suspendisse vel nulla mi. Duis imperdiet neque orci, ac ultrices orci molestie a. "
"Etiam malesuada vulputate hendrerit. Cras ultricies diam in lectus finibus, eu laoreet diam rutrum.\n"
"\n"
"Etiam dictum orci arcu, ac fermentum leo dapibus lacinia. Integer vitae elementum ex. Vestibulum tempor nunc eu hendrerit "
"ornare. Nunc pretium ligula sit amet massa pulvinar, vitae imperdiet justo bibendum. Maecenas consectetur elementum mi, sed "
"vehicula neque pulvinar sit amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tortor erat, accumsan in laoreet "
"quis, placerat nec enim. Nulla facilisi. Morbi vitae nibh ligula. Suspendisse in molestie magna, eget aliquet mauris. Sed "
"aliquam faucibus magna.\n"
"\n"
"Sed metus odio, imperdiet et consequat non, faucibus nec risus. Suspendisse facilisis sem neque, id scelerisque dui mattis sit "
"amet. Nullam tincidunt nisl nec dui dignissim mattis. Proin fermentum ornare ipsum. Proin eleifend, mi vitae porttitor placerat, "
"neque magna elementum turpis, eu aliquet mi urna et leo. Pellentesque interdum est mauris, sed pellentesque risus blandit in. "
"Phasellus dignissim consequat eros, at aliquam elit finibus posuere. Proin suscipit tortor leo, id vulputate odio lobortis in. "
"Vestibulum et orci ligula. Sed scelerisque nunc non nisi aliquam, vel eleifend felis suscipit. Integer posuere sapien elit, "
"lacinia ultricies nibh sodales nec.\n"
"\n"
"Etiam aliquam purus sit amet purus ultricies tristique. Nunc maximus nunc quis magna ornare, vel interdum urna fermentum. "
"Vestibulum cursus nisl ut nulla egestas, quis mattis elit venenatis. Praesent malesuada mi non magna aliquam fringilla eget eu "
"turpis. Integer suscipit elit vel consectetur vulputate. Integer euismod, erat eget elementum tempus, magna metus consectetur "
"elit, sed feugiat urna sapien sodales sapien. Sed sit amet varius nunc. Curabitur sodales nunc justo, ac scelerisque ipsum semper "
"eget. Integer ornare, velit ut hendrerit dapibus, erat mauris commodo justo, vel semper urna justo non mauris. Proin blandit, "
"enim ut posuere placerat, leo nibh tristique eros, ut pulvinar sapien elit eget enim. Pellentesque et mauris lectus. Curabitur "
"quis lobortis leo, sit amet egestas dui. Nullam ut sapien eu justo lacinia ultrices. Ut tincidunt, sem non luctus tempus, felis "
"purus imperdiet nisi, non ultricies libero ipsum eu augue. Mauris at luctus enim.\n"
"\n"
"Aliquam sed tortor a justo pulvinar dictum consectetur eu felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices "
"posuere cubilia curae; Etiam vehicula porttitor volutpat. Morbi fringilla tortor nec accumsan aliquet. Aliquam in commodo neque. "
"Sed laoreet tellus in consectetur aliquet. Nullam nibh eros, feugiat sit amet aliquam non, malesuada vel urna. Ut vel egestas nunc. "
"Pellentesque vitae ante quis ante pharetra pretium. Nam quis eros commodo, mattis enim sed, finibus ante. Quisque lacinia tortor ut "
"odio laoreet, vel viverra libero porttitor. Vestibulum vitae dapibus ex. Phasellus varius lorem sed justo sollicitudin faucibus. "
"Etiam aliquam lacinia consectetur. Phasellus nulla ipsum, viverra non nulla in, rhoncus posuere nunc.\n"
"\n"
"Phasellus efficitur commodo tellus, eget lobortis erat porta quis. Aenean condimentum tortor ut neque dapibus, vitae vulputate quam "
"condimentum. Aliquam elementum vitae nulla vitae tristique. Suspendisse feugiat turpis ac magna dapibus, ut blandit diam tincidunt. "
"Integer id dui id enim ullamcorper dictum. Maecenas malesuada vitae ex pharetra iaculis. Curabitur eu dolor consectetur, tempus augue "
"sed, finibus est. Nulla facilisi. Vivamus sed lacinia turpis, in gravida dolor. Aenean interdum consectetur enim a malesuada. Sed turpis "
"nisi, lacinia et fermentum nec, pharetra id dui. Vivamus neque ligula, iaculis sed tempor eget, vehicula blandit quam. Morbi rhoncus quam "
"semper magna mollis luctus. Donec eu dolor ut ante ullamcorper porta. Mauris et est tristique libero pharetra faucibus.\n"
"\n"
"Duis ut elementum sem. Praesent commodo erat nec sem ultricies sollicitudin. Suspendisse a pellentesque sapien. Nunc ac magna a dui "
"elementum luctus non a mi. Cras elementum nunc sed nunc gravida, sit amet accumsan tortor pulvinar. Etiam elit arcu, pellentesque non ex "
"id, vestibulum pellentesque velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque habitant morbi tristique senectus "
"et netus et malesuada fames ac turpis egestas. Proin sit amet velit eget tellus vulputate sagittis eget non massa. Cras accumsan tempor "
"tortor, quis rutrum neque placerat id. Nullam a egestas eros, eu porta nisi. Aenean rutrum, sapien quis fermentum tempus, dolor orci "
"faucibus eros, vel luctus justo leo vitae ante. Curabitur aliquam condimentum ipsum sit amet ultrices. Nullam ac velit semper, dapibus urna "
"sit amet, malesuada enim. Mauris ultricies nibh orci.";
mg_font create_font(const char* path)
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8(path));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s'\n", fontPathCString);
return(mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS};
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return(font);
}
enum { FONT_COUNT = 3 };
int main()
{
mp_init();
mp_clock_init();
mp_rect rect = {.x = 100, .y = 100, .w = 980, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface, canvas and font
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
mg_canvas canvas = mg_canvas_create();
int fontIndex = 0;
mg_font fonts[FONT_COUNT] = {create_font("../../resources/OpenSansLatinSubset.ttf"),
create_font("../../sketches/resources/CMUSerif-Roman.ttf"),
create_font("../../sketches/resources/Courier.ttf")};
mg_font_extents extents[FONT_COUNT];
f32 fontScales[FONT_COUNT];
f32 lineHeights[FONT_COUNT];
for(int i=0; i<FONT_COUNT; i++)
{
extents[i] = mg_font_get_extents(fonts[i]);
fontScales[i] = mg_font_get_scale_for_em_pixels(fonts[i], 14);
lineHeights[i] = fontScales[i]*(extents[i].ascent + extents[i].descent + extents[i].leading);
}
int codePointCount = utf8_codepoint_count_for_string(STR8((char*)TEST_STRING));
u32* codePoints = malloc_array(utf32, codePointCount);
utf8_to_codepoints(codePointCount, codePoints, STR8((char*)TEST_STRING));
u32 glyphCount = 0;
for(int i=0; i<codePointCount; i++)
{
if(codePoints[i] != ' ' && codePoints[i] != '\n')
{
glyphCount++;
}
}
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
f64 frameTime = 0;
bool tracked = false;
vec2 trackPoint = {0};
f32 zoom = 1;
f32 startX = 10;
f32 startY = 10 + lineHeights[fontIndex];
mp_input_state inputState = {0};
while(!mp_should_quit())
{
f64 startFrameTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
mp_input_process_event(&inputState, event);
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
case MP_EVENT_MOUSE_BUTTON:
{
if(event->key.code == MP_MOUSE_LEFT)
{
if(event->key.action == MP_KEY_PRESS)
{
tracked = true;
vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = mousePos.x/zoom - startX;
trackPoint.y = mousePos.y/zoom - startY;
}
else
{
tracked = false;
}
}
} break;
case MP_EVENT_MOUSE_WHEEL:
{
vec2 mousePos = mp_mouse_position(&inputState);
f32 trackX = mousePos.x/zoom - startX;
f32 trackY = mousePos.y/zoom - startY;
zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.2, 10);
startX = mousePos.x/zoom - trackX;
startY = mousePos.y/zoom - trackY;
} break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS)
{
fontIndex = (fontIndex+1)%FONT_COUNT;
}
} break;
default:
break;
}
}
if(tracked)
{
vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x/zoom - trackPoint.x;
startY = mousePos.y/zoom - trackPoint.y;
}
f32 textX = startX;
f32 textY = startY;
/*
#include <stdio.h>
#include <stdlib.h>
#define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE
#define LOG_COMPILE_DEBUG
#include "milepost.h"
#define LOG_SUBSYSTEM "Main"
static const char* TEST_STRING =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam enim, aliquam in placerat luctus, rutrum in quam. "
"Cras urna elit, pellentesque ac ipsum at, lobortis scelerisque eros. Aenean et turpis nibh. Maecenas lectus augue, eleifend "
"nec efficitur eu, faucibus eget turpis. Suspendisse vel nulla mi. Duis imperdiet neque orci, ac ultrices orci molestie a. "
"Etiam malesuada vulputate hendrerit. Cras ultricies diam in lectus finibus, eu laoreet diam rutrum.\n"
"\n"
"Etiam dictum orci arcu, ac fermentum leo dapibus lacinia. Integer vitae elementum ex. Vestibulum tempor nunc eu hendrerit "
"ornare. Nunc pretium ligula sit amet massa pulvinar, vitae imperdiet justo bibendum. Maecenas consectetur elementum mi, sed "
"vehicula neque pulvinar sit amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tortor erat, accumsan in laoreet "
"quis, placerat nec enim. Nulla facilisi. Morbi vitae nibh ligula. Suspendisse in molestie magna, eget aliquet mauris. Sed "
"aliquam faucibus magna.\n"
"\n"
"Sed metus odio, imperdiet et consequat non, faucibus nec risus. Suspendisse facilisis sem neque, id scelerisque dui mattis sit "
"amet. Nullam tincidunt nisl nec dui dignissim mattis. Proin fermentum ornare ipsum. Proin eleifend, mi vitae porttitor placerat, "
"neque magna elementum turpis, eu aliquet mi urna et leo. Pellentesque interdum est mauris, sed pellentesque risus blandit in. "
"Phasellus dignissim consequat eros, at aliquam elit finibus posuere. Proin suscipit tortor leo, id vulputate odio lobortis in. "
"Vestibulum et orci ligula. Sed scelerisque nunc non nisi aliquam, vel eleifend felis suscipit. Integer posuere sapien elit, "
"lacinia ultricies nibh sodales nec.\n"
"\n"
"Etiam aliquam purus sit amet purus ultricies tristique. Nunc maximus nunc quis magna ornare, vel interdum urna fermentum. "
"Vestibulum cursus nisl ut nulla egestas, quis mattis elit venenatis. Praesent malesuada mi non magna aliquam fringilla eget eu "
"turpis. Integer suscipit elit vel consectetur vulputate. Integer euismod, erat eget elementum tempus, magna metus consectetur "
"elit, sed feugiat urna sapien sodales sapien. Sed sit amet varius nunc. Curabitur sodales nunc justo, ac scelerisque ipsum semper "
"eget. Integer ornare, velit ut hendrerit dapibus, erat mauris commodo justo, vel semper urna justo non mauris. Proin blandit, "
"enim ut posuere placerat, leo nibh tristique eros, ut pulvinar sapien elit eget enim. Pellentesque et mauris lectus. Curabitur "
"quis lobortis leo, sit amet egestas dui. Nullam ut sapien eu justo lacinia ultrices. Ut tincidunt, sem non luctus tempus, felis "
"purus imperdiet nisi, non ultricies libero ipsum eu augue. Mauris at luctus enim.\n"
"\n"
"Aliquam sed tortor a justo pulvinar dictum consectetur eu felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices "
"posuere cubilia curae; Etiam vehicula porttitor volutpat. Morbi fringilla tortor nec accumsan aliquet. Aliquam in commodo neque. "
"Sed laoreet tellus in consectetur aliquet. Nullam nibh eros, feugiat sit amet aliquam non, malesuada vel urna. Ut vel egestas nunc. "
"Pellentesque vitae ante quis ante pharetra pretium. Nam quis eros commodo, mattis enim sed, finibus ante. Quisque lacinia tortor ut "
"odio laoreet, vel viverra libero porttitor. Vestibulum vitae dapibus ex. Phasellus varius lorem sed justo sollicitudin faucibus. "
"Etiam aliquam lacinia consectetur. Phasellus nulla ipsum, viverra non nulla in, rhoncus posuere nunc.\n"
"\n"
"Phasellus efficitur commodo tellus, eget lobortis erat porta quis. Aenean condimentum tortor ut neque dapibus, vitae vulputate quam "
"condimentum. Aliquam elementum vitae nulla vitae tristique. Suspendisse feugiat turpis ac magna dapibus, ut blandit diam tincidunt. "
"Integer id dui id enim ullamcorper dictum. Maecenas malesuada vitae ex pharetra iaculis. Curabitur eu dolor consectetur, tempus augue "
"sed, finibus est. Nulla facilisi. Vivamus sed lacinia turpis, in gravida dolor. Aenean interdum consectetur enim a malesuada. Sed turpis "
"nisi, lacinia et fermentum nec, pharetra id dui. Vivamus neque ligula, iaculis sed tempor eget, vehicula blandit quam. Morbi rhoncus quam "
"semper magna mollis luctus. Donec eu dolor ut ante ullamcorper porta. Mauris et est tristique libero pharetra faucibus.\n"
"\n"
"Duis ut elementum sem. Praesent commodo erat nec sem ultricies sollicitudin. Suspendisse a pellentesque sapien. Nunc ac magna a dui "
"elementum luctus non a mi. Cras elementum nunc sed nunc gravida, sit amet accumsan tortor pulvinar. Etiam elit arcu, pellentesque non ex "
"id, vestibulum pellentesque velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque habitant morbi tristique senectus "
"et netus et malesuada fames ac turpis egestas. Proin sit amet velit eget tellus vulputate sagittis eget non massa. Cras accumsan tempor "
"tortor, quis rutrum neque placerat id. Nullam a egestas eros, eu porta nisi. Aenean rutrum, sapien quis fermentum tempus, dolor orci "
"faucibus eros, vel luctus justo leo vitae ante. Curabitur aliquam condimentum ipsum sit amet ultrices. Nullam ac velit semper, dapibus urna "
"sit amet, malesuada enim. Mauris ultricies nibh orci.";
mg_font create_font(const char* path)
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8(path));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s'\n", fontPathCString);
return (mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return (font);
}
enum
{
FONT_COUNT = 3
};
int main()
{
mp_init();
mp_clock_init();
mp_rect rect = { .x = 100, .y = 100, .w = 980, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface, canvas and font
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("couldn't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
mg_canvas canvas = mg_canvas_create();
int fontIndex = 0;
mg_font fonts[FONT_COUNT] = { create_font("../../resources/OpenSansLatinSubset.ttf"),
create_font("../../sketches/resources/CMUSerif-Roman.ttf"),
create_font("../../sketches/resources/Courier.ttf") };
mg_font_extents extents[FONT_COUNT];
f32 fontScales[FONT_COUNT];
f32 lineHeights[FONT_COUNT];
for(int i = 0; i < FONT_COUNT; i++)
{
extents[i] = mg_font_get_extents(fonts[i]);
fontScales[i] = mg_font_get_scale_for_em_pixels(fonts[i], 14);
lineHeights[i] = fontScales[i] * (extents[i].ascent + extents[i].descent + extents[i].leading);
}
int codePointCount = utf8_codepoint_count_for_string(STR8((char*)TEST_STRING));
u32* codePoints = malloc_array(utf32, codePointCount);
utf8_to_codepoints(codePointCount, codePoints, STR8((char*)TEST_STRING));
u32 glyphCount = 0;
for(int i = 0; i < codePointCount; i++)
{
if(codePoints[i] != ' ' && codePoints[i] != '\n')
{
glyphCount++;
}
}
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
f64 frameTime = 0;
bool tracked = false;
vec2 trackPoint = { 0 };
f32 zoom = 1;
f32 startX = 10;
f32 startY = 10 + lineHeights[fontIndex];
mp_input_state inputState = { 0 };
while(!mp_should_quit())
{
f64 startFrameTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
mp_input_process_event(&inputState, event);
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_MOUSE_BUTTON:
{
if(event->key.code == MP_MOUSE_LEFT)
{
if(event->key.action == MP_KEY_PRESS)
{
tracked = true;
vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = mousePos.x / zoom - startX;
trackPoint.y = mousePos.y / zoom - startY;
}
else
{
tracked = false;
}
}
}
break;
case MP_EVENT_MOUSE_WHEEL:
{
vec2 mousePos = mp_mouse_position(&inputState);
f32 trackX = mousePos.x / zoom - startX;
f32 trackY = mousePos.y / zoom - startY;
zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.2, 10);
startX = mousePos.x / zoom - trackX;
startY = mousePos.y / zoom - trackY;
}
break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS)
{
fontIndex = (fontIndex + 1) % FONT_COUNT;
}
}
break;
default:
break;
}
}
if(tracked)
{
vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x / zoom - trackPoint.x;
startY = mousePos.y / zoom - trackPoint.y;
}
f32 textX = startX;
f32 textY = startY;
/*
mg_set_color_rgba(1, 1, 1, 1);
mg_clear();
mg_set_color_rgba(1, 0, 0, 1);
@ -239,94 +245,92 @@ int main()
{
mg_rectangle_fill(0, 0, 100, 100);
}
*/
mg_matrix_push((mg_mat2x3){zoom, 0, 0,
0, zoom, 0});
mg_set_color_rgba(1, 1, 1, 1);
mg_clear();
mg_set_font(fonts[fontIndex]);
mg_set_font_size(14);
mg_set_color_rgba(0, 0, 0, 1);
mg_move_to(textX, textY);
int startIndex = 0;
while(startIndex < codePointCount)
{
bool lineBreak = false;
int subIndex = 0;
for(; (startIndex+subIndex) < codePointCount && subIndex < 120; subIndex++)
{
if(codePoints[startIndex + subIndex] == '\n')
{
break;
}
}
u32 glyphs[512];
mg_font_get_glyph_indices(fonts[fontIndex], (str32){subIndex, codePoints+startIndex}, (str32){512, glyphs});
mg_glyph_outlines((str32){subIndex, glyphs});
mg_fill();
textY += lineHeights[fontIndex];
mg_move_to(textX, textY);
startIndex++;
startIndex += subIndex;
}
mg_matrix_pop();
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(fonts[fontIndex]);
mg_set_font_size(14);
mg_move_to(10, contentRect.h - 10 - lineHeights[fontIndex]);
str8 text = str8_pushf(mem_scratch(),
"Test program: %i glyphs, frame time = %fs, fps = %f",
glyphCount,
frameTime,
1./frameTime);
mg_text_outlines(text);
mg_fill();
f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC);
mg_surface_prepare(surface);
mg_render(surface, canvas);
f64 startPresentTime = mp_get_time(MP_CLOCK_MONOTONIC);
mg_surface_present(surface);
f64 endFrameTime = mp_get_time(MP_CLOCK_MONOTONIC);
frameTime = (endFrameTime - startFrameTime);
printf("frame time: %.2fms (%.2fFPS), draw = %f.2ms, flush = %.2fms, present = %.2fms\n",
frameTime*1000,
1./frameTime,
(startFlushTime - startFrameTime)*1000,
(startPresentTime - startFlushTime)*1000,
(endFrameTime - startPresentTime)*1000);
mp_input_next_frame(&inputState);
mem_arena_clear(mem_scratch());
}
for(int i=0; i<FONT_COUNT; i++)
{
mg_font_destroy(fonts[i]);
}
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return(0);
}
*/
mg_matrix_push((mg_mat2x3){ zoom, 0, 0,
0, zoom, 0 });
mg_set_color_rgba(1, 1, 1, 1);
mg_clear();
mg_set_font(fonts[fontIndex]);
mg_set_font_size(14);
mg_set_color_rgba(0, 0, 0, 1);
mg_move_to(textX, textY);
int startIndex = 0;
while(startIndex < codePointCount)
{
bool lineBreak = false;
int subIndex = 0;
for(; (startIndex + subIndex) < codePointCount && subIndex < 120; subIndex++)
{
if(codePoints[startIndex + subIndex] == '\n')
{
break;
}
}
u32 glyphs[512];
mg_font_get_glyph_indices(fonts[fontIndex], (str32){ subIndex, codePoints + startIndex }, (str32){ 512, glyphs });
mg_glyph_outlines((str32){ subIndex, glyphs });
mg_fill();
textY += lineHeights[fontIndex];
mg_move_to(textX, textY);
startIndex++;
startIndex += subIndex;
}
mg_matrix_pop();
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(fonts[fontIndex]);
mg_set_font_size(14);
mg_move_to(10, contentRect.h - 10 - lineHeights[fontIndex]);
str8 text = str8_pushf(mem_scratch(),
"Test program: %i glyphs, frame time = %fs, fps = %f",
glyphCount,
frameTime,
1. / frameTime);
mg_text_outlines(text);
mg_fill();
f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC);
mg_surface_prepare(surface);
mg_render(surface, canvas);
f64 startPresentTime = mp_get_time(MP_CLOCK_MONOTONIC);
mg_surface_present(surface);
f64 endFrameTime = mp_get_time(MP_CLOCK_MONOTONIC);
frameTime = (endFrameTime - startFrameTime);
printf("frame time: %.2fms (%.2fFPS), draw = %f.2ms, flush = %.2fms, present = %.2fms\n",
frameTime * 1000,
1. / frameTime,
(startFlushTime - startFrameTime) * 1000,
(startPresentTime - startFlushTime) * 1000,
(endFrameTime - startPresentTime) * 1000);
mp_input_next_frame(&inputState);
mem_arena_clear(mem_scratch());
}
for(int i = 0; i < FONT_COUNT; i++)
{
mg_font_destroy(fonts[i]);
}
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return (0);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,136 +6,138 @@
* @revision:
*
*****************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#include"milepost.h"
#include "milepost.h"
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
mg_surface_swap_interval(surface, 1);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
mg_surface_swap_interval(surface, 1);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return(-1);
}
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return (-1);
}
//TODO: create canvas
mg_canvas canvas = mg_canvas_create();
//TODO: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return(-1);
}
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return (-1);
}
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
f64 frameTime = 0;
f32 x = 0, y = 0;
f64 frameTime = 0;
f32 x = 0, y = 0;
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS)
{
if(event->key.code == MP_KEY_LEFT)
{
x-=1;
}
if(event->key.code == MP_KEY_RIGHT)
{
x+=1;
}
if(event->key.code == MP_KEY_UP)
{
y-=1;
}
if(event->key.code == MP_KEY_DOWN)
{
y+=1;
}
}
} break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS)
{
if(event->key.code == MP_KEY_LEFT)
{
x -= 1;
}
if(event->key.code == MP_KEY_RIGHT)
{
x += 1;
}
if(event->key.code == MP_KEY_UP)
{
y -= 1;
}
if(event->key.code == MP_KEY_DOWN)
{
y += 1;
}
}
}
break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_prepare(surface);
// background
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
// background
mg_set_color_rgba(0, 1, 1, 1);
mg_clear();
mg_move_to(100, 100);
mg_line_to(150, 150);
mg_line_to(100, 200);
mg_line_to(50, 150);
mg_close_path();
mg_set_color_rgba(1, 0, 0, 1);
mg_fill();
mg_move_to(100, 100);
mg_line_to(150, 150);
mg_line_to(100, 200);
mg_line_to(50, 150);
mg_close_path();
mg_set_color_rgba(1, 0, 0, 1);
mg_fill();
mg_move_to(200, 100);
mg_line_to(410, 100);
mg_line_to(410, 200);
mg_line_to(200, 200);
mg_close_path();
mg_set_color_rgba(0, 1, 0, 1);
mg_fill();
mg_move_to(200, 100);
mg_line_to(410, 100);
mg_line_to(410, 200);
mg_line_to(200, 200);
mg_close_path();
mg_set_color_rgba(0, 1, 0, 1);
mg_fill();
mg_set_color_rgba(0, 1, 1, 0.5);
mg_rectangle_fill(120, 120, 200, 200);
mg_set_color_rgba(0, 1, 1, 0.5);
mg_rectangle_fill(120, 120, 200, 200);
mg_set_color_rgba(1, 0, 0.5, 1);
mg_rectangle_fill(700, 500, 200, 200);
mg_set_color_rgba(1, 0, 0.5, 1);
mg_rectangle_fill(700, 500, 200, 200);
mg_move_to(300, 300);
mg_quadratic_to(400, 500, 500, 300);
mg_close_path();
mg_set_color_rgba(0, 0, 1, 1);
mg_fill();
mg_move_to(300, 300);
mg_quadratic_to(400, 500, 500, 300);
mg_close_path();
mg_set_color_rgba(0, 0, 1, 1);
mg_fill();
mg_move_to(200, 450);
mg_cubic_to(200, 250, 400, 550, 400, 450);
mg_close_path();
mg_set_color_rgba(1, 0.5, 0, 1);
mg_fill();
mg_move_to(200, 450);
mg_cubic_to(200, 250, 400, 550, 400, 450);
mg_close_path();
mg_set_color_rgba(1, 0.5, 0, 1);
mg_fill();
/*
/*
mg_set_joint(MG_JOINT_NONE);
mg_set_max_joint_excursion(20);
@ -172,22 +174,22 @@ int main()
mg_set_color_rgba(0, 0, 1, 1);
mg_fill();
*/
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1./frameTime);
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1. / frameTime);
mg_render(surface, canvas);
mg_surface_present(surface);
mg_render(surface, canvas);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -1,98 +1,99 @@
#include<stdlib.h>
#include<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#define MG_INCLUDE_GL_API 1
#include"milepost.h"
#include "milepost.h"
mg_surface surface = {0};
mg_canvas canvas = {0};
mg_surface surface = { 0 };
mg_canvas canvas = { 0 };
i32 render_thread(void* user)
{
while(!mp_should_quit())
{
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
while(!mp_should_quit())
{
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_canvas_set_current(canvas);
mg_surface_prepare(surface);
mg_canvas_set_current(canvas);
mg_set_color_rgba(0, 0, 0.5, 0.5);
mg_clear();
mg_set_color_rgba(0, 0, 0.5, 0.5);
mg_clear();
mg_set_color_rgba(1, 0, 0, 1);
mg_rectangle_fill(100, 100, 300, 150);
mg_set_color_rgba(1, 0, 0, 1);
mg_rectangle_fill(100, 100, 300, 150);
mg_render(surface, canvas);
mg_render(surface, canvas);
mg_surface_present(surface);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
}
return(0);
mem_arena_clear(mem_scratch());
}
return (0);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface 1\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
//NOTE: create surface
surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface 1\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas 1\n");
return(-1);
}
canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas 1\n");
return (-1);
}
mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS);
mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS);
// start app
mp_window_center(window);
mp_window_bring_to_front(window);
mp_window_focus(window);
// start app
mp_window_center(window);
mp_window_bring_to_front(window);
mp_window_focus(window);
mp_thread* renderThread = mp_thread_create(render_thread, NULL);
mp_thread* renderThread = mp_thread_create(render_thread, NULL);
while(!mp_should_quit())
{
mp_pump_events(0);
}
while(!mp_should_quit())
{
mp_pump_events(0);
}
mp_thread_join(renderThread, NULL);
mp_thread_join(renderThread, NULL);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_window_destroy(window);
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -1,121 +1,131 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
* @date: 30/07/2022
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"milepost.h"
int main()
{
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
mp_window_bring_to_front(window);
mp_window_focus(window);
mp_window_center(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event *event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
case MP_EVENT_WINDOW_RESIZE:
{
printf("resized, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
event->move.frame.x,
event->move.frame.y,
event->move.frame.w,
event->move.frame.h,
event->move.content.x,
event->move.content.y,
event->move.content.w,
event->move.content.h);
} break;
case MP_EVENT_WINDOW_MOVE:
{
printf("moved, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
event->move.frame.x,
event->move.frame.y,
event->move.frame.w,
event->move.frame.h,
event->move.content.x,
event->move.content.y,
event->move.content.w,
event->move.content.h);
} break;
case MP_EVENT_MOUSE_MOVE:
{
printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n",
event->mouse.x,
event->mouse.y,
event->mouse.deltaX,
event->mouse.deltaY);
} break;
case MP_EVENT_MOUSE_WHEEL:
{
printf("mouse wheel, delta = {%f, %f}\n",
event->mouse.deltaX,
event->mouse.deltaY);
} break;
case MP_EVENT_MOUSE_ENTER:
{
printf("mouse enter\n");
} break;
case MP_EVENT_MOUSE_LEAVE:
{
printf("mouse leave\n");
} break;
case MP_EVENT_MOUSE_BUTTON:
{
printf("mouse button %i: %i\n",
event->key.code,
event->key.action == MP_KEY_PRESS ? 1 : 0);
} break;
case MP_EVENT_KEYBOARD_KEY:
{
printf("key %i: %s\n",
event->key.code,
event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat"));
} break;
case MP_EVENT_KEYBOARD_CHAR:
{
printf("entered char %s\n", event->character.sequence);
} break;
default:
break;
}
}
mem_arena_clear(mem_scratch());
}
mp_terminate();
return(0);
}
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "milepost.h"
int main()
{
mp_init();
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
mp_window_bring_to_front(window);
mp_window_focus(window);
mp_window_center(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_WINDOW_RESIZE:
{
printf("resized, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
event->move.frame.x,
event->move.frame.y,
event->move.frame.w,
event->move.frame.h,
event->move.content.x,
event->move.content.y,
event->move.content.w,
event->move.content.h);
}
break;
case MP_EVENT_WINDOW_MOVE:
{
printf("moved, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n",
event->move.frame.x,
event->move.frame.y,
event->move.frame.w,
event->move.frame.h,
event->move.content.x,
event->move.content.y,
event->move.content.w,
event->move.content.h);
}
break;
case MP_EVENT_MOUSE_MOVE:
{
printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n",
event->mouse.x,
event->mouse.y,
event->mouse.deltaX,
event->mouse.deltaY);
}
break;
case MP_EVENT_MOUSE_WHEEL:
{
printf("mouse wheel, delta = {%f, %f}\n",
event->mouse.deltaX,
event->mouse.deltaY);
}
break;
case MP_EVENT_MOUSE_ENTER:
{
printf("mouse enter\n");
}
break;
case MP_EVENT_MOUSE_LEAVE:
{
printf("mouse leave\n");
}
break;
case MP_EVENT_MOUSE_BUTTON:
{
printf("mouse button %i: %i\n",
event->key.code,
event->key.action == MP_KEY_PRESS ? 1 : 0);
}
break;
case MP_EVENT_KEYBOARD_KEY:
{
printf("key %i: %s\n",
event->key.code,
event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat"));
}
break;
case MP_EVENT_KEYBOARD_CHAR:
{
printf("entered char %s\n", event->character.sequence);
}
break;
default:
break;
}
}
mem_arena_clear(mem_scratch());
}
mp_terminate();
return (0);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,221 +6,222 @@
* @revision:
*
*****************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#define MG_INCLUDE_GL_API
#include"milepost.h"
#include "milepost.h"
unsigned int program;
const char* vshaderSource =
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
typedef struct app_data
{
mp_window window;
mg_surface surface;
mg_canvas canvas;
mg_font font;
mp_window window;
mg_surface surface;
mg_canvas canvas;
mg_font font;
GLuint vertexBuffer;
GLuint vertexBuffer;
} app_data;
void process_event(app_data* app, mp_event event)
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_WINDOW_RESIZE:
{
log_info("resizing window!\n");
} break;
case MP_EVENT_WINDOW_RESIZE:
{
log_info("resizing window!\n");
}
break;
default:
break;
}
default:
break;
}
}
void update_and_render(app_data* app)
{
mg_surface_prepare(app->surface);
mg_surface_prepare(app->surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800 / (f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
alpha += 2*M_PI/120;
alpha += 2 * M_PI / 120;
glUniformMatrix4fv(0, 1, false, matrix);
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawArrays(GL_TRIANGLES, 0, 3);
mg_surface_present(app->surface);
mg_surface_present(app->surface);
mem_arena_clear(mem_scratch());
mem_arena_clear(mem_scratch());
}
i32 render(void* user)
{
app_data* app = (app_data*)user;
app_data* app = (app_data*)user;
//NOTE: init shader and gl state
mg_surface_prepare(app->surface);
//NOTE: init shader and gl state
mg_surface_prepare(app->surface);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &app->vertexBuffer);
glGenBuffers(1, &app->vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
glUseProgram(program);
while(!mp_should_quit())
{
mp_event* event = 0;
while(!mp_should_quit())
{
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
process_event(app, *event);
}
update_and_render(app);
mem_arena_clear(mem_scratch());
}
while((event = mp_next_event(mem_scratch())) != 0)
{
process_event(app, *event);
}
update_and_render(app);
mem_arena_clear(mem_scratch());
}
return(0);
return (0);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GL);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return(-1);
}
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GL);
if(mg_surface_is_nil(surface))
{
printf("Error: couldn't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 1);
mg_surface_deselect();
mg_surface_swap_interval(surface, 1);
mg_surface_deselect();
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
//TODO: start thread
app_data app = { .window = window,
.surface = surface };
//TODO: start thread
app_data app = {.window = window,
.surface = surface};
mp_thread* renderThread = mp_thread_create(render, &app);
mp_thread* renderThread = mp_thread_create(render, &app);
while(!mp_should_quit())
{
mp_pump_events(0);
}
while(!mp_should_quit())
{
mp_pump_events(0);
}
mp_thread_join(renderThread, NULL);
mp_thread_join(renderThread, NULL);
mg_surface_destroy(surface);
mp_window_destroy(window);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -1,291 +1,291 @@
#include<stdlib.h>
#include<string.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#include<stdlib.h>
#include<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#define MG_INCLUDE_GL_API 1
#include"milepost.h"
#include "milepost.h"
#define LOG_SUBSYSTEM "Main"
#ifdef OS_WIN64
#include<process.h>
#include<io.h>
#include<fcntl.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>
#define dup2 _dup2
#define pipe(fds) _pipe(fds, 256, O_BINARY)
#define read _read
#define write _write
#define dup2 _dup2
#define pipe(fds) _pipe(fds, 256, O_BINARY)
#define read _read
#define write _write
#define process_id HANDLE
#define process_id HANDLE
process_id spawn_child(char* program, char** argv)
{
return((process_id)_spawnv(P_NOWAIT, program, argv));
}
process_id spawn_child(char* program, char** argv)
{
return ((process_id)_spawnv(P_NOWAIT, program, argv));
}
void terminate_child(process_id child)
{
TerminateProcess(child, 0);
}
void terminate_child(process_id child)
{
TerminateProcess(child, 0);
}
#elif OS_MACOS
#include<unistd.h>
#include<signal.h>
#include <unistd.h>
#include <signal.h>
#define process_id pid_t
#define process_id pid_t
process_id spawn_child(char* program, char** argv)
{
pid_t pid = fork();
if(!pid)
{
char* envp[] = {0};
execve(program, argv, envp);
assert(0);
}
return(pid);
}
process_id spawn_child(char* program, char** argv)
{
pid_t pid = fork();
if(!pid)
{
char* envp[] = { 0 };
execve(program, argv, envp);
assert(0);
}
return (pid);
}
void terminate_child(process_id child)
{
kill(child, SIGTERM);
}
void terminate_child(process_id child)
{
kill(child, SIGTERM);
}
#endif
unsigned int program;
const char* vshaderSource =
//"#version 320 es\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
//"#version 320 es\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
//"#version 320 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
//"#version 320 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int child_main(int writeFd)
{
mp_init();
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_remote(800, 600, MG_BACKEND_GLES);
mg_surface_id connectionID = mg_surface_remote_id(surface);
//NOTE: create surface
mg_surface surface = mg_surface_create_remote(800, 600, MG_BACKEND_GLES);
mg_surface_id connectionID = mg_surface_remote_id(surface);
mg_surface_prepare(surface);
mg_surface_prepare(surface);
//NOTE: init shader and gl state
mg_surface_prepare(surface);
//NOTE: init shader and gl state
mg_surface_prepare(surface);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
glUseProgram(program);
//NOTE: send context id to parent
write(writeFd, &connectionID, sizeof(connectionID));
//NOTE: send context id to parent
write(writeFd, &connectionID, sizeof(connectionID));
//NOTE: render loop
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = { 0 };
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
//NOTE: render loop
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = {0};
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
default:
break;
}
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_prepare(surface);
mp_rect rect = mg_surface_get_frame(surface);
vec2 scaling = mg_surface_contents_scaling(surface);
mp_rect rect = mg_surface_get_frame(surface);
vec2 scaling = mg_surface_contents_scaling(surface);
glViewport(0, 0, rect.w * scaling.x, rect.h * scaling.y);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, rect.w*scaling.x, rect.h*scaling.y);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800 / (f32)600;
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
alpha += 2 * M_PI / 120;
alpha += 2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
mg_surface_present(surface);
}
glDrawArrays(GL_TRIANGLES, 0, 3);
mp_terminate();
mg_surface_present(surface);
}
mp_terminate();
return(0);
return (0);
}
int main(int argc, char** argv)
{
LogLevel(LOG_LEVEL_DEBUG);
LogLevel(LOG_LEVEL_DEBUG);
if(argc > 1)
{
if(!strcmp(argv[1], "--child"))
{
int writeFd = atoi(argv[2]);
printf("child process created with file desc %i\n", writeFd);
return(child_main(writeFd));
}
else
{
return(-1);
}
}
// setvbuf( stdout, NULL, _IONBF, 0 );
mp_init();
if(argc > 1)
{
if(!strcmp(argv[1], "--child"))
{
int writeFd = atoi(argv[2]);
printf("child process created with file desc %i\n", writeFd);
return (child_main(writeFd));
}
else
{
return (-1);
}
}
// setvbuf( stdout, NULL, _IONBF, 0 );
mp_init();
//NOTE: create main window
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create main window
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface client
mg_surface surface = mg_surface_create_host(window);
//NOTE: create surface client
mg_surface surface = mg_surface_create_host(window);
//NOTE setup descriptors
int fileDesc[2];
pipe(fileDesc);
//NOTE setup descriptors
int fileDesc[2];
pipe(fileDesc);
printf("parent process created readFd %i and writeFd %i\n", fileDesc[0], fileDesc[1]);
printf("parent process created readFd %i and writeFd %i\n", fileDesc[0], fileDesc[1]);
char writeDescStr[64];
snprintf(writeDescStr, 64, "%i", fileDesc[1]);
char* args[] = {"bin/example_surface_sharing", "--child", writeDescStr, 0};
char writeDescStr[64];
snprintf(writeDescStr, 64, "%i", fileDesc[1]);
char* args[] = { "bin/example_surface_sharing", "--child", writeDescStr, 0 };
process_id child = spawn_child(args[0], args);
process_id child = spawn_child(args[0], args);
//NOTE: read the connection id
mg_surface_id connectionID = 0;
read(fileDesc[0], &connectionID, sizeof(connectionID));
printf("received child connection id %llu\n", connectionID);
//NOTE: read the connection id
mg_surface_id connectionID = 0;
read(fileDesc[0], &connectionID, sizeof(connectionID));
printf("received child connection id %llu\n", connectionID);
//NOTE: connect the client
mg_surface_host_connect(surface, connectionID);
//NOTE: connect the client
mg_surface_host_connect(surface, connectionID);
//NOTE: show the window
mp_window_bring_to_front(window);
//NOTE: show the window
mp_window_bring_to_front(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = {0};
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = { 0 };
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_present(surface);
}
default:
break;
}
}
mg_surface_prepare(surface);
mg_surface_present(surface);
}
terminate_child(child);
terminate_child(child);
mp_terminate();
return(0);
mp_terminate();
return (0);
}

View File

@ -1,247 +1,253 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
* @date: 30/07/2022
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<errno.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include"milepost.h"
#include"tiger.c"
mg_font create_font()
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf"));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS};
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return(font);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610};
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("Couln't create surface\n");
return(-1);
}
mg_surface_swap_interval(surface, 0);
//TODO: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return(-1);
}
mg_font font = create_font();
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
bool tracked = false;
vec2 trackPoint = {0};
f32 zoom = 1;
f32 startX = 300, startY = 200;
bool singlePath = false;
int singlePathIndex = 0;
f64 frameTime = 0;
mp_input_state inputState = {0};
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
mp_input_process_event(&inputState, event);
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
case MP_EVENT_MOUSE_BUTTON:
{
if(event->key.code == MP_MOUSE_LEFT)
{
if(event->key.action == MP_KEY_PRESS)
{
tracked = true;
vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = (mousePos.x - startX)/zoom;
trackPoint.y = (mousePos.y - startY)/zoom;
}
else
{
tracked = false;
}
}
} break;
case MP_EVENT_MOUSE_WHEEL:
{
vec2 mousePos = mp_mouse_position(&inputState);
f32 pinX = (mousePos.x - startX)/zoom;
f32 pinY = (mousePos.y - startY)/zoom;
zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.5, 5);
startX = mousePos.x - pinX*zoom;
startY = mousePos.y - pinY*zoom;
} break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT)
{
switch(event->key.code)
{
case MP_KEY_SPACE:
singlePath = !singlePath;
break;
case MP_KEY_UP:
{
if(event->key.mods & MP_KEYMOD_SHIFT)
{
singlePathIndex++;
}
else
{
zoom += 0.001;
}
} break;
case MP_KEY_DOWN:
{
if(event->key.mods & MP_KEYMOD_SHIFT)
{
singlePathIndex--;
}
else
{
zoom -= 0.001;
}
} break;
}
}
} break;
default:
break;
}
}
if(tracked)
{
vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x - trackPoint.x*zoom;
startY = mousePos.y - trackPoint.y*zoom;
}
mg_surface_prepare(surface);
mg_set_color_rgba(1, 0, 1, 1);
mg_clear();
mg_matrix_push((mg_mat2x3){zoom, 0, startX,
0, zoom, startY});
draw_tiger(singlePath, singlePathIndex);
if(singlePath)
{
printf("display single path %i\n", singlePathIndex);
printf("viewpos = (%f, %f), zoom = %f\n", startX, startY, zoom);
}
mg_matrix_pop();
// text
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font);
mg_set_font_size(12);
mg_move_to(50, 600-50);
str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime,
1./frameTime);
mg_text_outlines(text);
mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1./frameTime);
mg_render(surface, canvas);
mg_surface_present(surface);
mp_input_next_frame(&inputState);
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mg_font_destroy(font);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return(0);
}
*****************************************************************/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include <math.h>
#include "milepost.h"
#include "tiger.c"
mg_font create_font()
{
//NOTE(martin): create font
str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf"));
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return (mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return (font);
}
int main()
{
mp_init();
mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface))
{
log_error("Couln't create surface\n");
return (-1);
}
mg_surface_swap_interval(surface, 0);
//TODO: create canvas
mg_canvas canvas = mg_canvas_create();
if(mg_canvas_is_nil(canvas))
{
printf("Error: couldn't create canvas\n");
return (-1);
}
mg_font font = create_font();
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
bool tracked = false;
vec2 trackPoint = { 0 };
f32 zoom = 1;
f32 startX = 300, startY = 200;
bool singlePath = false;
int singlePathIndex = 0;
f64 frameTime = 0;
mp_input_state inputState = { 0 };
while(!mp_should_quit())
{
f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC);
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
mp_input_process_event(&inputState, event);
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
case MP_EVENT_MOUSE_BUTTON:
{
if(event->key.code == MP_MOUSE_LEFT)
{
if(event->key.action == MP_KEY_PRESS)
{
tracked = true;
vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = (mousePos.x - startX) / zoom;
trackPoint.y = (mousePos.y - startY) / zoom;
}
else
{
tracked = false;
}
}
}
break;
case MP_EVENT_MOUSE_WHEEL:
{
vec2 mousePos = mp_mouse_position(&inputState);
f32 pinX = (mousePos.x - startX) / zoom;
f32 pinY = (mousePos.y - startY) / zoom;
zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.5, 5);
startX = mousePos.x - pinX * zoom;
startY = mousePos.y - pinY * zoom;
}
break;
case MP_EVENT_KEYBOARD_KEY:
{
if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT)
{
switch(event->key.code)
{
case MP_KEY_SPACE:
singlePath = !singlePath;
break;
case MP_KEY_UP:
{
if(event->key.mods & MP_KEYMOD_SHIFT)
{
singlePathIndex++;
}
else
{
zoom += 0.001;
}
}
break;
case MP_KEY_DOWN:
{
if(event->key.mods & MP_KEYMOD_SHIFT)
{
singlePathIndex--;
}
else
{
zoom -= 0.001;
}
}
break;
}
}
}
break;
default:
break;
}
}
if(tracked)
{
vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x - trackPoint.x * zoom;
startY = mousePos.y - trackPoint.y * zoom;
}
mg_surface_prepare(surface);
mg_set_color_rgba(1, 0, 1, 1);
mg_clear();
mg_matrix_push((mg_mat2x3){ zoom, 0, startX,
0, zoom, startY });
draw_tiger(singlePath, singlePathIndex);
if(singlePath)
{
printf("display single path %i\n", singlePathIndex);
printf("viewpos = (%f, %f), zoom = %f\n", startX, startY, zoom);
}
mg_matrix_pop();
// text
mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font);
mg_set_font_size(12);
mg_move_to(50, 600 - 50);
str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime,
1. / frameTime);
mg_text_outlines(text);
mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime,
1. / frameTime);
mg_render(surface, canvas);
mg_surface_present(surface);
mp_input_next_frame(&inputState);
mem_arena_clear(mem_scratch());
frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime;
}
mg_font_destroy(font);
mg_canvas_destroy(canvas);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return (0);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,163 +1,163 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
* @date: 30/07/2022
* @revision:
*
*****************************************************************/
#include<stdio.h>
#include<string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#define MG_INCLUDE_GL_API
#include"milepost.h"
unsigned int program;
const char* vshaderSource =
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int main()
{
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GL);
//NOTE: init shader and gl state
mg_surface_prepare(surface);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
mp_window_bring_to_front(window);
// mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
default:
break;
}
}
mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
alpha += 2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
}
mp_terminate();
return(0);
}
*****************************************************************/
#include <stdio.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include <math.h>
#define MG_INCLUDE_GL_API
#include "milepost.h"
unsigned int program;
const char* vshaderSource =
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int main()
{
mp_init();
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GL);
//NOTE: init shader and gl state
mg_surface_prepare(surface);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
mp_window_bring_to_front(window);
// mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800 / (f32)600;
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
alpha += 2 * M_PI / 120;
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
mg_surface_present(surface);
mem_arena_clear(mem_scratch());
}
mp_terminate();
return (0);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,160 +6,160 @@
* @revision:
*
*****************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#define MG_INCLUDE_GL_API 1
#include"milepost.h"
#include "milepost.h"
unsigned int program;
const char* vshaderSource =
//"#version 320 es\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
//"#version 320 es\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
//"#version 320 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
//"#version 320 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int main()
{
mp_init();
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GLES);
mg_surface_prepare(surface);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_GLES);
mg_surface_prepare(surface);
//NOTE: init shader and gl state
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//NOTE: init shader and gl state
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
glUseProgram(program);
mp_window_bring_to_front(window);
// mp_window_focus(window);
mp_window_bring_to_front(window);
// mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0)
{
switch(event->type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
default:
break;
}
}
default:
break;
}
}
// mg_surface_prepare(surface);
// mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800 / (f32)600;
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
alpha += 2 * M_PI / 120;
alpha += 2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
mg_surface_present(surface);
glDrawArrays(GL_TRIANGLES, 0, 3);
mem_arena_clear(mem_scratch());
}
mg_surface_present(surface);
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
mem_arena_clear(mem_scratch());
}
mg_surface_destroy(surface);
mp_window_destroy(window);
mp_terminate();
return(0);
return (0);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: main.cpp
* @author: Martin Fouilleul
@ -6,121 +6,122 @@
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<string.h>
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include <math.h>
#include"milepost.h"
#include"mtl_surface.h"
#include "milepost.h"
#include "mtl_surface.h"
#define LOG_SUBSYSTEM "Main"
#import<Metal/Metal.h>
#import<QuartzCore/CAMetalLayer.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#include"vertex.h"
#include "vertex.h"
static const my_vertex triangle[3] = {{{250, -250},{1, 0, 0, 1}},
{{-250, -250},{0, 1, 0, 1}},
{{0, 250},{0, 0, 1, 1}}};
static const my_vertex triangle[3] = { { { 250, -250 }, { 1, 0, 0, 1 } },
{ { -250, -250 }, { 0, 1, 0, 1 } },
{ { 0, 250 }, { 0, 0, 1, 1 } } };
int main()
{
LogLevel(LOG_LEVEL_DEBUG);
LogLevel(LOG_LEVEL_DEBUG);
mp_init();
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL);
//NOTE(martin): load the library
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
//NOTE(martin): load the library
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
str8 shaderPath = path_executable_relative(mem_scratch(), STR8("triangle_shader.metallib"));
const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath);
NSString* metalFileName = [[NSString alloc] initWithCString: shaderPathCString encoding: NSUTF8StringEncoding];
NSError* err = 0;
id<MTLLibrary> library = [device newLibraryWithFile: metalFileName error:&err];
if(err != nil)
{
const char* errStr = [[err localizedDescription] UTF8String];
printf("error : %s\n", errStr);
return(-1);
}
id<MTLFunction> vertexFunction = [library newFunctionWithName:@"VertexShader"];
id<MTLFunction> fragmentFunction = [library newFunctionWithName:@"FragmentShader"];
str8 shaderPath = path_executable_relative(mem_scratch(), STR8("triangle_shader.metallib"));
const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath);
NSString* metalFileName = [[NSString alloc] initWithCString:shaderPathCString encoding:NSUTF8StringEncoding];
NSError* err = 0;
id<MTLLibrary> library = [device newLibraryWithFile:metalFileName error:&err];
if(err != nil)
{
const char* errStr = [[err localizedDescription] UTF8String];
printf("error : %s\n", errStr);
return (-1);
}
id<MTLFunction> vertexFunction = [library newFunctionWithName:@"VertexShader"];
id<MTLFunction> fragmentFunction = [library newFunctionWithName:@"FragmentShader"];
//NOTE(martin): create a render pipeline
MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipelineStateDescriptor.label = @"My simple pipeline";
pipelineStateDescriptor.vertexFunction = vertexFunction;
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
//NOTE(martin): create a render pipeline
MTLRenderPipelineDescriptor* pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipelineStateDescriptor.label = @"My simple pipeline";
pipelineStateDescriptor.vertexFunction = vertexFunction;
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
CAMetalLayer* layer = mg_mtl_surface_layer(surface);
pipelineStateDescriptor.colorAttachments[0].pixelFormat = layer.pixelFormat;
CAMetalLayer* layer = mg_mtl_surface_layer(surface);
pipelineStateDescriptor.colorAttachments[0].pixelFormat = layer.pixelFormat;
id<MTLRenderPipelineState> pipelineState = [device newRenderPipelineStateWithDescriptor: pipelineStateDescriptor error:&err];
if(err != nil)
{
const char* errStr = [[err localizedDescription] UTF8String];
printf("error : %s\n", errStr);
return(-1);
}
id<MTLRenderPipelineState> pipelineState = [device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&err];
if(err != nil)
{
const char* errStr = [[err localizedDescription] UTF8String];
printf("error : %s\n", errStr);
return (-1);
}
// start app
// start app
mp_window_bring_to_front(window);
mp_window_focus(window);
mp_window_bring_to_front(window);
mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = {0};
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = { 0 };
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
}
break;
default:
break;
}
}
default:
break;
}
}
vector_uint2 viewportSize;
viewportSize.x = 800;
viewportSize.y = 600;
vector_uint2 viewportSize;
viewportSize.x = 800;
viewportSize.y = 600;
mg_surface_prepare(surface);
id<CAMetalDrawable> drawable = mg_mtl_surface_drawable(surface);
id<MTLCommandBuffer> commandBuffer = mg_mtl_surface_command_buffer(surface);
mg_surface_prepare(surface);
id<CAMetalDrawable> drawable = mg_mtl_surface_drawable(surface);
id<MTLCommandBuffer> commandBuffer = mg_mtl_surface_command_buffer(surface);
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
//Set the pipeline state
[encoder setRenderPipelineState:pipelineState];
//Set the pipeline state
[encoder setRenderPipelineState:pipelineState];
//Send data to the shader and add draw call
[encoder setVertexBytes: triangle length:sizeof(triangle) atIndex: vertexInputIndexVertices];
[encoder setVertexBytes: &viewportSize length:sizeof(viewportSize) atIndex: vertexInputIndexViewportSize];
[encoder drawPrimitives: MTLPrimitiveTypeTriangle vertexStart: 0 vertexCount: 3];
[encoder endEncoding];
//Send data to the shader and add draw call
[encoder setVertexBytes:triangle length:sizeof(triangle) atIndex:vertexInputIndexVertices];
[encoder setVertexBytes:&viewportSize length:sizeof(viewportSize) atIndex:vertexInputIndexViewportSize];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
[encoder endEncoding];
mg_surface_present(surface);
}
mg_surface_present(surface);
}
mp_terminate();
mp_terminate();
return(0);
return (0);
}

View File

@ -2,16 +2,18 @@
#ifndef __VERTEX_H__
#define __VERTEX_H__
#include<simd/simd.h>
#include <simd/simd.h>
typedef struct
{
vector_float2 pos;
vector_float4 col;
vector_float2 pos;
vector_float4 col;
} my_vertex;
typedef enum { vertexInputIndexVertices = 0,
vertexInputIndexViewportSize = 1 } vertexInputIndex;
typedef enum
{
vertexInputIndexVertices = 0,
vertexInputIndexViewportSize = 1
} vertexInputIndex;
#endif //__VERTEX_H__

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: app.c
* @author: Martin Fouilleul
@ -6,10 +6,10 @@
* @revision:
*
*****************************************************************/
#include"platform/platform_debug.h"
#include"app_internal.h"
#include "app_internal.h"
#include "platform/platform_debug.h"
oc_app oc_appData = {0};
oc_app oc_appData = { 0 };
//---------------------------------------------------------------
// Window handles
@ -17,63 +17,63 @@ oc_app oc_appData = {0};
void oc_init_window_handles()
{
oc_list_init(&oc_appData.windowFreeList);
for(int i=0; i<OC_APP_MAX_WINDOWS; i++)
{
oc_appData.windowPool[i].generation = 1;
oc_list_append(&oc_appData.windowFreeList, &oc_appData.windowPool[i].freeListElt);
}
oc_list_init(&oc_appData.windowFreeList);
for(int i = 0; i < OC_APP_MAX_WINDOWS; i++)
{
oc_appData.windowPool[i].generation = 1;
oc_list_append(&oc_appData.windowFreeList, &oc_appData.windowPool[i].freeListElt);
}
}
bool oc_window_handle_is_null(oc_window window)
{
return(window.h == 0);
return (window.h == 0);
}
oc_window oc_window_null_handle()
{
return((oc_window){.h = 0});
return ((oc_window){ .h = 0 });
}
oc_window_data* oc_window_alloc()
{
return(oc_list_pop_entry(&oc_appData.windowFreeList, oc_window_data, freeListElt));
return (oc_list_pop_entry(&oc_appData.windowFreeList, oc_window_data, freeListElt));
}
oc_window_data* oc_window_ptr_from_handle(oc_window handle)
{
u32 index = handle.h>>32;
u32 generation = handle.h & 0xffffffff;
if(index >= OC_APP_MAX_WINDOWS)
{
return(0);
}
oc_window_data* window = &oc_appData.windowPool[index];
if(window->generation != generation)
{
return(0);
}
else
{
return(window);
}
u32 index = handle.h >> 32;
u32 generation = handle.h & 0xffffffff;
if(index >= OC_APP_MAX_WINDOWS)
{
return (0);
}
oc_window_data* window = &oc_appData.windowPool[index];
if(window->generation != generation)
{
return (0);
}
else
{
return (window);
}
}
oc_window oc_window_handle_from_ptr(oc_window_data* window)
{
OC_DEBUG_ASSERT( (window - oc_appData.windowPool) >= 0
&& (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS);
OC_DEBUG_ASSERT((window - oc_appData.windowPool) >= 0
&& (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS);
u64 h = ((u64)(window - oc_appData.windowPool))<<32
| ((u64)window->generation);
u64 h = ((u64)(window - oc_appData.windowPool)) << 32
| ((u64)window->generation);
return((oc_window){h});
return ((oc_window){ h });
}
void oc_window_recycle_ptr(oc_window_data* window)
{
window->generation++;
oc_list_push(&oc_appData.windowFreeList, &window->freeListElt);
window->generation++;
oc_list_push(&oc_appData.windowFreeList, &window->freeListElt);
}
//---------------------------------------------------------------
@ -82,13 +82,13 @@ void oc_window_recycle_ptr(oc_window_data* window)
static void oc_init_common()
{
oc_init_window_handles();
oc_ringbuffer_init(&oc_appData.eventQueue, 16);
oc_init_window_handles();
oc_ringbuffer_init(&oc_appData.eventQueue, 16);
}
static void oc_terminate_common()
{
oc_ringbuffer_cleanup(&oc_appData.eventQueue);
oc_ringbuffer_cleanup(&oc_appData.eventQueue);
}
//---------------------------------------------------------------
@ -97,87 +97,87 @@ static void oc_terminate_common()
void oc_queue_event(oc_event* event)
{
oc_ringbuffer* queue = &oc_appData.eventQueue;
oc_ringbuffer* queue = &oc_appData.eventQueue;
if(oc_ringbuffer_write_available(queue) < sizeof(oc_event))
{
oc_log_error("event queue full\n");
}
else
{
bool error = false;
oc_ringbuffer_reserve(queue, sizeof(oc_event), (u8*)event);
if(oc_ringbuffer_write_available(queue) < sizeof(oc_event))
{
oc_log_error("event queue full\n");
}
else
{
bool error = false;
oc_ringbuffer_reserve(queue, sizeof(oc_event), (u8*)event);
if(event->type == OC_EVENT_PATHDROP)
{
oc_list_for(&event->paths.list, elt, oc_str8_elt, listElt)
{
oc_str8* path = &elt->string;
if(oc_ringbuffer_write_available(queue) < (sizeof(u64) + path->len))
{
oc_log_error("event queue full\n");
error = true;
break;
}
else
{
oc_ringbuffer_reserve(queue, sizeof(u64), (u8*)&path->len);
oc_ringbuffer_reserve(queue, path->len, (u8*)path->ptr);
}
}
}
if(error)
{
oc_ringbuffer_rewind(queue);
}
else
{
oc_ringbuffer_commit(queue);
}
}
if(event->type == OC_EVENT_PATHDROP)
{
oc_list_for(&event->paths.list, elt, oc_str8_elt, listElt)
{
oc_str8* path = &elt->string;
if(oc_ringbuffer_write_available(queue) < (sizeof(u64) + path->len))
{
oc_log_error("event queue full\n");
error = true;
break;
}
else
{
oc_ringbuffer_reserve(queue, sizeof(u64), (u8*)&path->len);
oc_ringbuffer_reserve(queue, path->len, (u8*)path->ptr);
}
}
}
if(error)
{
oc_ringbuffer_rewind(queue);
}
else
{
oc_ringbuffer_commit(queue);
}
}
}
oc_event* oc_next_event(oc_arena* arena)
{
//NOTE: pop and return event from queue
oc_event* event = 0;
oc_ringbuffer* queue = &oc_appData.eventQueue;
//NOTE: pop and return event from queue
oc_event* event = 0;
oc_ringbuffer* queue = &oc_appData.eventQueue;
if(oc_ringbuffer_read_available(queue) >= sizeof(oc_event))
{
event = oc_arena_push_type(arena, oc_event);
u64 read = oc_ringbuffer_read(queue, sizeof(oc_event), (u8*)event);
OC_DEBUG_ASSERT(read == sizeof(oc_event));
if(oc_ringbuffer_read_available(queue) >= sizeof(oc_event))
{
event = oc_arena_push_type(arena, oc_event);
u64 read = oc_ringbuffer_read(queue, sizeof(oc_event), (u8*)event);
OC_DEBUG_ASSERT(read == sizeof(oc_event));
if(event->type == OC_EVENT_PATHDROP)
{
u64 pathCount = event->paths.eltCount;
event->paths = (oc_str8_list){0};
if(event->type == OC_EVENT_PATHDROP)
{
u64 pathCount = event->paths.eltCount;
event->paths = (oc_str8_list){ 0 };
for(int i=0; i<pathCount; i++)
{
if(oc_ringbuffer_read_available(queue) < sizeof(u64))
{
oc_log_error("malformed path payload: no string size\n");
break;
}
for(int i = 0; i < pathCount; i++)
{
if(oc_ringbuffer_read_available(queue) < sizeof(u64))
{
oc_log_error("malformed path payload: no string size\n");
break;
}
u64 len = 0;
oc_ringbuffer_read(queue, sizeof(u64), (u8*)&len);
if(oc_ringbuffer_read_available(queue) < len)
{
oc_log_error("malformed path payload: string shorter than expected\n");
break;
}
u64 len = 0;
oc_ringbuffer_read(queue, sizeof(u64), (u8*)&len);
if(oc_ringbuffer_read_available(queue) < len)
{
oc_log_error("malformed path payload: string shorter than expected\n");
break;
}
char* buffer = oc_arena_push_array(arena, char, len);
oc_ringbuffer_read(queue, len, (u8*)buffer);
char* buffer = oc_arena_push_array(arena, char, len);
oc_ringbuffer_read(queue, len, (u8*)buffer);
oc_str8_list_push(arena, &event->paths, oc_str8_from_buffer(len, buffer));
}
}
}
return(event);
oc_str8_list_push(arena, &event->paths, oc_str8_from_buffer(len, buffer));
}
}
}
return (event);
}
//---------------------------------------------------------------
@ -186,32 +186,32 @@ oc_event* oc_next_event(oc_arena* arena)
void oc_window_set_content_position(oc_window window, oc_vec2 position)
{
oc_rect rect = oc_window_get_content_rect(window);
rect.x = position.x;
rect.y = position.y;
oc_window_set_content_rect(window, rect);
oc_rect rect = oc_window_get_content_rect(window);
rect.x = position.x;
rect.y = position.y;
oc_window_set_content_rect(window, rect);
}
void oc_window_set_content_size(oc_window window, oc_vec2 size)
{
oc_rect rect = oc_window_get_content_rect(window);
rect.w = size.x;
rect.h = size.y;
oc_window_set_content_rect(window, rect);
oc_rect rect = oc_window_get_content_rect(window);
rect.w = size.x;
rect.h = size.y;
oc_window_set_content_rect(window, rect);
}
void oc_window_set_frame_position(oc_window window, oc_vec2 position)
{
oc_rect frame = oc_window_get_frame_rect(window);
frame.x = position.x;
frame.y = position.y;
oc_window_set_frame_rect(window, frame);
oc_rect frame = oc_window_get_frame_rect(window);
frame.x = position.x;
frame.y = position.y;
oc_window_set_frame_rect(window, frame);
}
void oc_window_set_frame_size(oc_window window, oc_vec2 size)
{
oc_rect frame = oc_window_get_frame_rect(window);
frame.w = size.x;
frame.h = size.y;
oc_window_set_frame_rect(window, frame);
oc_rect frame = oc_window_get_frame_rect(window);
frame.w = size.x;
frame.h = size.y;
oc_window_set_frame_rect(window, frame);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: platform_app.h
* @author: Martin Fouilleul
@ -9,378 +9,396 @@
#ifndef __APP_H_
#define __APP_H_
#include"util/typedefs.h"
#include"util/utf8.h"
#include"util/lists.h"
#include"util/memory.h"
#include "util/lists.h"
#include "util/memory.h"
#include "util/typedefs.h"
#include "util/utf8.h"
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
//--------------------------------------------------------------------
// Typedefs, enums and constants
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Typedefs, enums and constants
//--------------------------------------------------------------------
typedef struct oc_window { u64 h; } oc_window;
typedef struct oc_window
{
u64 h;
} oc_window;
typedef enum { OC_MOUSE_CURSOR_ARROW,
OC_MOUSE_CURSOR_RESIZE_0,
OC_MOUSE_CURSOR_RESIZE_90,
OC_MOUSE_CURSOR_RESIZE_45,
OC_MOUSE_CURSOR_RESIZE_135,
OC_MOUSE_CURSOR_TEXT } oc_mouse_cursor;
typedef enum
{
OC_MOUSE_CURSOR_ARROW,
OC_MOUSE_CURSOR_RESIZE_0,
OC_MOUSE_CURSOR_RESIZE_90,
OC_MOUSE_CURSOR_RESIZE_45,
OC_MOUSE_CURSOR_RESIZE_135,
OC_MOUSE_CURSOR_TEXT
} oc_mouse_cursor;
typedef i32 oc_window_style;
static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01<<0,
OC_WINDOW_STYLE_FIXED_SIZE = 0x01<<1,
OC_WINDOW_STYLE_NO_CLOSE = 0x01<<2,
OC_WINDOW_STYLE_NO_MINIFY = 0x01<<3,
OC_WINDOW_STYLE_NO_FOCUS = 0x01<<4,
OC_WINDOW_STYLE_FLOAT = 0x01<<5,
OC_WINDOW_STYLE_POPUPMENU = 0x01<<6,
OC_WINDOW_STYLE_NO_BUTTONS = 0x01<<7;
typedef i32 oc_window_style;
static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01 << 0,
OC_WINDOW_STYLE_FIXED_SIZE = 0x01 << 1,
OC_WINDOW_STYLE_NO_CLOSE = 0x01 << 2,
OC_WINDOW_STYLE_NO_MINIFY = 0x01 << 3,
OC_WINDOW_STYLE_NO_FOCUS = 0x01 << 4,
OC_WINDOW_STYLE_FLOAT = 0x01 << 5,
OC_WINDOW_STYLE_POPUPMENU = 0x01 << 6,
OC_WINDOW_STYLE_NO_BUTTONS = 0x01 << 7;
typedef enum { OC_EVENT_NONE,
OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
OC_EVENT_KEYBOARD_KEY,
OC_EVENT_KEYBOARD_CHAR,
OC_EVENT_MOUSE_BUTTON,
OC_EVENT_MOUSE_MOVE,
OC_EVENT_MOUSE_WHEEL,
OC_EVENT_MOUSE_ENTER,
OC_EVENT_MOUSE_LEAVE,
OC_EVENT_WINDOW_RESIZE,
OC_EVENT_WINDOW_MOVE,
OC_EVENT_WINDOW_FOCUS,
OC_EVENT_WINDOW_UNFOCUS,
OC_EVENT_WINDOW_HIDE, // rename to minimize?
OC_EVENT_WINDOW_SHOW, // rename to restore?
OC_EVENT_WINDOW_CLOSE,
OC_EVENT_PATHDROP,
OC_EVENT_FRAME,
OC_EVENT_QUIT } oc_event_type;
typedef enum
{
OC_EVENT_NONE,
OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
OC_EVENT_KEYBOARD_KEY,
OC_EVENT_KEYBOARD_CHAR,
OC_EVENT_MOUSE_BUTTON,
OC_EVENT_MOUSE_MOVE,
OC_EVENT_MOUSE_WHEEL,
OC_EVENT_MOUSE_ENTER,
OC_EVENT_MOUSE_LEAVE,
OC_EVENT_WINDOW_RESIZE,
OC_EVENT_WINDOW_MOVE,
OC_EVENT_WINDOW_FOCUS,
OC_EVENT_WINDOW_UNFOCUS,
OC_EVENT_WINDOW_HIDE, // rename to minimize?
OC_EVENT_WINDOW_SHOW, // rename to restore?
OC_EVENT_WINDOW_CLOSE,
OC_EVENT_PATHDROP,
OC_EVENT_FRAME,
OC_EVENT_QUIT
} oc_event_type;
typedef enum { OC_KEY_NO_ACTION,
OC_KEY_PRESS,
OC_KEY_RELEASE,
OC_KEY_REPEAT } oc_key_action;
typedef enum
{
OC_KEY_NO_ACTION,
OC_KEY_PRESS,
OC_KEY_RELEASE,
OC_KEY_REPEAT
} oc_key_action;
typedef enum { OC_KEY_UNKNOWN = 0,
OC_KEY_SPACE = 32,
OC_KEY_APOSTROPHE = 39, /* ' */
OC_KEY_COMMA = 44, /* , */
OC_KEY_MINUS = 45, // -
OC_KEY_PERIOD = 46, // .
OC_KEY_SLASH = 47, // /
OC_KEY_0 = 48,
OC_KEY_1 = 49,
OC_KEY_2 = 50,
OC_KEY_3 = 51,
OC_KEY_4 = 52,
OC_KEY_5 = 53,
OC_KEY_6 = 54,
OC_KEY_7 = 55,
OC_KEY_8 = 56,
OC_KEY_9 = 57,
OC_KEY_SEMICOLON = 59, // ;
OC_KEY_EQUAL = 61, // =
OC_KEY_A = 65,
OC_KEY_B = 66,
OC_KEY_C = 67,
OC_KEY_D = 68,
OC_KEY_E = 69,
OC_KEY_F = 70,
OC_KEY_G = 71,
OC_KEY_H = 72,
OC_KEY_I = 73,
OC_KEY_J = 74,
OC_KEY_K = 75,
OC_KEY_L = 76,
OC_KEY_M = 77,
OC_KEY_N = 78,
OC_KEY_O = 79,
OC_KEY_P = 80,
OC_KEY_Q = 81,
OC_KEY_R = 82,
OC_KEY_S = 83,
OC_KEY_T = 84,
OC_KEY_U = 85,
OC_KEY_V = 86,
OC_KEY_W = 87,
OC_KEY_X = 88,
OC_KEY_Y = 89,
OC_KEY_Z = 90,
OC_KEY_LEFT_BRACKET = 91, // [
OC_KEY_BACKSLASH = 92, // \ */
OC_KEY_RIGHT_BRACKET = 93, // ]
OC_KEY_GRAVE_ACCENT = 96, // `
OC_KEY_WORLD_1 = 161, // non-US #1
OC_KEY_WORLD_2 = 162, // non-US #2
OC_KEY_ESCAPE = 256,
OC_KEY_ENTER = 257,
OC_KEY_TAB = 258,
OC_KEY_BACKSPACE = 259,
OC_KEY_INSERT = 260,
OC_KEY_DELETE = 261,
OC_KEY_RIGHT = 262,
OC_KEY_LEFT = 263,
OC_KEY_DOWN = 264,
OC_KEY_UP = 265,
OC_KEY_PAGE_UP = 266,
OC_KEY_PAGE_DOWN = 267,
OC_KEY_HOME = 268,
OC_KEY_END = 269,
OC_KEY_CAPS_LOCK = 280,
OC_KEY_SCROLL_LOCK = 281,
OC_KEY_NUM_LOCK = 282,
OC_KEY_PRINT_SCREEN = 283,
OC_KEY_PAUSE = 284,
OC_KEY_F1 = 290,
OC_KEY_F2 = 291,
OC_KEY_F3 = 292,
OC_KEY_F4 = 293,
OC_KEY_F5 = 294,
OC_KEY_F6 = 295,
OC_KEY_F7 = 296,
OC_KEY_F8 = 297,
OC_KEY_F9 = 298,
OC_KEY_F10 = 299,
OC_KEY_F11 = 300,
OC_KEY_F12 = 301,
OC_KEY_F13 = 302,
OC_KEY_F14 = 303,
OC_KEY_F15 = 304,
OC_KEY_F16 = 305,
OC_KEY_F17 = 306,
OC_KEY_F18 = 307,
OC_KEY_F19 = 308,
OC_KEY_F20 = 309,
OC_KEY_F21 = 310,
OC_KEY_F22 = 311,
OC_KEY_F23 = 312,
OC_KEY_F24 = 313,
OC_KEY_F25 = 314,
OC_KEY_KP_0 = 320,
OC_KEY_KP_1 = 321,
OC_KEY_KP_2 = 322,
OC_KEY_KP_3 = 323,
OC_KEY_KP_4 = 324,
OC_KEY_KP_5 = 325,
OC_KEY_KP_6 = 326,
OC_KEY_KP_7 = 327,
OC_KEY_KP_8 = 328,
OC_KEY_KP_9 = 329,
OC_KEY_KP_DECIMAL = 330,
OC_KEY_KP_DIVIDE = 331,
OC_KEY_KP_MULTIPLY = 332,
OC_KEY_KP_SUBTRACT = 333,
OC_KEY_KP_ADD = 334,
OC_KEY_KP_ENTER = 335,
OC_KEY_KP_EQUAL = 336,
OC_KEY_LEFT_SHIFT = 340,
OC_KEY_LEFT_CONTROL = 341,
OC_KEY_LEFT_ALT = 342,
OC_KEY_LEFT_SUPER = 343,
OC_KEY_RIGHT_SHIFT = 344,
OC_KEY_RIGHT_CONTROL = 345,
OC_KEY_RIGHT_ALT = 346,
OC_KEY_RIGHT_SUPER = 347,
OC_KEY_MENU = 348,
OC_KEY_COUNT } oc_key_code;
typedef enum
{
OC_KEY_UNKNOWN = 0,
OC_KEY_SPACE = 32,
OC_KEY_APOSTROPHE = 39, /* ' */
OC_KEY_COMMA = 44, /* , */
OC_KEY_MINUS = 45, // -
OC_KEY_PERIOD = 46, // .
OC_KEY_SLASH = 47, // /
OC_KEY_0 = 48,
OC_KEY_1 = 49,
OC_KEY_2 = 50,
OC_KEY_3 = 51,
OC_KEY_4 = 52,
OC_KEY_5 = 53,
OC_KEY_6 = 54,
OC_KEY_7 = 55,
OC_KEY_8 = 56,
OC_KEY_9 = 57,
OC_KEY_SEMICOLON = 59, // ;
OC_KEY_EQUAL = 61, // =
OC_KEY_A = 65,
OC_KEY_B = 66,
OC_KEY_C = 67,
OC_KEY_D = 68,
OC_KEY_E = 69,
OC_KEY_F = 70,
OC_KEY_G = 71,
OC_KEY_H = 72,
OC_KEY_I = 73,
OC_KEY_J = 74,
OC_KEY_K = 75,
OC_KEY_L = 76,
OC_KEY_M = 77,
OC_KEY_N = 78,
OC_KEY_O = 79,
OC_KEY_P = 80,
OC_KEY_Q = 81,
OC_KEY_R = 82,
OC_KEY_S = 83,
OC_KEY_T = 84,
OC_KEY_U = 85,
OC_KEY_V = 86,
OC_KEY_W = 87,
OC_KEY_X = 88,
OC_KEY_Y = 89,
OC_KEY_Z = 90,
OC_KEY_LEFT_BRACKET = 91, // [
OC_KEY_BACKSLASH = 92, // \ */
OC_KEY_RIGHT_BRACKET = 93, // ]
OC_KEY_GRAVE_ACCENT = 96, // `
OC_KEY_WORLD_1 = 161, // non-US #1
OC_KEY_WORLD_2 = 162, // non-US #2
OC_KEY_ESCAPE = 256,
OC_KEY_ENTER = 257,
OC_KEY_TAB = 258,
OC_KEY_BACKSPACE = 259,
OC_KEY_INSERT = 260,
OC_KEY_DELETE = 261,
OC_KEY_RIGHT = 262,
OC_KEY_LEFT = 263,
OC_KEY_DOWN = 264,
OC_KEY_UP = 265,
OC_KEY_PAGE_UP = 266,
OC_KEY_PAGE_DOWN = 267,
OC_KEY_HOME = 268,
OC_KEY_END = 269,
OC_KEY_CAPS_LOCK = 280,
OC_KEY_SCROLL_LOCK = 281,
OC_KEY_NUM_LOCK = 282,
OC_KEY_PRINT_SCREEN = 283,
OC_KEY_PAUSE = 284,
OC_KEY_F1 = 290,
OC_KEY_F2 = 291,
OC_KEY_F3 = 292,
OC_KEY_F4 = 293,
OC_KEY_F5 = 294,
OC_KEY_F6 = 295,
OC_KEY_F7 = 296,
OC_KEY_F8 = 297,
OC_KEY_F9 = 298,
OC_KEY_F10 = 299,
OC_KEY_F11 = 300,
OC_KEY_F12 = 301,
OC_KEY_F13 = 302,
OC_KEY_F14 = 303,
OC_KEY_F15 = 304,
OC_KEY_F16 = 305,
OC_KEY_F17 = 306,
OC_KEY_F18 = 307,
OC_KEY_F19 = 308,
OC_KEY_F20 = 309,
OC_KEY_F21 = 310,
OC_KEY_F22 = 311,
OC_KEY_F23 = 312,
OC_KEY_F24 = 313,
OC_KEY_F25 = 314,
OC_KEY_KP_0 = 320,
OC_KEY_KP_1 = 321,
OC_KEY_KP_2 = 322,
OC_KEY_KP_3 = 323,
OC_KEY_KP_4 = 324,
OC_KEY_KP_5 = 325,
OC_KEY_KP_6 = 326,
OC_KEY_KP_7 = 327,
OC_KEY_KP_8 = 328,
OC_KEY_KP_9 = 329,
OC_KEY_KP_DECIMAL = 330,
OC_KEY_KP_DIVIDE = 331,
OC_KEY_KP_MULTIPLY = 332,
OC_KEY_KP_SUBTRACT = 333,
OC_KEY_KP_ADD = 334,
OC_KEY_KP_ENTER = 335,
OC_KEY_KP_EQUAL = 336,
OC_KEY_LEFT_SHIFT = 340,
OC_KEY_LEFT_CONTROL = 341,
OC_KEY_LEFT_ALT = 342,
OC_KEY_LEFT_SUPER = 343,
OC_KEY_RIGHT_SHIFT = 344,
OC_KEY_RIGHT_CONTROL = 345,
OC_KEY_RIGHT_ALT = 346,
OC_KEY_RIGHT_SUPER = 347,
OC_KEY_MENU = 348,
OC_KEY_COUNT
} oc_key_code;
typedef enum {
OC_KEYMOD_NONE = 0x00,
OC_KEYMOD_ALT = 0x01,
OC_KEYMOD_SHIFT = 0x02,
OC_KEYMOD_CTRL = 0x04,
OC_KEYMOD_CMD = 0x08,
OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ } oc_keymod_flags;
typedef enum
{
OC_KEYMOD_NONE = 0x00,
OC_KEYMOD_ALT = 0x01,
OC_KEYMOD_SHIFT = 0x02,
OC_KEYMOD_CTRL = 0x04,
OC_KEYMOD_CMD = 0x08,
OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */
} oc_keymod_flags;
typedef enum {
OC_MOUSE_LEFT = 0x00,
OC_MOUSE_RIGHT = 0x01,
OC_MOUSE_MIDDLE = 0x02,
OC_MOUSE_EXT1 = 0x03,
OC_MOUSE_EXT2 = 0x04,
OC_MOUSE_BUTTON_COUNT } oc_mouse_button;
typedef enum
{
OC_MOUSE_LEFT = 0x00,
OC_MOUSE_RIGHT = 0x01,
OC_MOUSE_MIDDLE = 0x02,
OC_MOUSE_EXT1 = 0x03,
OC_MOUSE_EXT2 = 0x04,
OC_MOUSE_BUTTON_COUNT
} oc_mouse_button;
typedef struct oc_key_event // keyboard and mouse buttons input
{
oc_key_action action;
i32 code;
oc_keymod_flags mods;
char label[8];
u8 labelLen;
int clickCount;
} oc_key_event;
typedef struct oc_key_event // keyboard and mouse buttons input
{
oc_key_action action;
i32 code;
oc_keymod_flags mods;
char label[8];
u8 labelLen;
int clickCount;
} oc_key_event;
typedef struct oc_char_event // character input
{
oc_utf32 codepoint;
char sequence[8];
u8 seqLen;
} oc_char_event;
typedef struct oc_char_event // character input
{
oc_utf32 codepoint;
char sequence[8];
u8 seqLen;
} oc_char_event;
typedef struct oc_mouse_event // mouse move/scroll
{
f32 x;
f32 y;
f32 deltaX;
f32 deltaY;
oc_keymod_flags mods;
} oc_mouse_event;
typedef struct oc_mouse_event // mouse move/scroll
{
f32 x;
f32 y;
f32 deltaX;
f32 deltaY;
oc_keymod_flags mods;
} oc_mouse_event;
typedef struct oc_move_event // window resize / move
{
oc_rect frame;
oc_rect content;
} oc_move_event;
typedef struct oc_move_event // window resize / move
{
oc_rect frame;
oc_rect content;
} oc_move_event;
typedef struct oc_event
{
//TODO clipboard and path drop
oc_window window;
oc_event_type type;
typedef struct oc_event
{
//TODO clipboard and path drop
oc_window window;
oc_event_type type;
union
{
oc_key_event key;
oc_char_event character;
oc_mouse_event mouse;
oc_move_event move;
oc_str8_list paths;
};
union
{
oc_key_event key;
oc_char_event character;
oc_mouse_event mouse;
oc_move_event move;
oc_str8_list paths;
};
} oc_event;
} oc_event;
//NOTE: these APIs are not directly available to Orca apps
#if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
//--------------------------------------------------------------------
// app management
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// app management
//--------------------------------------------------------------------
ORCA_API void oc_init(void);
ORCA_API void oc_terminate(void);
ORCA_API void oc_init(void);
ORCA_API void oc_terminate(void);
ORCA_API bool oc_should_quit(void);
ORCA_API void oc_cancel_quit(void);
ORCA_API void oc_request_quit(void);
ORCA_API bool oc_should_quit(void);
ORCA_API void oc_cancel_quit(void);
ORCA_API void oc_request_quit(void);
ORCA_API void oc_set_cursor(oc_mouse_cursor cursor);
ORCA_API void oc_set_cursor(oc_mouse_cursor cursor);
//--------------------------------------------------------------------
// Main loop and events handling
//--------------------------------------------------------------------
/*NOTE:
//--------------------------------------------------------------------
// Main loop and events handling
//--------------------------------------------------------------------
/*NOTE:
oc_pump_events() pumps system events into the event queue. A timeout of 0 polls for events,
while a timeout of -1 blocks for events. A timeout > 0 blocks until new events are available
or the timeout elapses.
oc_next_event() get the next event from the event queue, allocating from the passed arena
*/
ORCA_API void oc_pump_events(f64 timeout);
ORCA_API oc_event* oc_next_event(oc_arena* arena);
ORCA_API void oc_pump_events(f64 timeout);
ORCA_API oc_event* oc_next_event(oc_arena* arena);
typedef void(*oc_live_resize_callback)(oc_event event, void* data);
ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data);
typedef void (*oc_live_resize_callback)(oc_event event, void* data);
ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data);
//--------------------------------------------------------------------
// window management
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// window management
//--------------------------------------------------------------------
ORCA_API bool oc_window_handle_is_null(oc_window window);
ORCA_API oc_window oc_window_null_handle(void);
ORCA_API bool oc_window_handle_is_null(oc_window window);
ORCA_API oc_window oc_window_null_handle(void);
ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style);
ORCA_API void oc_window_destroy(oc_window window);
ORCA_API void* oc_window_native_pointer(oc_window window);
ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style);
ORCA_API void oc_window_destroy(oc_window window);
ORCA_API void* oc_window_native_pointer(oc_window window);
ORCA_API bool oc_window_should_close(oc_window window);
ORCA_API void oc_window_request_close(oc_window window);
ORCA_API void oc_window_cancel_close(oc_window window);
ORCA_API bool oc_window_should_close(oc_window window);
ORCA_API void oc_window_request_close(oc_window window);
ORCA_API void oc_window_cancel_close(oc_window window);
ORCA_API bool oc_window_is_hidden(oc_window window);
ORCA_API void oc_window_hide(oc_window window);
ORCA_API void oc_window_show(oc_window window);
ORCA_API bool oc_window_is_hidden(oc_window window);
ORCA_API void oc_window_hide(oc_window window);
ORCA_API void oc_window_show(oc_window window);
ORCA_API bool oc_window_is_minimized(oc_window window);
ORCA_API bool oc_window_is_maximized(oc_window window);
ORCA_API void oc_window_minimize(oc_window window);
ORCA_API void oc_window_maximize(oc_window window);
ORCA_API void oc_window_restore(oc_window window);
ORCA_API bool oc_window_is_minimized(oc_window window);
ORCA_API bool oc_window_is_maximized(oc_window window);
ORCA_API void oc_window_minimize(oc_window window);
ORCA_API void oc_window_maximize(oc_window window);
ORCA_API void oc_window_restore(oc_window window);
ORCA_API bool oc_window_has_focus(oc_window window);
ORCA_API void oc_window_focus(oc_window window);
ORCA_API void oc_window_unfocus(oc_window window);
ORCA_API bool oc_window_has_focus(oc_window window);
ORCA_API void oc_window_focus(oc_window window);
ORCA_API void oc_window_unfocus(oc_window window);
ORCA_API void oc_window_send_to_back(oc_window window);
ORCA_API void oc_window_bring_to_front(oc_window window);
ORCA_API void oc_window_send_to_back(oc_window window);
ORCA_API void oc_window_bring_to_front(oc_window window);
ORCA_API oc_rect oc_window_get_frame_rect(oc_window window);
ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect);
ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position);
ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size);
ORCA_API oc_rect oc_window_get_frame_rect(oc_window window);
ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect);
ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position);
ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size);
ORCA_API oc_rect oc_window_get_content_rect(oc_window window);
ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect);
ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position);
ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size);
ORCA_API oc_rect oc_window_get_content_rect(oc_window window);
ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect);
ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position);
ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size);
ORCA_API void oc_window_center(oc_window window);
ORCA_API void oc_window_center(oc_window window);
ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style);
ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style);
ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style);
ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style);
//---------------------------------------------------------------
// Dispatching stuff to the main thread
//---------------------------------------------------------------
//---------------------------------------------------------------
// Dispatching stuff to the main thread
//---------------------------------------------------------------
typedef i32 (*oc_dispatch_proc)(void* user);
typedef i32 (*oc_dispatch_proc)(void* user);
ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user);
ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user);
//--------------------------------------------------------------------
// Clipboard
//--------------------------------------------------------------------
ORCA_API void oc_clipboard_clear(void);
//--------------------------------------------------------------------
// Clipboard
//--------------------------------------------------------------------
ORCA_API void oc_clipboard_clear(void);
ORCA_API void oc_clipboard_set_string(oc_str8 string);
ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena);
ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing);
ORCA_API void oc_clipboard_set_string(oc_str8 string);
ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena);
ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing);
ORCA_API bool oc_clipboard_has_tag(const char* tag);
ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data);
ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag);
ORCA_API bool oc_clipboard_has_tag(const char* tag);
ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data);
ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag);
//--------------------------------------------------------------------
// native open/save/alert windows
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// native open/save/alert windows
//--------------------------------------------------------------------
ORCA_API oc_str8 oc_open_dialog(oc_arena* arena,
oc_str8 title,
oc_str8 defaultPath,
oc_str8_list filters,
bool directory);
ORCA_API oc_str8 oc_open_dialog(oc_arena* arena,
oc_str8 title,
oc_str8 defaultPath,
oc_str8_list filters,
bool directory);
ORCA_API oc_str8 oc_save_dialog(oc_arena* arena,
oc_str8 title,
oc_str8 defaultPath,
oc_str8_list filters);
ORCA_API oc_str8 oc_save_dialog(oc_arena* arena,
oc_str8 title,
oc_str8 defaultPath,
oc_str8_list filters);
ORCA_API int oc_alert_popup(oc_str8 title,
oc_str8 message,
oc_str8_list options);
ORCA_API int oc_alert_popup(oc_str8 title,
oc_str8 message,
oc_str8_list options);
//--------------------------------------------------------------------
// file system stuff... //TODO: move elsewhere
//--------------------------------------------------------------------
ORCA_API int oc_file_move(oc_str8 from, oc_str8 to);
ORCA_API int oc_file_remove(oc_str8 path);
//--------------------------------------------------------------------
// file system stuff... //TODO: move elsewhere
//--------------------------------------------------------------------
ORCA_API int oc_file_move(oc_str8 from, oc_str8 to);
ORCA_API int oc_file_remove(oc_str8 path);
ORCA_API int oc_directory_create(oc_str8 path);
ORCA_API int oc_directory_create(oc_str8 path);
#endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
@ -388,5 +406,4 @@ ORCA_API int oc_directory_create(oc_str8 path);
} // extern "C"
#endif
#endif //__APP_H_

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: app_internal.h
* @author: Martin Fouilleul
@ -9,17 +9,17 @@
#ifndef __APP_INTERNAL_H_
#define __APP_INTERNAL_H_
#include"app.h"
#include "app.h"
#include"platform/platform.h"
#include"util/ringbuffer.h"
#include "platform/platform.h"
#include "util/ringbuffer.h"
#if OC_PLATFORM_WINDOWS
#include"win32_app.h"
#include "win32_app.h"
#elif OC_PLATFORM_MACOS
#include"osx_app.h"
#include "osx_app.h"
#else
#error "platform not supported yet"
#error "platform not supported yet"
#endif
//---------------------------------------------------------------
@ -28,64 +28,65 @@
typedef struct oc_frame_stats
{
f64 start;
f64 workTime;
f64 remainingTime;
f64 targetFramePeriod;
f64 start;
f64 workTime;
f64 remainingTime;
f64 targetFramePeriod;
} oc_frame_stats;
typedef struct oc_window_data
{
oc_list_elt freeListElt;
u32 generation;
oc_list_elt freeListElt;
u32 generation;
oc_window_style style;
oc_window_style style;
bool shouldClose; //TODO could be in status flags
bool hidden;
bool minimized;
bool shouldClose; //TODO could be in status flags
bool hidden;
bool minimized;
OC_PLATFORM_WINDOW_DATA
OC_PLATFORM_WINDOW_DATA
} oc_window_data;
//---------------------------------------------------------------
// Global App State
//---------------------------------------------------------------
typedef struct oc_key_utf8
{
u8 labelLen;
char label[8];
u8 labelLen;
char label[8];
} oc_key_utf8;
enum { OC_APP_MAX_WINDOWS = 128 };
enum
{
OC_APP_MAX_WINDOWS = 128
};
typedef struct oc_app
{
bool init;
bool shouldQuit;
bool minimized;
bool init;
bool shouldQuit;
bool minimized;
oc_str8 pendingPathDrop;
oc_arena eventArena;
oc_str8 pendingPathDrop;
oc_arena eventArena;
oc_ringbuffer eventQueue;
oc_ringbuffer eventQueue;
oc_frame_stats frameStats;
oc_frame_stats frameStats;
oc_window_data windowPool[OC_APP_MAX_WINDOWS];
oc_list windowFreeList;
oc_window_data windowPool[OC_APP_MAX_WINDOWS];
oc_list windowFreeList;
oc_live_resize_callback liveResizeCallback;
void* liveResizeData;
oc_live_resize_callback liveResizeCallback;
void* liveResizeData;
oc_key_utf8 keyLabels[512];
int keyCodes[512];
int nativeKeys[OC_KEY_COUNT];
oc_key_utf8 keyLabels[512];
int keyCodes[512];
int nativeKeys[OC_KEY_COUNT];
OC_PLATFORM_APP_DATA
OC_PLATFORM_APP_DATA
} oc_app;
#endif // __APP_INTERNAL_H_

View File

@ -1,4 +1,4 @@
#include"orca.h"
#include "orca.h"
//This is used to pass raw events from the runtime
ORCA_EXPORT oc_event oc_rawEvent;

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: osx_app.h
* @author: Martin Fouilleul
@ -9,28 +9,28 @@
#ifndef __OSX_APP_H_
#define __OSX_APP_H_
#include"app.h"
#include"graphics/graphics.h"
#include "app.h"
#include "graphics/graphics.h"
#ifdef __OBJC__
#import<Cocoa/Cocoa.h>
#import <Cocoa/Cocoa.h>
#else
#define NSWindow void
#define NSView void
#define NSObject void
#define NSTimer void
#define NSCursor void
#define CALayer void
#define CAContext void
#define NSWindow void
#define NSView void
#define NSObject void
#define NSTimer void
#define NSCursor void
#define CALayer void
#define CAContext void
#endif
#include<Carbon/Carbon.h>
#include <Carbon/Carbon.h>
typedef struct oc_osx_window_data
{
NSWindow* nsWindow;
NSView* nsView;
NSObject* nsWindowDelegate;
NSWindow* nsWindow;
NSView* nsView;
NSObject* nsWindowDelegate;
} oc_osx_window_data;
@ -40,12 +40,12 @@ const u32 OC_APP_MAX_VIEWS = 128;
typedef struct oc_osx_app_data
{
NSTimer* frameTimer;
NSCursor* cursor;
NSTimer* frameTimer;
NSCursor* cursor;
TISInputSourceRef kbLayoutInputSource;
void* kbLayoutUnicodeData;
id kbLayoutListener;
TISInputSourceRef kbLayoutInputSource;
void* kbLayoutUnicodeData;
id kbLayoutListener;
} oc_osx_app_data;
@ -55,33 +55,31 @@ typedef struct oc_osx_app_data
// Surface layer
//-----------------------------------------------
#ifdef __OBJC__
//NOTE: these private interfaces for surface sharing need to be declared explicitly here
typedef uint32_t CGSConnectionID;
CGSConnectionID CGSMainConnectionID(void);
//NOTE: these private interfaces for surface sharing need to be declared explicitly here
typedef uint32_t CGSConnectionID;
CGSConnectionID CGSMainConnectionID(void);
typedef uint32_t CAContextID;
typedef uint32_t CAContextID;
@interface CAContext : NSObject
{
}
+ (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict;
@property(readonly) CAContextID contextId;
@property(retain) CALayer *layer;
@end
@interface CAContext : NSObject
{
}
+ (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict;
@property(readonly) CAContextID contextId;
@property(retain) CALayer* layer;
@end
@interface CALayerHost : CALayer
{
}
@property CAContextID contextId;
@end
@interface CALayerHost : CALayer
{
}
@property CAContextID contextId;
@end
#endif
typedef struct oc_layer
{
CALayer* caLayer;
CAContext* caContext;
CALayer* caLayer;
CAContext* caContext;
} oc_layer;
#endif //__OSX_APP_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,37 +10,37 @@
#ifndef __WIN32_APP_H_
#define __WIN32_APP_H_
#include"app.h"
#include "app.h"
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include<windows.h>
#include <windows.h>
typedef struct oc_win32_window_data
{
HWND hWnd;
oc_list layers;
HWND hWnd;
oc_list layers;
} oc_win32_window_data;
typedef struct oc_window_data oc_window_data;
typedef struct oc_layer
{
oc_window_data* parent;
oc_list_elt listElt;
HWND hWnd;
oc_window_data* parent;
oc_list_elt listElt;
HWND hWnd;
} oc_layer;
#define OC_PLATFORM_WINDOW_DATA oc_win32_window_data win32;
typedef struct oc_win32_app_data
{
u32 savedConsoleCodePage;
u32 savedConsoleCodePage;
int mouseCaptureMask;
bool mouseTracked;
oc_vec2 lastMousePos;
u32 wheelScrollLines;
int mouseCaptureMask;
bool mouseTracked;
oc_vec2 lastMousePos;
u32 wheelScrollLines;
} oc_win32_app_data;
@ -48,7 +48,7 @@ typedef struct oc_win32_app_data
enum OC_WM_USER
{
OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF
OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF
};
#endif __WIN32_APP_H_

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: egl_surface.cpp
* @author: Martin Fouilleul
@ -8,176 +8,178 @@
*****************************************************************/
#define EGL_EGLEXT_PROTOTYPES
#include<EGL/egl.h>
#include<EGL/eglext.h>
#include"app/app_internal.h"
#include"graphics_surface.h"
#include"gl_loader.h"
#include "app/app_internal.h"
#include "gl_loader.h"
#include "graphics_surface.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#if OC_PLATFORM_MACOS
//NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly
#define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE
//NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly
#define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE
//NOTE: hardcode GLES versions for now
//TODO: use version hints, once we have all api versions correctly categorized by glapi.py
#define OC_GLES_VERSION_MAJOR 3
#define OC_GLES_VERSION_MINOR 0
#define oc_gl_load_gles oc_gl_load_gles31
//NOTE: hardcode GLES versions for now
//TODO: use version hints, once we have all api versions correctly categorized by glapi.py
#define OC_GLES_VERSION_MAJOR 3
#define OC_GLES_VERSION_MINOR 0
#define oc_gl_load_gles oc_gl_load_gles31
#else
#define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE
#define OC_GLES_VERSION_MAJOR 3
#define OC_GLES_VERSION_MINOR 1
#define oc_gl_load_gles oc_gl_load_gles32
#define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE
#define OC_GLES_VERSION_MAJOR 3
#define OC_GLES_VERSION_MINOR 1
#define oc_gl_load_gles oc_gl_load_gles32
#endif
typedef struct oc_egl_surface
{
oc_surface_data interface;
oc_surface_data interface;
EGLDisplay eglDisplay;
EGLConfig eglConfig;
EGLContext eglContext;
EGLSurface eglSurface;
EGLDisplay eglDisplay;
EGLConfig eglConfig;
EGLContext eglContext;
EGLSurface eglSurface;
oc_gl_api api;
oc_gl_api api;
} oc_egl_surface;
void oc_egl_surface_destroy(oc_surface_data* interface)
{
oc_egl_surface* surface = (oc_egl_surface*)interface;
oc_egl_surface* surface = (oc_egl_surface*)interface;
if(&surface->api == oc_gl_get_api())
{
oc_gl_deselect_api();
}
if(eglGetCurrentContext() == surface->eglContext)
{
eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
eglDestroyContext(surface->eglDisplay, surface->eglContext);
eglDestroySurface(surface->eglDisplay, surface->eglSurface);
if(&surface->api == oc_gl_get_api())
{
oc_gl_deselect_api();
}
if(eglGetCurrentContext() == surface->eglContext)
{
eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
eglDestroyContext(surface->eglDisplay, surface->eglContext);
eglDestroySurface(surface->eglDisplay, surface->eglSurface);
oc_surface_cleanup((oc_surface_data*)surface);
free(surface);
oc_surface_cleanup((oc_surface_data*)surface);
free(surface);
}
void oc_egl_surface_prepare(oc_surface_data* interface)
{
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext);
oc_gl_select_api(&surface->api);
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext);
oc_gl_select_api(&surface->api);
}
void oc_egl_surface_present(oc_surface_data* interface)
{
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglSwapBuffers(surface->eglDisplay, surface->eglSurface);
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglSwapBuffers(surface->eglDisplay, surface->eglSurface);
}
void oc_egl_surface_deselect(oc_surface_data* interface)
{
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
oc_gl_deselect_api();
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
oc_gl_deselect_api();
}
void oc_egl_surface_swap_interval(oc_surface_data* interface, int swap)
{
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglSwapInterval(surface->eglDisplay, swap);
oc_egl_surface* surface = (oc_egl_surface*)interface;
eglSwapInterval(surface->eglDisplay, swap);
}
void oc_egl_surface_init(oc_egl_surface* surface)
{
void* nativeLayer = surface->interface.nativeLayer((oc_surface_data*)surface);
void* nativeLayer = surface->interface.nativeLayer((oc_surface_data*)surface);
surface->interface.api = OC_GLES;
surface->interface.api = OC_GLES;
surface->interface.destroy = oc_egl_surface_destroy;
surface->interface.prepare = oc_egl_surface_prepare;
surface->interface.present = oc_egl_surface_present;
surface->interface.deselect = oc_egl_surface_deselect;
surface->interface.swapInterval = oc_egl_surface_swap_interval;
surface->interface.destroy = oc_egl_surface_destroy;
surface->interface.prepare = oc_egl_surface_prepare;
surface->interface.present = oc_egl_surface_present;
surface->interface.deselect = oc_egl_surface_deselect;
surface->interface.swapInterval = oc_egl_surface_swap_interval;
EGLAttrib displayAttribs[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
EGL_NONE};
EGLAttrib displayAttribs[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
EGL_NONE
};
surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs);
eglInitialize(surface->eglDisplay, NULL, NULL);
surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs);
eglInitialize(surface->eglDisplay, NULL, NULL);
EGLint const configAttributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, EGL_DONT_CARE,
EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
EGL_NONE };
EGLint const configAttributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, EGL_DONT_CARE,
EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
EGL_NONE
};
int numConfigs = 0;
eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs);
int numConfigs = 0;
eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs);
EGLint const surfaceAttributes[] = {EGL_NONE};
surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay,
surface->eglConfig,
nativeLayer,
surfaceAttributes);
EGLint const surfaceAttributes[] = { EGL_NONE };
surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay,
surface->eglConfig,
nativeLayer,
surfaceAttributes);
eglBindAPI(EGL_OPENGL_ES_API);
EGLint contextAttributes[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, OC_GLES_VERSION_MAJOR,
EGL_CONTEXT_MINOR_VERSION_KHR, OC_GLES_VERSION_MINOR,
EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE,
EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE,
EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE,
EGL_NONE};
eglBindAPI(EGL_OPENGL_ES_API);
EGLint contextAttributes[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, OC_GLES_VERSION_MAJOR,
EGL_CONTEXT_MINOR_VERSION_KHR, OC_GLES_VERSION_MINOR,
EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE,
EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE,
EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE,
EGL_NONE
};
surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes);
eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext);
surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes);
eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext);
oc_gl_load_gles(&surface->api, (oc_gl_load_proc)eglGetProcAddress);
oc_gl_load_gles(&surface->api, (oc_gl_load_proc)eglGetProcAddress);
eglSwapInterval(surface->eglDisplay, 1);
eglSwapInterval(surface->eglDisplay, 1);
}
oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height)
{
oc_egl_surface* surface = 0;
oc_egl_surface* surface = 0;
surface = oc_malloc_type(oc_egl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_egl_surface));
surface = oc_malloc_type(oc_egl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_egl_surface));
oc_surface_init_remote((oc_surface_data*)surface, width, height);
oc_egl_surface_init(surface);
}
oc_surface_init_remote((oc_surface_data*)surface, width, height);
oc_egl_surface_init(surface);
}
return((oc_surface_data*)surface);
return ((oc_surface_data*)surface);
}
oc_surface_data* oc_egl_surface_create_for_window(oc_window window)
{
oc_egl_surface* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
surface = oc_malloc_type(oc_egl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_egl_surface));
oc_egl_surface* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
surface = oc_malloc_type(oc_egl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_egl_surface));
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
oc_egl_surface_init(surface);
}
}
return((oc_surface_data*)surface);
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
oc_egl_surface_init(surface);
}
}
return ((oc_surface_data*)surface);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: egl_surface.h
* @author: Martin Fouilleul
@ -9,8 +9,8 @@
#ifndef __EGL_SURFACE_H_
#define __EGL_SURFACE_H_
#include"graphics_surface.h"
#include"app/app.h"
#include "app/app.h"
#include "graphics_surface.h"
oc_surface_data* oc_egl_surface_create_for_window(oc_window window);
oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
#ifndef __GL_LOADER_H__
#define __GL_LOADER_H__
#include"gl_api.h"
#include "gl_api.h"
typedef void*(*oc_gl_load_proc)(const char* name);
typedef void* (*oc_gl_load_proc)(const char* name);
void oc_gl_load_gl41(oc_gl_api* api, oc_gl_load_proc loadProc);
void oc_gl_load_gl43(oc_gl_api* api, oc_gl_load_proc loadProc);

View File

@ -6,13 +6,17 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathQueueBufferSSBO
{
oc_gl_path_queue elements[];
} pathQueueBuffer;
oc_gl_path_queue elements[];
}
pathQueueBuffer;
layout(binding = 1) restrict buffer tileQueueBufferSSBO
{
oc_gl_tile_queue elements[];
} tileQueueBuffer;
oc_gl_tile_queue elements[];
}
tileQueueBuffer;
layout(location = 0) uniform int pathQueueBufferStart;
@ -20,32 +24,32 @@ shared int nextRowIndex;
void main()
{
int pathIndex = int(gl_WorkGroupID.x);
int localID = int(gl_LocalInvocationID.x);
int pathIndex = int(gl_WorkGroupID.x);
int localID = int(gl_LocalInvocationID.x);
if(localID == 0)
{
nextRowIndex = 0;
}
barrier();
if(localID == 0)
{
nextRowIndex = 0;
}
barrier();
int rowIndex = 0;
oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathQueueBufferStart + pathIndex];
int tileQueueBase = pathQueue.tileQueues;
int rowSize = pathQueue.area.z;
int rowCount = pathQueue.area.w;
int rowIndex = 0;
oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathQueueBufferStart + pathIndex];
int tileQueueBase = pathQueue.tileQueues;
int rowSize = pathQueue.area.z;
int rowCount = pathQueue.area.w;
rowIndex = atomicAdd(nextRowIndex, 1);
while(rowIndex < rowCount)
{
int sum = 0;
for(int x = rowSize-1; x >= 0; x--)
{
int tileIndex = tileQueueBase + rowIndex * rowSize.x + x;
int offset = tileQueueBuffer.elements[tileIndex].windingOffset;
tileQueueBuffer.elements[tileIndex].windingOffset = sum;
sum += offset;
}
rowIndex = atomicAdd(nextRowIndex, 1);
}
rowIndex = atomicAdd(nextRowIndex, 1);
while(rowIndex < rowCount)
{
int sum = 0;
for(int x = rowSize - 1; x >= 0; x--)
{
int tileIndex = tileQueueBase + rowIndex * rowSize.x + x;
int offset = tileQueueBuffer.elements[tileIndex].windingOffset;
tileQueueBuffer.elements[tileIndex].windingOffset = sum;
sum += offset;
}
rowIndex = atomicAdd(nextRowIndex, 1);
}
}

View File

@ -6,22 +6,25 @@ layout(std430) buffer;
layout(binding = 0) coherent restrict readonly buffer screenTilesCountBufferSSBO
{
int elements[];
} screenTilesCountBuffer;
int elements[];
}
screenTilesCountBuffer;
layout(binding = 1) coherent restrict writeonly buffer dispatchBufferSSBO
{
oc_gl_dispatch_indirect_command elements[];
} dispatchBuffer;
oc_gl_dispatch_indirect_command elements[];
}
dispatchBuffer;
layout(location = 0) uniform uint maxWorkGroupCount;
void main()
{
uint totalWorkGroupCount = screenTilesCountBuffer.elements[0];
uint totalWorkGroupCount = screenTilesCountBuffer.elements[0];
dispatchBuffer.elements[0].num_groups_x = totalWorkGroupCount > maxWorkGroupCount ? maxWorkGroupCount : totalWorkGroupCount;
dispatchBuffer.elements[0].num_groups_y = (totalWorkGroupCount + maxWorkGroupCount - 1) / maxWorkGroupCount;
dispatchBuffer.elements[0].num_groups_z = 1;
dispatchBuffer.elements[0].num_groups_x = totalWorkGroupCount > maxWorkGroupCount ? maxWorkGroupCount : totalWorkGroupCount;
dispatchBuffer.elements[0].num_groups_y = (totalWorkGroupCount + maxWorkGroupCount - 1) / maxWorkGroupCount;
dispatchBuffer.elements[0].num_groups_z = 1;
}

View File

@ -4,9 +4,9 @@ precision mediump float;
in vec2 uv;
out vec4 fragColor;
layout(location=0) uniform sampler2D tex;
layout(location = 0) uniform sampler2D tex;
void main()
{
fragColor = texture(tex, uv);
fragColor = texture(tex, uv);
}

View File

@ -5,11 +5,11 @@ out vec2 uv;
void main()
{
/* generate (0, 0) (1, 0) (1, 1) (1, 1) (0, 1) (0, 0)*/
/* generate (0, 0) (1, 0) (1, 1) (1, 1) (0, 1) (0, 0)*/
float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);
float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);
float x = float(((uint(gl_VertexID) + 2u) / 3u) % 2u);
float y = float(((uint(gl_VertexID) + 1u) / 3u) % 2u);
gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f);
uv = vec2(x, 1-y);
gl_Position = vec4(-1.0f + x * 2.0f, -1.0f + y * 2.0f, 0.0f, 1.0f);
uv = vec2(x, 1 - y);
}

View File

@ -11,17 +11,17 @@ layout(std430) buffer;
#define OC_GL_CUBIC 3
// curve config
#define OC_GL_BL 1 /* curve on bottom left */
#define OC_GL_BL 1 /* curve on bottom left */
#define OC_GL_BR 2 /* curve on bottom right */
#define OC_GL_TL 3 /* curve on top left */
#define OC_GL_TR 4 /* curve on top right */
#define OC_GL_TR 4 /* curve on top right */
// Operations
#define OC_GL_OP_FILL 0
#define OC_GL_OP_FILL 0
#define OC_GL_OP_CLIP_FILL 1
#define OC_GL_OP_START 2
#define OC_GL_OP_END 3
#define OC_GL_OP_SEGMENT 4
#define OC_GL_OP_START 2
#define OC_GL_OP_END 3
#define OC_GL_OP_SEGMENT 4
// MSAA
#define OC_GL_MAX_SAMPLE_COUNT 8
@ -29,158 +29,160 @@ layout(std430) buffer;
struct oc_gl_path
{
mat3 uvTransform;
vec4 color;
vec4 box;
vec4 clip;
int cmd;
int textureID;
mat3 uvTransform;
vec4 color;
vec4 box;
vec4 clip;
int cmd;
int textureID;
};
struct oc_gl_path_elt
{
vec2 p[4];
int pathIndex;
int kind;
vec2 p[4];
int pathIndex;
int kind;
};
struct oc_gl_segment
{
int kind;
int pathIndex;
int config;
int windingIncrement;
vec4 box;
mat3 implicitMatrix;
vec2 hullVertex;
float sign;
int kind;
int pathIndex;
int config;
int windingIncrement;
vec4 box;
mat3 implicitMatrix;
vec2 hullVertex;
float sign;
};
struct oc_gl_path_queue
{
ivec4 area;
int tileQueues;
ivec4 area;
int tileQueues;
};
struct oc_gl_tile_op
{
int kind;
int next;
int index;
int windingOffsetOrCrossRight;
int kind;
int next;
int index;
int windingOffsetOrCrossRight;
};
struct oc_gl_tile_queue
{
int windingOffset;
int first;
int last;
int windingOffset;
int first;
int last;
};
struct oc_gl_screen_tile
{
uvec2 tileCoord;
int first;
uvec2 tileCoord;
int first;
};
struct oc_gl_dispatch_indirect_command
{
uint num_groups_x;
uint num_groups_y;
uint num_groups_z;
uint num_groups_x;
uint num_groups_y;
uint num_groups_z;
};
float ccw(vec2 a, vec2 b, vec2 c)
{
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));
}
int side_of_segment(vec2 p, oc_gl_segment seg)
{
int side = 0;
if(p.y > seg.box.w || p.y <= seg.box.y)
{
if(p.x > seg.box.x && p.x <= seg.box.z)
{
if(p.y > seg.box.w)
{
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? -1 : 1;
}
else
{
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? 1 : -1;
}
}
}
else if(p.x > seg.box.z)
{
side = 1;
}
else if(p.x <= seg.box.x)
{
side = -1;
}
else
{
vec2 a, b, c;
switch(seg.config)
{
case OC_GL_TL:
a = seg.box.xy;
b = seg.box.zw;
break;
int side = 0;
if(p.y > seg.box.w || p.y <= seg.box.y)
{
if(p.x > seg.box.x && p.x <= seg.box.z)
{
if(p.y > seg.box.w)
{
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? -1 : 1;
}
else
{
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? 1 : -1;
}
}
}
else if(p.x > seg.box.z)
{
side = 1;
}
else if(p.x <= seg.box.x)
{
side = -1;
}
else
{
vec2 a, b, c;
switch(seg.config)
{
case OC_GL_TL:
a = seg.box.xy;
b = seg.box.zw;
break;
case OC_GL_BR:
a = seg.box.zw;
b = seg.box.xy;
break;
case OC_GL_BR:
a = seg.box.zw;
b = seg.box.xy;
break;
case OC_GL_TR:
a = seg.box.xw;
b = seg.box.zy;
break;
case OC_GL_TR:
a = seg.box.xw;
b = seg.box.zy;
break;
case OC_GL_BL:
a = seg.box.zy;
b = seg.box.xw;
break;
}
c = seg.hullVertex;
case OC_GL_BL:
a = seg.box.zy;
b = seg.box.xw;
break;
}
c = seg.hullVertex;
if(ccw(a, b, p) < 0)
{
// other side of the diagonal
side = (seg.config == OC_GL_BR || seg.config == OC_GL_TR) ? -1 : 1;
}
else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0)
{
// same side of the diagonal, but outside curve hull
side = (seg.config == OC_GL_BL || seg.config == OC_GL_TL) ? -1 : 1;
}
else
{
// inside curve hull
switch(seg.kind)
{
case OC_GL_LINE:
side = 1;
break;
if(ccw(a, b, p) < 0)
{
// other side of the diagonal
side = (seg.config == OC_GL_BR || seg.config == OC_GL_TR) ? -1 : 1;
}
else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0)
{
// same side of the diagonal, but outside curve hull
side = (seg.config == OC_GL_BL || seg.config == OC_GL_TL) ? -1 : 1;
}
else
{
// inside curve hull
switch(seg.kind)
{
case OC_GL_LINE:
side = 1;
break;
case OC_GL_QUADRATIC:
{
vec3 ph = {p.x, p.y, 1};
vec3 klm = seg.implicitMatrix * ph;
side = ((klm.x*klm.x - klm.y)*klm.z < 0)? -1 : 1;
} break;
case OC_GL_QUADRATIC:
{
vec3 ph = { p.x, p.y, 1 };
vec3 klm = seg.implicitMatrix * ph;
side = ((klm.x * klm.x - klm.y) * klm.z < 0) ? -1 : 1;
}
break;
case OC_GL_CUBIC:
{
vec3 ph = {p.x, p.y, 1};
vec3 klm = seg.implicitMatrix * ph;
side = (seg.sign*(klm.x*klm.x*klm.x - klm.y*klm.z) < 0)? -1 : 1;
} break;
}
}
}
return(side);
case OC_GL_CUBIC:
{
vec3 ph = { p.x, p.y, 1 };
vec3 klm = seg.implicitMatrix * ph;
side = (seg.sign * (klm.x * klm.x * klm.x - klm.y * klm.z) < 0) ? -1 : 1;
}
break;
}
}
}
return (side);
}

View File

@ -6,39 +6,52 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO
{
oc_gl_path elements[];
} pathBuffer;
oc_gl_path elements[];
}
pathBuffer;
layout(binding = 1) restrict readonly buffer pathQueueBufferSSBO
{
oc_gl_path_queue elements[];
} pathQueueBuffer;
oc_gl_path_queue elements[];
}
pathQueueBuffer;
layout(binding = 2) restrict readonly buffer tileQueueBufferSSBO
{
oc_gl_tile_queue elements[];
} tileQueueBuffer;
oc_gl_tile_queue elements[];
}
tileQueueBuffer;
layout(binding = 3) coherent restrict buffer tileOpCountBufferSSBO
{
int elements[];
} tileOpCountBuffer;
int elements[];
}
tileOpCountBuffer;
layout(binding = 4) restrict buffer tileOpBufferSSBO
{
oc_gl_tile_op elements[];
} tileOpBuffer;
oc_gl_tile_op elements[];
}
tileOpBuffer;
layout(binding = 5) restrict writeonly buffer screenTilesBufferSSBO
{
oc_gl_screen_tile elements[];
} screenTilesBuffer;
oc_gl_screen_tile elements[];
}
screenTilesBuffer;
layout(binding = 6) coherent restrict buffer screenTilesCountBufferSSBO
{
int elements[];
} screenTilesCountBuffer;
int elements[];
}
screenTilesCountBuffer;
layout(location = 0) uniform int tileSize;
layout(location = 1) uniform float scale;
@ -47,147 +60,147 @@ layout(location = 3) uniform int pathBufferStart;
void main()
{
ivec2 tileCoord = ivec2(gl_WorkGroupID.xy);
int tileIndex = -1;
ivec2 tileCoord = ivec2(gl_WorkGroupID.xy);
int tileIndex = -1;
int lastOpIndex = -1;
int lastOpIndex = -1;
for(int pathIndex = 0; pathIndex < pathCount; pathIndex++)
{
oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathIndex];
ivec2 pathTileCoord = tileCoord - pathQueue.area.xy;
for(int pathIndex = 0; pathIndex < pathCount; pathIndex++)
{
oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathIndex];
ivec2 pathTileCoord = tileCoord - pathQueue.area.xy;
vec4 pathBox = pathBuffer.elements[pathBufferStart + pathIndex].box;
vec4 pathClip = pathBuffer.elements[pathBufferStart + pathIndex].clip;
vec4 pathBox = pathBuffer.elements[pathBufferStart + pathIndex].box;
vec4 pathClip = pathBuffer.elements[pathBufferStart + pathIndex].clip;
float xMax = min(pathBox.z, pathClip.z);
int tileMax = int(xMax * scale) / tileSize;
int pathTileMax = tileMax - pathQueue.area.x;
float xMax = min(pathBox.z, pathClip.z);
int tileMax = int(xMax * scale) / tileSize;
int pathTileMax = tileMax - pathQueue.area.x;
if( pathTileCoord.x >= 0
&& pathTileCoord.x <= pathTileMax
&& pathTileCoord.y >= 0
&& pathTileCoord.y < pathQueue.area.w)
{
if(tileIndex < 0)
{
tileIndex = int(atomicAdd(screenTilesCountBuffer.elements[0], 1));
screenTilesBuffer.elements[tileIndex].tileCoord = uvec2(tileCoord);
screenTilesBuffer.elements[tileIndex].first = -1;
}
if(pathTileCoord.x >= 0
&& pathTileCoord.x <= pathTileMax
&& pathTileCoord.y >= 0
&& pathTileCoord.y < pathQueue.area.w)
{
if(tileIndex < 0)
{
tileIndex = int(atomicAdd(screenTilesCountBuffer.elements[0], 1));
screenTilesBuffer.elements[tileIndex].tileCoord = uvec2(tileCoord);
screenTilesBuffer.elements[tileIndex].first = -1;
}
int pathTileIndex = pathQueue.tileQueues + pathTileCoord.y * pathQueue.area.z + pathTileCoord.x;
oc_gl_tile_queue tileQueue = tileQueueBuffer.elements[pathTileIndex];
int pathTileIndex = pathQueue.tileQueues + pathTileCoord.y * pathQueue.area.z + pathTileCoord.x;
oc_gl_tile_queue tileQueue = tileQueueBuffer.elements[pathTileIndex];
int windingOffset = tileQueue.windingOffset;
int firstOpIndex = tileQueue.first;
int windingOffset = tileQueue.windingOffset;
int firstOpIndex = tileQueue.first;
vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1);
tileBox *= tileSize;
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x + 1, tileCoord.y + 1);
tileBox *= tileSize;
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
if( tileBox.x >= clip.z
|| tileBox.z < clip.x
|| tileBox.y >= clip.w
|| tileBox.w < clip.y)
{
//NOTE: tile is fully outside clip, cull it
//TODO: move that test up
}
else if(firstOpIndex == -1)
{
if((windingOffset & 1) != 0)
{
//NOTE: tile is full covered. Add path start op (with winding offset).
// Additionally if color is opaque and tile is fully inside clip, trim tile list.
int pathOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(tileBox.x >= clip.z
|| tileBox.z < clip.x
|| tileBox.y >= clip.w
|| tileBox.w < clip.y)
{
//NOTE: tile is fully outside clip, cull it
//TODO: move that test up
}
else if(firstOpIndex == -1)
{
if((windingOffset & 1) != 0)
{
//NOTE: tile is full covered. Add path start op (with winding offset).
// Additionally if color is opaque and tile is fully inside clip, trim tile list.
int pathOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(pathOpIndex >= tileOpBuffer.elements.length())
{
return;
}
if(pathOpIndex >= tileOpBuffer.elements.length())
{
return;
}
tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_CLIP_FILL;
tileOpBuffer.elements[pathOpIndex].next = -1;
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset;
tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_CLIP_FILL;
tileOpBuffer.elements[pathOpIndex].next = -1;
tileOpBuffer.elements[pathOpIndex].index = pathIndex;
tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset;
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = pathOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = pathOpIndex;
}
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = pathOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = pathOpIndex;
}
if( tileBox.x >= clip.x
&& tileBox.z < clip.z
&& tileBox.y >= clip.y
&& tileBox.w < clip.w)
{
tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL;
if(tileBox.x >= clip.x
&& tileBox.z < clip.z
&& tileBox.y >= clip.y
&& tileBox.w < clip.w)
{
tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL;
if( pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1
&& pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0)
{
screenTilesBuffer.elements[tileIndex].first = pathOpIndex;
}
}
lastOpIndex = pathOpIndex;
}
// else, tile is fully uncovered, skip path
}
else
{
//NOTE: add path start op (with winding offset)
int startOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(startOpIndex >= tileOpBuffer.elements.length())
{
return;
}
if(pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1
&& pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0)
{
screenTilesBuffer.elements[tileIndex].first = pathOpIndex;
}
}
lastOpIndex = pathOpIndex;
}
// else, tile is fully uncovered, skip path
}
else
{
//NOTE: add path start op (with winding offset)
int startOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(startOpIndex >= tileOpBuffer.elements.length())
{
return;
}
tileOpBuffer.elements[startOpIndex].kind = OC_GL_OP_START;
tileOpBuffer.elements[startOpIndex].next = -1;
tileOpBuffer.elements[startOpIndex].index = pathIndex;
tileOpBuffer.elements[startOpIndex].windingOffsetOrCrossRight = windingOffset;
tileOpBuffer.elements[startOpIndex].kind = OC_GL_OP_START;
tileOpBuffer.elements[startOpIndex].next = -1;
tileOpBuffer.elements[startOpIndex].index = pathIndex;
tileOpBuffer.elements[startOpIndex].windingOffsetOrCrossRight = windingOffset;
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = startOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = startOpIndex;
}
lastOpIndex = startOpIndex;
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = startOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = startOpIndex;
}
lastOpIndex = startOpIndex;
//NOTE: chain remaining path ops to end of tile list
tileOpBuffer.elements[lastOpIndex].next = firstOpIndex;
lastOpIndex = tileQueue.last;
//NOTE: chain remaining path ops to end of tile list
tileOpBuffer.elements[lastOpIndex].next = firstOpIndex;
lastOpIndex = tileQueue.last;
//NOTE: add path end op
int endOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(endOpIndex >= tileOpBuffer.elements.length())
{
return;
}
//NOTE: add path end op
int endOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1);
if(endOpIndex >= tileOpBuffer.elements.length())
{
return;
}
tileOpBuffer.elements[endOpIndex].kind = OC_GL_OP_END;
tileOpBuffer.elements[endOpIndex].next = -1;
tileOpBuffer.elements[endOpIndex].index = pathIndex;
tileOpBuffer.elements[endOpIndex].windingOffsetOrCrossRight = windingOffset;
tileOpBuffer.elements[endOpIndex].kind = OC_GL_OP_END;
tileOpBuffer.elements[endOpIndex].next = -1;
tileOpBuffer.elements[endOpIndex].index = pathIndex;
tileOpBuffer.elements[endOpIndex].windingOffsetOrCrossRight = windingOffset;
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = endOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = endOpIndex;
}
lastOpIndex = endOpIndex;
}
}
}
if(lastOpIndex < 0)
{
screenTilesBuffer.elements[tileIndex].first = endOpIndex;
}
else
{
tileOpBuffer.elements[lastOpIndex].next = endOpIndex;
}
lastOpIndex = endOpIndex;
}
}
}
}

View File

@ -6,23 +6,31 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO
{
oc_gl_path elements[];
} pathBuffer;
oc_gl_path elements[];
}
pathBuffer;
layout(binding = 1) restrict writeonly buffer pathQueueBufferSSBO
{
oc_gl_path_queue elements[];
} pathQueueBuffer;
oc_gl_path_queue elements[];
}
pathQueueBuffer;
layout(binding = 2) coherent restrict buffer tileQueueCountBufferSSBO
{
int elements[];
} tileQueueCountBuffer;
int elements[];
}
tileQueueCountBuffer;
layout(binding = 3) restrict writeonly buffer tileQueueBufferSSBO
{
oc_gl_tile_queue elements[];
} tileQueueBuffer;
oc_gl_tile_queue elements[];
}
tileQueueBuffer;
layout(location = 0) uniform int tileSize;
layout(location = 1) uniform float scale;
@ -31,40 +39,40 @@ layout(location = 3) uniform int pathQueueBufferStart;
void main()
{
uint pathIndex = gl_WorkGroupID.x;
const oc_gl_path path = pathBuffer.elements[pathIndex + pathBufferStart];
uint pathIndex = gl_WorkGroupID.x;
const oc_gl_path path = pathBuffer.elements[pathIndex + pathBufferStart];
//NOTE: we don't clip on the right, since we need those tiles to accurately compute
// the prefix sum of winding increments in the backprop pass.
vec4 clippedBox = vec4(max(path.box.x, path.clip.x),
max(path.box.y, path.clip.y),
path.box.z,
min(path.box.w, path.clip.w));
//NOTE: we don't clip on the right, since we need those tiles to accurately compute
// the prefix sum of winding increments in the backprop pass.
vec4 clippedBox = vec4(max(path.box.x, path.clip.x),
max(path.box.y, path.clip.y),
path.box.z,
min(path.box.w, path.clip.w));
ivec2 firstTile = ivec2(clippedBox.xy*scale)/tileSize;
ivec2 lastTile = ivec2(clippedBox.zw*scale)/tileSize;
ivec2 firstTile = ivec2(clippedBox.xy * scale) / tileSize;
ivec2 lastTile = ivec2(clippedBox.zw * scale) / tileSize;
int nTilesX = max(0, lastTile.x - firstTile.x + 1);
int nTilesY = max(0, lastTile.y - firstTile.y + 1);
int tileCount = nTilesX * nTilesY;
int nTilesX = max(0, lastTile.x - firstTile.x + 1);
int nTilesY = max(0, lastTile.y - firstTile.y + 1);
int tileCount = nTilesX * nTilesY;
int tileQueuesIndex = atomicAdd(tileQueueCountBuffer.elements[0], tileCount);
int tileQueuesIndex = atomicAdd(tileQueueCountBuffer.elements[0], tileCount);
if(tileQueuesIndex + tileCount >= tileQueueBuffer.elements.length())
{
pathQueueBuffer.elements[pathIndex].area = ivec4(0);
pathQueueBuffer.elements[pathIndex].tileQueues = 0;
}
else
{
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY);
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex;
if(tileQueuesIndex + tileCount >= tileQueueBuffer.elements.length())
{
pathQueueBuffer.elements[pathIndex].area = ivec4(0);
pathQueueBuffer.elements[pathIndex].tileQueues = 0;
}
else
{
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY);
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex;
for(int i=0; i<tileCount; i++)
{
tileQueueBuffer.elements[tileQueuesIndex + i].first = -1;
tileQueueBuffer.elements[tileQueuesIndex + i].last = -1;
tileQueueBuffer.elements[tileQueuesIndex + i].windingOffset = 0;
}
}
for(int i = 0; i < tileCount; i++)
{
tileQueueBuffer.elements[tileQueuesIndex + i].first = -1;
tileQueueBuffer.elements[tileQueuesIndex + i].last = -1;
tileQueueBuffer.elements[tileQueuesIndex + i].windingOffset = 0;
}
}
}

View File

@ -6,29 +6,38 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO
{
oc_gl_path elements[];
} pathBuffer;
oc_gl_path elements[];
}
pathBuffer;
layout(binding = 1) restrict readonly buffer segmentBufferSSBO
{
oc_gl_segment elements[];
} segmentBuffer;
oc_gl_segment elements[];
}
segmentBuffer;
layout(binding = 2) restrict readonly buffer tileOpBufferSSBO
{
oc_gl_tile_op elements[];
} tileOpBuffer;
oc_gl_tile_op elements[];
}
tileOpBuffer;
layout(binding = 3) restrict readonly buffer screenTilesBufferSSBO
{
oc_gl_screen_tile elements[];
} screenTilesBuffer;
oc_gl_screen_tile elements[];
}
screenTilesBuffer;
layout(binding = 4) restrict readonly buffer screenTilesCountBufferSSBO
{
int elements[];
} screenTilesCountBuffer;
int elements[];
}
screenTilesCountBuffer;
layout(location = 0) uniform float scale;
layout(location = 1) uniform int msaaSampleCount;
@ -48,196 +57,197 @@ layout(binding = 8) uniform sampler2D srcTexture7;
void main()
{
uint tileIndex = gl_WorkGroupID.y * maxWorkGroupCount + gl_WorkGroupID.x;
uint tileIndex = gl_WorkGroupID.y * maxWorkGroupCount + gl_WorkGroupID.x;
if(tileIndex >= screenTilesCountBuffer.elements[0])
{
return;
}
if(tileIndex >= screenTilesCountBuffer.elements[0])
{
return;
}
uvec2 tileCoord = screenTilesBuffer.elements[tileIndex].tileCoord;
ivec2 pixelCoord = ivec2(tileCoord * gl_WorkGroupSize.x + gl_LocalInvocationID.xy);
uvec2 tileCoord = screenTilesBuffer.elements[tileIndex].tileCoord;
ivec2 pixelCoord = ivec2(tileCoord * gl_WorkGroupSize.x + gl_LocalInvocationID.xy);
vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5);
vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5);
/*
/*
if((pixelCoord.x % 16) == 0 || (pixelCoord.y % 16) == 0)
{
imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1));
return;
}
*/
vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = {
centerCoord + vec2(1, 3)/16,
centerCoord + vec2(-1, -3)/16,
centerCoord + vec2(5, -1)/16,
centerCoord + vec2(-3, 5)/16,
centerCoord + vec2(-5, -5)/16,
centerCoord + vec2(-7, 1)/16,
centerCoord + vec2(3, -7)/16,
centerCoord + vec2(7, 7)/16
};
vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = {
centerCoord + vec2(1, 3) / 16,
centerCoord + vec2(-1, -3) / 16,
centerCoord + vec2(5, -1) / 16,
centerCoord + vec2(-3, 5) / 16,
centerCoord + vec2(-5, -5) / 16,
centerCoord + vec2(-7, 1) / 16,
centerCoord + vec2(3, -7) / 16,
centerCoord + vec2(7, 7) / 16
};
int sampleCount = msaaSampleCount;
if(sampleCount != 8)
{
sampleCount = 1;
sampleCoords[0] = centerCoord;
}
int sampleCount = msaaSampleCount;
if(sampleCount != 8)
{
sampleCount = 1;
sampleCoords[0] = centerCoord;
}
const int srcSampleCount = 2;
const int srcSampleCount = 2;
vec2 imgSampleCoords[OC_GL_MAX_SRC_SAMPLE_COUNT] = {
centerCoord + vec2(-0.25, 0.25),
centerCoord + vec2(+0.25, +0.25),
centerCoord + vec2(+0.25, -0.25),
centerCoord + vec2(-0.25, +0.25)};
vec2 imgSampleCoords[OC_GL_MAX_SRC_SAMPLE_COUNT] = {
centerCoord + vec2(-0.25, 0.25),
centerCoord + vec2(+0.25, +0.25),
centerCoord + vec2(+0.25, -0.25),
centerCoord + vec2(-0.25, +0.25)
};
vec4 color = vec4(0);
int winding[OC_GL_MAX_SAMPLE_COUNT];
vec4 color = vec4(0);
int winding[OC_GL_MAX_SAMPLE_COUNT];
for(int i=0; i<sampleCount; i++)
{
winding[i] = 0;
}
for(int i = 0; i < sampleCount; i++)
{
winding[i] = 0;
}
int pathIndex = 0;
int opIndex = screenTilesBuffer.elements[tileIndex].first;
int pathIndex = 0;
int opIndex = screenTilesBuffer.elements[tileIndex].first;
while(opIndex >= 0)
{
oc_gl_tile_op op = tileOpBuffer.elements[opIndex];
while(opIndex >= 0)
{
oc_gl_tile_op op = tileOpBuffer.elements[opIndex];
if(op.kind == OC_GL_OP_START)
{
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++)
{
winding[sampleIndex] = op.windingOffsetOrCrossRight;
}
}
else if(op.kind == OC_GL_OP_SEGMENT)
{
int segIndex = op.index;
oc_gl_segment seg = segmentBuffer.elements[segIndex];
if(op.kind == OC_GL_OP_START)
{
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{
winding[sampleIndex] = op.windingOffsetOrCrossRight;
}
}
else if(op.kind == OC_GL_OP_SEGMENT)
{
int segIndex = op.index;
oc_gl_segment seg = segmentBuffer.elements[segIndex];
for(int sampleIndex=0; sampleIndex<sampleCount; sampleIndex++)
{
vec2 sampleCoord = sampleCoords[sampleIndex];
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{
vec2 sampleCoord = sampleCoords[sampleIndex];
if( (sampleCoord.y > seg.box.y)
&&(sampleCoord.y <= seg.box.w)
&&(side_of_segment(sampleCoord, seg) < 0))
{
winding[sampleIndex] += seg.windingIncrement;
}
if((sampleCoord.y > seg.box.y)
&& (sampleCoord.y <= seg.box.w)
&& (side_of_segment(sampleCoord, seg) < 0))
{
winding[sampleIndex] += seg.windingIncrement;
}
if(op.windingOffsetOrCrossRight != 0)
{
if( (seg.config == OC_GL_BR || seg.config == OC_GL_TL)
&&(sampleCoord.y > seg.box.w))
{
winding[sampleIndex] += seg.windingIncrement;
}
else if( (seg.config == OC_GL_BL || seg.config == OC_GL_TR)
&&(sampleCoord.y > seg.box.y))
{
winding[sampleIndex] -= seg.windingIncrement;
}
}
}
}
else
{
int pathIndex = op.index;
if(op.windingOffsetOrCrossRight != 0)
{
if((seg.config == OC_GL_BR || seg.config == OC_GL_TL)
&& (sampleCoord.y > seg.box.w))
{
winding[sampleIndex] += seg.windingIncrement;
}
else if((seg.config == OC_GL_BL || seg.config == OC_GL_TR)
&& (sampleCoord.y > seg.box.y))
{
winding[sampleIndex] -= seg.windingIncrement;
}
}
}
}
else
{
int pathIndex = op.index;
vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color;
nextColor.rgb *= nextColor.a;
vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color;
nextColor.rgb *= nextColor.a;
int textureID = pathBuffer.elements[pathBufferStart+pathIndex].textureID;
if(textureID >= 0)
{
vec4 texColor = vec4(0);
int textureID = pathBuffer.elements[pathBufferStart + pathIndex].textureID;
if(textureID >= 0)
{
vec4 texColor = vec4(0);
for(int sampleIndex = 0; sampleIndex<srcSampleCount; sampleIndex++)
{
vec2 sampleCoord = imgSampleCoords[sampleIndex];
vec3 ph = vec3(sampleCoord.xy, 1);
vec2 uv = (pathBuffer.elements[pathBufferStart + pathIndex].uvTransform * ph).xy;
for(int sampleIndex = 0; sampleIndex < srcSampleCount; sampleIndex++)
{
vec2 sampleCoord = imgSampleCoords[sampleIndex];
vec3 ph = vec3(sampleCoord.xy, 1);
vec2 uv = (pathBuffer.elements[pathBufferStart + pathIndex].uvTransform * ph).xy;
if(textureID == 0)
{
texColor += texture(srcTexture0, uv);
}
else if(textureID == 1)
{
texColor += texture(srcTexture1, uv);
}
else if(textureID == 2)
{
texColor += texture(srcTexture2, uv);
}
else if(textureID == 3)
{
texColor += texture(srcTexture3, uv);
}
else if(textureID == 4)
{
texColor += texture(srcTexture4, uv);
}
else if(textureID == 5)
{
texColor += texture(srcTexture5, uv);
}
else if(textureID == 6)
{
texColor += texture(srcTexture6, uv);
}
else if(textureID == 7)
{
texColor += texture(srcTexture7, uv);
}
}
texColor /= srcSampleCount;
texColor.rgb *= texColor.a;
nextColor *= texColor;
}
if(textureID == 0)
{
texColor += texture(srcTexture0, uv);
}
else if(textureID == 1)
{
texColor += texture(srcTexture1, uv);
}
else if(textureID == 2)
{
texColor += texture(srcTexture2, uv);
}
else if(textureID == 3)
{
texColor += texture(srcTexture3, uv);
}
else if(textureID == 4)
{
texColor += texture(srcTexture4, uv);
}
else if(textureID == 5)
{
texColor += texture(srcTexture5, uv);
}
else if(textureID == 6)
{
texColor += texture(srcTexture6, uv);
}
else if(textureID == 7)
{
texColor += texture(srcTexture7, uv);
}
}
texColor /= srcSampleCount;
texColor.rgb *= texColor.a;
nextColor *= texColor;
}
if(op.kind == OC_GL_OP_FILL)
{
color = color*(1-nextColor.a) + nextColor;
}
else
{
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
float coverage = 0;
if(op.kind == OC_GL_OP_FILL)
{
color = color * (1 - nextColor.a) + nextColor;
}
else
{
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
float coverage = 0;
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++)
{
vec2 sampleCoord = sampleCoords[sampleIndex];
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{
vec2 sampleCoord = sampleCoords[sampleIndex];
if( sampleCoord.x >= clip.x
&& sampleCoord.x < clip.z
&& sampleCoord.y >= clip.y
&& sampleCoord.y < clip.w)
{
bool filled = op.kind == OC_GL_OP_CLIP_FILL
||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL
&& ((winding[sampleIndex] & 1) != 0))
||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE
&& (winding[sampleIndex] != 0));
if(filled)
{
coverage++;
}
}
winding[sampleIndex] = op.windingOffsetOrCrossRight;
}
coverage /= sampleCount;
color = coverage*(color*(1-nextColor.a) + nextColor) + (1.-coverage)*color;
}
}
opIndex = op.next;
}
if(sampleCoord.x >= clip.x
&& sampleCoord.x < clip.z
&& sampleCoord.y >= clip.y
&& sampleCoord.y < clip.w)
{
bool filled = op.kind == OC_GL_OP_CLIP_FILL
|| (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL
&& ((winding[sampleIndex] & 1) != 0))
|| (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE
&& (winding[sampleIndex] != 0));
if(filled)
{
coverage++;
}
}
winding[sampleIndex] = op.windingOffsetOrCrossRight;
}
coverage /= sampleCount;
color = coverage * (color * (1 - nextColor.a) + nextColor) + (1. - coverage) * color;
}
}
opIndex = op.next;
}
imageStore(outTexture, pixelCoord, color);
imageStore(outTexture, pixelCoord, color);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: graphics.h
* @author: Martin Fouilleul
@ -9,78 +9,80 @@
#ifndef __GRAPHICS_H_
#define __GRAPHICS_H_
#include"util/typedefs.h"
#include"platform/platform.h"
#include"app/app.h"
#include "app/app.h"
#include "platform/platform.h"
#include "util/typedefs.h"
//------------------------------------------------------------------------------------------
//NOTE(martin): backends selection
//------------------------------------------------------------------------------------------
typedef enum {
OC_NONE,
OC_METAL,
OC_GL,
OC_GLES,
OC_CANVAS,
OC_HOST } oc_surface_api;
typedef enum
{
OC_NONE,
OC_METAL,
OC_GL,
OC_GLES,
OC_CANVAS,
OC_HOST
} oc_surface_api;
//NOTE: these macros are used to select which backend to include when building milepost
// they can be overridden by passing them to the compiler command line
#if OC_PLATFORM_MACOS
#ifndef OC_COMPILE_METAL
#define OC_COMPILE_METAL 1
#endif
#ifndef OC_COMPILE_METAL
#define OC_COMPILE_METAL 1
#endif
#ifndef OC_COMPILE_GLES
#define OC_COMPILE_GLES 1
#endif
#ifndef OC_COMPILE_GLES
#define OC_COMPILE_GLES 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_METAL
#error "Canvas surface requires a Metal backend on macOS. Make sure you define OC_COMPILE_METAL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_METAL
#error "Canvas surface requires a Metal backend on macOS. Make sure you define OC_COMPILE_METAL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#define OC_COMPILE_GL 0
#define OC_COMPILE_GL 0
#elif OC_PLATFORM_WINDOWS
#ifndef OC_COMPILE_GL
#define OC_COMPILE_GL 1
#endif
#ifndef OC_COMPILE_GL
#define OC_COMPILE_GL 1
#endif
#ifndef OC_COMPILE_GLES
#define OC_COMPILE_GLES 1
#endif
#ifndef OC_COMPILE_GLES
#define OC_COMPILE_GLES 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_GL
#error "Canvas surface requires an OpenGL backend on Windows. Make sure you define OC_COMPILE_GL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_GL
#error "Canvas surface requires an OpenGL backend on Windows. Make sure you define OC_COMPILE_GL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#elif PLATFORM_LINUX
#ifndef OC_COMPILE_GL
#define OC_COMPILE_GL 1
#endif
#ifndef OC_COMPILE_GL
#define OC_COMPILE_GL 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_GL
#error "Canvas surface requires an OpenGL backend on Linux. Make sure you define OC_COMPILE_GL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#ifndef OC_COMPILE_CANVAS
#if !OC_COMPILE_GL
#error "Canvas surface requires an OpenGL backend on Linux. Make sure you define OC_COMPILE_GL to 1."
#endif
#define OC_COMPILE_CANVAS 1
#endif
#endif
//NOTE: these macros are used to select backend-specific APIs to include when using milepost
#ifdef OC_EXPOSE_SURFACE_METAL
#include"mtl_surface.h"
#include "mtl_surface.h"
#endif
#ifdef OC_EXPOSE_SURFACE_WGL
#include"wgl_surface.h"
#include "wgl_surface.h"
#endif
//TODO: expose nsgl surface when supported, expose egl surface, etc...
@ -92,7 +94,10 @@ ORCA_API bool oc_is_surface_api_available(oc_surface_api api);
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics surface
//------------------------------------------------------------------------------------------
typedef struct oc_surface { u64 h; } oc_surface;
typedef struct oc_surface
{
u64 h;
} oc_surface;
ORCA_API oc_surface oc_surface_nil(void);
ORCA_API bool oc_surface_is_nil(oc_surface surface);
@ -121,51 +126,69 @@ ORCA_API void oc_surface_host_connect(oc_surface surface, oc_surface_id remoteId
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics canvas structs
//------------------------------------------------------------------------------------------
typedef struct oc_canvas { u64 h; } oc_canvas;
typedef struct oc_font { u64 h; } oc_font;
typedef struct oc_image { u64 h; } oc_image;
typedef struct oc_canvas
{
u64 h;
} oc_canvas;
typedef struct oc_font
{
u64 h;
} oc_font;
typedef struct oc_image
{
u64 h;
} oc_image;
typedef struct oc_color
{
union
{
struct
{
f32 r;
f32 g;
f32 b;
f32 a;
};
f32 c[4];
};
union
{
struct
{
f32 r;
f32 g;
f32 b;
f32 a;
};
f32 c[4];
};
} oc_color;
typedef enum {OC_JOINT_MITER = 0,
OC_JOINT_BEVEL,
OC_JOINT_NONE } oc_joint_type;
typedef enum
{
OC_JOINT_MITER = 0,
OC_JOINT_BEVEL,
OC_JOINT_NONE
} oc_joint_type;
typedef enum {OC_CAP_NONE = 0,
OC_CAP_SQUARE } oc_cap_type;
typedef enum
{
OC_CAP_NONE = 0,
OC_CAP_SQUARE
} oc_cap_type;
typedef struct oc_font_extents
{
f32 ascent; // the extent above the baseline (by convention a positive value extends above the baseline)
f32 descent; // the extent below the baseline (by convention, positive value extends below the baseline)
f32 leading; // spacing between one row's descent and the next row's ascent
f32 xHeight; // height of the lower case letter 'x'
f32 capHeight; // height of the upper case letter 'M'
f32 width; // maximum width of the font
f32 ascent; // the extent above the baseline (by convention a positive value extends above the baseline)
f32 descent; // the extent below the baseline (by convention, positive value extends below the baseline)
f32 leading; // spacing between one row's descent and the next row's ascent
f32 xHeight; // height of the lower case letter 'x'
f32 capHeight; // height of the upper case letter 'M'
f32 width; // maximum width of the font
} oc_font_extents;
typedef struct oc_text_extents
{
f32 xBearing;
f32 yBearing;
f32 width;
f32 height;
f32 xAdvance;
f32 yAdvance;
f32 xBearing;
f32 yBearing;
f32 width;
f32 height;
f32 xAdvance;
f32 yAdvance;
} oc_text_extents;
@ -238,8 +261,8 @@ ORCA_API void oc_rect_atlas_recycle(oc_rect_atlas* atlas, oc_rect rect);
//NOTE: image atlas helpers
typedef struct oc_image_region
{
oc_image image;
oc_rect rect;
oc_image image;
oc_rect rect;
} oc_image_region;
ORCA_API oc_image_region oc_image_atlas_alloc_from_rgba8(oc_rect_atlas* atlas, oc_image backingImage, u32 width, u32 height, u8* pixels);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: graphics_common.h
* @author: Martin Fouilleul
@ -8,75 +8,80 @@
#ifndef __GRAPHICS_COMMON_H_
#define __GRAPHICS_COMMON_H_
#include"graphics.h"
#include "graphics.h"
//------------------------------------------------------------------------
// canvas structs
//------------------------------------------------------------------------
typedef enum { OC_PATH_MOVE,
OC_PATH_LINE,
OC_PATH_QUADRATIC,
OC_PATH_CUBIC } oc_path_elt_type;
typedef enum
{
OC_PATH_MOVE,
OC_PATH_LINE,
OC_PATH_QUADRATIC,
OC_PATH_CUBIC
} oc_path_elt_type;
typedef struct oc_path_elt
{
oc_path_elt_type type;
oc_vec2 p[3];
oc_path_elt_type type;
oc_vec2 p[3];
} oc_path_elt;
typedef struct oc_path_descriptor
{
u32 startIndex;
u32 count;
oc_vec2 startPoint;
u32 startIndex;
u32 count;
oc_vec2 startPoint;
} oc_path_descriptor;
typedef struct oc_attributes
{
f32 width;
f32 tolerance;
oc_color color;
oc_joint_type joint;
f32 maxJointExcursion;
oc_cap_type cap;
f32 width;
f32 tolerance;
oc_color color;
oc_joint_type joint;
f32 maxJointExcursion;
oc_cap_type cap;
oc_font font;
f32 fontSize;
oc_font font;
f32 fontSize;
oc_image image;
oc_rect srcRegion;
oc_image image;
oc_rect srcRegion;
oc_mat2x3 transform;
oc_rect clip;
oc_mat2x3 transform;
oc_rect clip;
} oc_attributes;
typedef enum { OC_CMD_FILL,
OC_CMD_STROKE,
OC_CMD_JUMP
} oc_primitive_cmd;
typedef enum
{
OC_CMD_FILL,
OC_CMD_STROKE,
OC_CMD_JUMP
} oc_primitive_cmd;
typedef struct oc_primitive
{
oc_primitive_cmd cmd;
oc_attributes attributes;
oc_primitive_cmd cmd;
oc_attributes attributes;
union
{
oc_path_descriptor path;
oc_rect rect;
u32 jump;
};
union
{
oc_path_descriptor path;
oc_rect rect;
u32 jump;
};
} oc_primitive;
ORCA_API void oc_surface_render_commands(oc_surface surface,
oc_color clearColor,
u32 primitiveCount,
oc_primitive* primitives,
u32 eltCount,
oc_path_elt* elements);
oc_color clearColor,
u32 primitiveCount,
oc_primitive* primitives,
u32 eltCount,
oc_path_elt* elements);
#endif //__GRAPHICS_COMMON_H_

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: graphics_surface.c
* @author: Martin Fouilleul
@ -6,13 +6,13 @@
*
*****************************************************************/
#include"graphics_surface.h"
#include "graphics_surface.h"
//---------------------------------------------------------------
// per-thread selected surface
//---------------------------------------------------------------
oc_thread_local oc_surface oc_selectedSurface = {0};
oc_thread_local oc_surface oc_selectedSurface = { 0 };
//---------------------------------------------------------------
// typed handles functions
@ -20,26 +20,26 @@ oc_thread_local oc_surface oc_selectedSurface = {0};
oc_surface oc_surface_handle_alloc(oc_surface_data* surface)
{
oc_surface handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) };
return(handle);
oc_surface handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) };
return (handle);
}
oc_surface_data* oc_surface_data_from_handle(oc_surface handle)
{
oc_surface_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_SURFACE, handle.h);
return(data);
oc_surface_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_SURFACE, handle.h);
return (data);
}
oc_image oc_image_handle_alloc(oc_image_data* image)
{
oc_image handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) };
return(handle);
oc_image handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) };
return (handle);
}
oc_image_data* oc_image_data_from_handle(oc_image handle)
{
oc_image_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_IMAGE, handle.h);
return(data);
oc_image_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_IMAGE, handle.h);
return (data);
}
//---------------------------------------------------------------
@ -47,304 +47,305 @@ oc_image_data* oc_image_data_from_handle(oc_image handle)
//---------------------------------------------------------------
#if OC_COMPILE_GL
#if OC_PLATFORM_WINDOWS
#include"wgl_surface.h"
#define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window
#endif
#if OC_PLATFORM_WINDOWS
#include "wgl_surface.h"
#define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window
#endif
#endif
#if OC_COMPILE_GLES
#include"egl_surface.h"
#include "egl_surface.h"
#endif
#if OC_COMPILE_METAL
#include"mtl_surface.h"
#include "mtl_surface.h"
#endif
#if OC_COMPILE_CANVAS
#if OC_PLATFORM_MACOS
oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window);
#elif OC_PLATFORM_WINDOWS
oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window);
#endif
#if OC_PLATFORM_MACOS
oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window);
#elif OC_PLATFORM_WINDOWS
oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window);
#endif
#endif
bool oc_is_surface_backend_available(oc_surface_api api)
{
bool result = false;
switch(api)
{
#if OC_COMPILE_METAL
case OC_METAL:
#endif
bool result = false;
switch(api)
{
#if OC_COMPILE_METAL
case OC_METAL:
#endif
#if OC_COMPILE_GL
case OC_GL:
#endif
#if OC_COMPILE_GL
case OC_GL:
#endif
#if OC_COMPILE_GLES
case OC_GLES:
#endif
#if OC_COMPILE_GLES
case OC_GLES:
#endif
#if OC_COMPILE_CANVAS
case OC_CANVAS:
#endif
result = true;
break;
#if OC_COMPILE_CANVAS
case OC_CANVAS:
#endif
result = true;
break;
default:
break;
}
return(result);
default:
break;
}
return (result);
}
oc_surface oc_surface_nil() { return((oc_surface){.h = 0}); }
bool oc_surface_is_nil(oc_surface surface) { return(surface.h == 0); }
oc_surface oc_surface_nil() { return ((oc_surface){ .h = 0 }); }
bool oc_surface_is_nil(oc_surface surface) { return (surface.h == 0); }
oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
{
if(oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface surfaceHandle = oc_surface_nil();
oc_surface_data* surface = 0;
if(oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface surfaceHandle = oc_surface_nil();
oc_surface_data* surface = 0;
switch(api)
{
#if OC_COMPILE_GL
case OC_GL:
surface = oc_gl_surface_create_for_window(window);
break;
#endif
switch(api)
{
#if OC_COMPILE_GL
case OC_GL:
surface = oc_gl_surface_create_for_window(window);
break;
#endif
#if OC_COMPILE_GLES
case OC_GLES:
surface = oc_egl_surface_create_for_window(window);
break;
#endif
#if OC_COMPILE_GLES
case OC_GLES:
surface = oc_egl_surface_create_for_window(window);
break;
#endif
#if OC_COMPILE_METAL
case OC_METAL:
surface = oc_mtl_surface_create_for_window(window);
break;
#endif
#if OC_COMPILE_METAL
case OC_METAL:
surface = oc_mtl_surface_create_for_window(window);
break;
#endif
#if OC_COMPILE_CANVAS
case OC_CANVAS:
#if OC_COMPILE_CANVAS
case OC_CANVAS:
#if OC_PLATFORM_MACOS
surface = oc_mtl_canvas_surface_create_for_window(window);
#elif OC_PLATFORM_WINDOWS
surface = oc_gl_canvas_surface_create_for_window(window);
#endif
break;
#endif
#if OC_PLATFORM_MACOS
surface = oc_mtl_canvas_surface_create_for_window(window);
#elif OC_PLATFORM_WINDOWS
surface = oc_gl_canvas_surface_create_for_window(window);
#endif
break;
#endif
default:
break;
}
if(surface)
{
surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle);
}
return(surfaceHandle);
default:
break;
}
if(surface)
{
surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle);
}
return (surfaceHandle);
}
oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api)
{
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface surfaceHandle = oc_surface_nil();
oc_surface_data* surface = 0;
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface surfaceHandle = oc_surface_nil();
oc_surface_data* surface = 0;
switch(api)
{
#if OC_COMPILE_GLES
case OC_GLES:
surface = oc_egl_surface_create_remote(width, height);
break;
#endif
switch(api)
{
#if OC_COMPILE_GLES
case OC_GLES:
surface = oc_egl_surface_create_remote(width, height);
break;
#endif
default:
break;
}
if(surface)
{
surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle);
}
return(surfaceHandle);
default:
break;
}
if(surface)
{
surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle);
}
return (surfaceHandle);
}
oc_surface oc_surface_create_host(oc_window window)
{
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface handle = oc_surface_nil();
oc_surface_data* surface = 0;
#if OC_PLATFORM_MACOS
surface = oc_osx_surface_create_host(window);
#elif OC_PLATFORM_WINDOWS
surface = oc_win32_surface_create_host(window);
#endif
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface handle = oc_surface_nil();
oc_surface_data* surface = 0;
#if OC_PLATFORM_MACOS
surface = oc_osx_surface_create_host(window);
#elif OC_PLATFORM_WINDOWS
surface = oc_win32_surface_create_host(window);
#endif
if(surface)
{
handle = oc_surface_handle_alloc(surface);
}
return(handle);
if(surface)
{
handle = oc_surface_handle_alloc(surface);
}
return (handle);
}
void oc_surface_destroy(oc_surface handle)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface)
{
if(oc_selectedSurface.h == handle.h)
{
oc_surface_deselect();
}
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface)
{
if(oc_selectedSurface.h == handle.h)
{
oc_surface_deselect();
}
if(surface->backend && surface->backend->destroy)
{
surface->backend->destroy(surface->backend);
}
surface->destroy(surface);
oc_graphics_handle_recycle(handle.h);
}
if(surface->backend && surface->backend->destroy)
{
surface->backend->destroy(surface->backend);
}
surface->destroy(surface);
oc_graphics_handle_recycle(handle.h);
}
}
void oc_surface_deselect()
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* prevSurface = oc_surface_data_from_handle(oc_selectedSurface);
if(prevSurface && prevSurface->deselect)
{
prevSurface->deselect(prevSurface);
}
oc_selectedSurface = oc_surface_nil();
oc_surface_data* prevSurface = oc_surface_data_from_handle(oc_selectedSurface);
if(prevSurface && prevSurface->deselect)
{
prevSurface->deselect(prevSurface);
}
oc_selectedSurface = oc_surface_nil();
}
void oc_surface_select(oc_surface surface)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
OC_DEBUG_ASSERT(oc_graphicsData.init);
if(surface.h != oc_selectedSurface.h)
{
oc_surface_deselect();
}
if(surface.h != oc_selectedSurface.h)
{
oc_surface_deselect();
}
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->prepare)
{
surfaceData->prepare(surfaceData);
oc_selectedSurface = surface;
}
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->prepare)
{
surfaceData->prepare(surfaceData);
oc_selectedSurface = surface;
}
}
void oc_surface_present(oc_surface surface)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->present)
{
surfaceData->present(surfaceData);
}
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->present)
{
surfaceData->present(surfaceData);
}
}
void oc_surface_swap_interval(oc_surface surface, int swap)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->swapInterval)
{
surfaceData->swapInterval(surfaceData, swap);
}
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->swapInterval)
{
surfaceData->swapInterval(surfaceData, swap);
}
}
oc_vec2 oc_surface_get_size(oc_surface surface)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 size = {0};
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->getSize)
{
size = surfaceData->getSize(surfaceData);
}
return(size);
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 size = { 0 };
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->getSize)
{
size = surfaceData->getSize(surfaceData);
}
return (size);
}
oc_vec2 oc_surface_contents_scaling(oc_surface surface)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 scaling = {1, 1};
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->contentsScaling)
{
scaling = surfaceData->contentsScaling(surfaceData);
}
return(scaling);
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 scaling = { 1, 1 };
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->contentsScaling)
{
scaling = surfaceData->contentsScaling(surfaceData);
}
return (scaling);
}
void oc_surface_set_hidden(oc_surface surface, bool hidden)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->setHidden)
{
surfaceData->setHidden(surfaceData, hidden);
}
OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->setHidden)
{
surfaceData->setHidden(surfaceData, hidden);
}
}
bool oc_surface_get_hidden(oc_surface surface)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
bool res = false;
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->getHidden)
{
res = surfaceData->getHidden(surfaceData);
}
return(res);
OC_DEBUG_ASSERT(oc_graphicsData.init);
bool res = false;
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->getHidden)
{
res = surfaceData->getHidden(surfaceData);
}
return (res);
}
void* oc_surface_native_layer(oc_surface surface)
{
void* res = 0;
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->nativeLayer)
{
res = surfaceData->nativeLayer(surfaceData);
}
return(res);
void* res = 0;
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->nativeLayer)
{
res = surfaceData->nativeLayer(surfaceData);
}
return (res);
}
oc_surface_id oc_surface_remote_id(oc_surface handle)
{
oc_surface_id remoteId = 0;
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->remoteID)
{
remoteId = surface->remoteID(surface);
}
return(remoteId);
oc_surface_id remoteId = 0;
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->remoteID)
{
remoteId = surface->remoteID(surface);
}
return (remoteId);
}
void oc_surface_host_connect(oc_surface handle, oc_surface_id remoteID)
{
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->hostConnect)
{
surface->hostConnect(surface, remoteID);
}
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->hostConnect)
{
surface->hostConnect(surface, remoteID);
}
}
void oc_surface_render_commands(oc_surface surface,
@ -354,21 +355,21 @@ void oc_surface_render_commands(oc_surface surface,
u32 eltCount,
oc_path_elt* elements)
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before drawing onto a surface.\n");
}
else if(surfaceData && surfaceData->backend)
{
surfaceData->backend->render(surfaceData->backend,
clearColor,
primitiveCount,
primitives,
eltCount,
elements);
}
if(surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before drawing onto a surface.\n");
}
else if(surfaceData && surfaceData->backend)
{
surfaceData->backend->render(surfaceData->backend,
clearColor,
primitiveCount,
primitives,
eltCount,
elements);
}
}
//------------------------------------------------------------------------------------------
@ -377,78 +378,78 @@ void oc_surface_render_commands(oc_surface surface,
oc_vec2 oc_image_size(oc_image image)
{
oc_vec2 res = {0};
oc_image_data* imageData = oc_image_data_from_handle(image);
if(imageData)
{
res = imageData->size;
}
return(res);
oc_vec2 res = { 0 };
oc_image_data* imageData = oc_image_data_from_handle(image);
if(imageData)
{
res = imageData->size;
}
return (res);
}
oc_image oc_image_create(oc_surface surface, u32 width, u32 height)
{
oc_image image = oc_image_nil();
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
oc_image image = oc_image_nil();
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else if(surfaceData && surfaceData->backend)
{
OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS);
if(surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else if(surfaceData && surfaceData->backend)
{
OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS);
oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){width, height});
if(imageData)
{
imageData->surface = surface;
image = oc_image_handle_alloc(imageData);
}
}
return(image);
oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){ width, height });
if(imageData)
{
imageData->surface = surface;
image = oc_image_handle_alloc(imageData);
}
}
return (image);
}
void oc_image_destroy(oc_image image)
{
oc_image_data* imageData = oc_image_data_from_handle(image);
oc_image_data* imageData = oc_image_data_from_handle(image);
if(imageData)
{
if(imageData->surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else
{
oc_surface_data* surface = oc_surface_data_from_handle(imageData->surface);
if(surface && surface->backend)
{
surface->backend->imageDestroy(surface->backend, imageData);
oc_graphics_handle_recycle(image.h);
}
}
}
if(imageData)
{
if(imageData->surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else
{
oc_surface_data* surface = oc_surface_data_from_handle(imageData->surface);
if(surface && surface->backend)
{
surface->backend->imageDestroy(surface->backend, imageData);
oc_graphics_handle_recycle(image.h);
}
}
}
}
void oc_image_upload_region_rgba8(oc_image image, oc_rect region, u8* pixels)
{
oc_image_data* imageData = oc_image_data_from_handle(image);
oc_image_data* imageData = oc_image_data_from_handle(image);
if(imageData)
{
if(imageData->surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(imageData->surface);
if(surfaceData)
{
OC_DEBUG_ASSERT(surfaceData->backend);
surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels);
}
}
}
if(imageData)
{
if(imageData->surface.h != oc_selectedSurface.h)
{
oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n");
}
else
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(imageData->surface);
if(surfaceData)
{
OC_DEBUG_ASSERT(surfaceData->backend);
surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels);
}
}
}
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: graphics_surface.h
* @author: Martin Fouilleul
@ -8,102 +8,103 @@
#ifndef __GRAPHICS_SURFACE_H_
#define __GRAPHICS_SURFACE_H_
#include"graphics_common.h"
#include"app/app_internal.h"
#include "app/app_internal.h"
#include "graphics_common.h"
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
//---------------------------------------------------------------
// surface interface
//---------------------------------------------------------------
typedef struct oc_surface_data oc_surface_data;
typedef struct oc_canvas_backend oc_canvas_backend;
//---------------------------------------------------------------
// surface interface
//---------------------------------------------------------------
typedef struct oc_surface_data oc_surface_data;
typedef struct oc_canvas_backend oc_canvas_backend;
typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface);
typedef void (*oc_surface_select_proc)(oc_surface_data* surface);
typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface);
typedef void (*oc_surface_present_proc)(oc_surface_data* surface);
typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap);
typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface);
typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface);
typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface);
typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden);
typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface);
typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface);
typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId);
typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface);
typedef void (*oc_surface_select_proc)(oc_surface_data* surface);
typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface);
typedef void (*oc_surface_present_proc)(oc_surface_data* surface);
typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap);
typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface);
typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface);
typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface);
typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden);
typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface);
typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface);
typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId);
typedef struct oc_surface_data
{
oc_surface_api api;
oc_layer layer;
typedef struct oc_surface_data
{
oc_surface_api api;
oc_layer layer;
oc_surface_destroy_proc destroy;
oc_surface_select_proc prepare;
oc_surface_present_proc present;
oc_surface_deselect_proc deselect;
oc_surface_swap_interval_proc swapInterval;
oc_surface_get_size_proc getSize;
oc_surface_contents_scaling_proc contentsScaling;
oc_surface_get_hidden_proc getHidden;
oc_surface_set_hidden_proc setHidden;
oc_surface_native_layer_proc nativeLayer;
oc_surface_remote_id_proc remoteID;
oc_surface_host_connect_proc hostConnect;
oc_surface_destroy_proc destroy;
oc_surface_select_proc prepare;
oc_surface_present_proc present;
oc_surface_deselect_proc deselect;
oc_surface_swap_interval_proc swapInterval;
oc_surface_get_size_proc getSize;
oc_surface_contents_scaling_proc contentsScaling;
oc_surface_get_hidden_proc getHidden;
oc_surface_set_hidden_proc setHidden;
oc_surface_native_layer_proc nativeLayer;
oc_surface_remote_id_proc remoteID;
oc_surface_host_connect_proc hostConnect;
oc_canvas_backend* backend;
oc_canvas_backend* backend;
} oc_surface_data;
} oc_surface_data;
oc_surface oc_surface_handle_alloc(oc_surface_data* surface);
oc_surface_data* oc_surface_data_from_handle(oc_surface handle);
oc_surface oc_surface_handle_alloc(oc_surface_data* surface);
oc_surface_data* oc_surface_data_from_handle(oc_surface handle);
void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window);
void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height);
void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window);
void oc_surface_cleanup(oc_surface_data* surface);
void* oc_surface_native_layer(oc_surface surface);
void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window);
void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height);
void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window);
void oc_surface_cleanup(oc_surface_data* surface);
void* oc_surface_native_layer(oc_surface surface);
//---------------------------------------------------------------
// canvas backend interface
//---------------------------------------------------------------
typedef struct oc_image_data
{
oc_list_elt listElt;
u32 generation;
oc_surface surface;
oc_vec2 size;
//---------------------------------------------------------------
// canvas backend interface
//---------------------------------------------------------------
typedef struct oc_image_data
{
oc_list_elt listElt;
u32 generation;
oc_surface surface;
oc_vec2 size;
} oc_image_data;
} oc_image_data;
typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend);
typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend);
typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size);
typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image);
typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend,
oc_image_data* image,
oc_rect region,
u8* pixels);
typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size);
typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image);
typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend,
oc_image_data* image,
oc_rect region,
u8* pixels);
typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend,
oc_color clearColor,
u32 primitiveCount,
oc_primitive* primitives,
u32 eltCount,
oc_path_elt* pathElements);
typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend,
oc_color clearColor,
u32 primitiveCount,
oc_primitive* primitives,
u32 eltCount,
oc_path_elt* pathElements);
typedef struct oc_canvas_backend
{
oc_canvas_backend_destroy_proc destroy;
typedef struct oc_canvas_backend
{
oc_canvas_backend_destroy_proc destroy;
oc_canvas_backend_image_create_proc imageCreate;
oc_canvas_backend_image_destroy_proc imageDestroy;
oc_canvas_backend_image_upload_region_proc imageUploadRegion;
oc_canvas_backend_image_create_proc imageCreate;
oc_canvas_backend_image_destroy_proc imageDestroy;
oc_canvas_backend_image_upload_region_proc imageUploadRegion;
oc_canvas_backend_render_proc render;
oc_canvas_backend_render_proc render;
} oc_canvas_backend;
} oc_canvas_backend;
#ifdef __cplusplus
} // extern "C"

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: mtl_renderer.h
* @author: Martin Fouilleul
@ -9,103 +9,111 @@
#ifndef __MTL_RENDERER_H_
#define __MTL_RENDERER_H_
#include<simd/simd.h>
#include <simd/simd.h>
typedef enum {
OC_MTL_FILL,
OC_MTL_STROKE,
typedef enum
{
OC_MTL_FILL,
OC_MTL_STROKE,
} oc_mtl_cmd;
typedef struct oc_mtl_path
{
oc_mtl_cmd cmd;
matrix_float3x3 uvTransform;
vector_float4 color;
vector_float4 box;
vector_float4 clip;
int texture;
oc_mtl_cmd cmd;
matrix_float3x3 uvTransform;
vector_float4 color;
vector_float4 box;
vector_float4 clip;
int texture;
} oc_mtl_path;
typedef enum {
OC_MTL_LINE = 1,
OC_MTL_QUADRATIC,
OC_MTL_CUBIC,
typedef enum
{
OC_MTL_LINE = 1,
OC_MTL_QUADRATIC,
OC_MTL_CUBIC,
} oc_mtl_seg_kind;
typedef struct oc_mtl_path_elt
{
int pathIndex;
oc_mtl_seg_kind kind;
vector_float2 p[4];
int pathIndex;
oc_mtl_seg_kind kind;
vector_float2 p[4];
} oc_mtl_path_elt;
typedef enum {
OC_MTL_BL, // curve on bottom left
OC_MTL_BR, // curve on bottom right
OC_MTL_TL, // curve on top left
OC_MTL_TR // curve on top right
typedef enum
{
OC_MTL_BL, // curve on bottom left
OC_MTL_BR, // curve on bottom right
OC_MTL_TL, // curve on top left
OC_MTL_TR // curve on top right
} oc_mtl_seg_config;
typedef struct oc_mtl_segment
{
oc_mtl_seg_kind kind;
int pathIndex;
oc_mtl_seg_config config; //TODO pack these
int windingIncrement;
vector_float4 box;
matrix_float3x3 implicitMatrix;
float sign;
vector_float2 hullVertex;
int debugID;
oc_mtl_seg_kind kind;
int pathIndex;
oc_mtl_seg_config config; //TODO pack these
int windingIncrement;
vector_float4 box;
matrix_float3x3 implicitMatrix;
float sign;
vector_float2 hullVertex;
int debugID;
} oc_mtl_segment;
typedef struct oc_mtl_path_queue
{
vector_int4 area;
int tileQueues;
vector_int4 area;
int tileQueues;
} oc_mtl_path_queue;
#ifdef __METAL_VERSION__
using namespace metal;
using namespace metal;
#endif
typedef enum { OC_MTL_OP_FILL,
OC_MTL_OP_CLIP_FILL,
OC_MTL_OP_START,
OC_MTL_OP_END,
OC_MTL_OP_SEGMENT } oc_mtl_tile_op_kind;
typedef enum
{
OC_MTL_OP_FILL,
OC_MTL_OP_CLIP_FILL,
OC_MTL_OP_START,
OC_MTL_OP_END,
OC_MTL_OP_SEGMENT
} oc_mtl_tile_op_kind;
typedef struct oc_mtl_tile_op
{
oc_mtl_tile_op_kind kind;
int index;
int next;
union
{
bool crossRight;
int windingOffset;
};
oc_mtl_tile_op_kind kind;
int index;
int next;
union
{
bool crossRight;
int windingOffset;
};
} oc_mtl_tile_op;
typedef struct oc_mtl_tile_queue
{
atomic_int windingOffset;
atomic_int first;
int last;
atomic_int windingOffset;
atomic_int first;
int last;
} oc_mtl_tile_queue;
typedef struct oc_mtl_screen_tile
{
vector_uint2 tileCoord;
int first;
vector_uint2 tileCoord;
int first;
} oc_mtl_screen_tile;
enum {
OC_MTL_MAX_IMAGES_PER_BATCH = 30
enum
{
OC_MTL_MAX_IMAGES_PER_BATCH = 30
};
#endif //__MTL_RENDERER_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: mtl_surface.h
* @author: Martin Fouilleul
@ -9,10 +9,10 @@
#ifndef __MTL_SURFACE_H_
#define __MTL_SURFACE_H_
#include"graphics_surface.h"
#include "graphics_surface.h"
#ifdef __OBJC__
#import<Metal/Metal.h>
#import <Metal/Metal.h>
#endif
oc_surface_data* oc_mtl_surface_create_for_window(oc_window window);

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: mtl_surface.m
* @author: Martin Fouilleul
@ -6,63 +6,65 @@
* @revision:
*
*****************************************************************/
#import<Metal/Metal.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#import <QuartzCore/QuartzCore.h>
#import<QuartzCore/CAMetalLayer.h>
#include<simd/simd.h>
#include <simd/simd.h>
#include"graphics_surface.h"
#include"util/macros.h"
#include"app/osx_app.h"
#include "app/osx_app.h"
#include "graphics_surface.h"
#include "util/macros.h"
typedef struct oc_mtl_surface
{
oc_surface_data interface;
oc_surface_data interface;
// permanent mtl resources
id<MTLDevice> device;
CAMetalLayer* mtlLayer;
id<MTLCommandQueue> commandQueue;
// permanent mtl resources
id<MTLDevice> device;
CAMetalLayer* mtlLayer;
id<MTLCommandQueue> commandQueue;
// transient metal resources
id<CAMetalDrawable> drawable;
id<MTLCommandBuffer> commandBuffer;
// transient metal resources
id<CAMetalDrawable> drawable;
id<MTLCommandBuffer> commandBuffer;
} oc_mtl_surface;
void oc_mtl_surface_destroy(oc_surface_data* interface)
{
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool
{
//NOTE: when GPU frame capture is enabled, if we release resources before all work is completed,
// libMetalCapture crashes... the following hack avoids this crash by enqueuing a last (empty)
// command buffer and waiting for it to complete, ensuring all previous buffers have completed
id<MTLCommandBuffer> endBuffer = [surface->commandQueue commandBuffer];
[endBuffer commit];
[endBuffer waitUntilCompleted];
@autoreleasepool
{
//NOTE: when GPU frame capture is enabled, if we release resources before all work is completed,
// libMetalCapture crashes... the following hack avoids this crash by enqueuing a last (empty)
// command buffer and waiting for it to complete, ensuring all previous buffers have completed
id<MTLCommandBuffer> endBuffer = [surface->commandQueue commandBuffer];
[endBuffer commit];
[endBuffer waitUntilCompleted];
[surface->commandQueue release];
[surface->mtlLayer removeFromSuperlayer];
[surface->mtlLayer release];
[surface->device release];
}
//NOTE: we don't use oc_layer_cleanup here, because the CAMetalLayer is taken care off by the surface itself
[surface->commandQueue release];
[surface->mtlLayer removeFromSuperlayer];
[surface->mtlLayer release];
[surface->device release];
}
//NOTE: we don't use oc_layer_cleanup here, because the CAMetalLayer is taken care off by the surface itself
}
void oc_mtl_surface_acquire_command_buffer(oc_mtl_surface* surface)
{
if(surface->commandBuffer == nil)
{
surface->commandBuffer = [surface->commandQueue commandBuffer];
[surface->commandBuffer retain];
}
if(surface->commandBuffer == nil)
{
surface->commandBuffer = [surface->commandQueue commandBuffer];
[surface->commandBuffer retain];
}
}
void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface)
{@autoreleasepool{
/*WARN(martin):
{
@autoreleasepool
{
/*WARN(martin):
//TODO: we should stop trying to render if we detect that the app is in the background
or occluded
@ -70,50 +72,51 @@ void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface)
for too long.
*/
//NOTE: returned drawable could be nil if we stall for more than 1s, although that never seem to happen in practice?
if(surface->drawable == nil)
{
surface->drawable = [surface->mtlLayer nextDrawable];
if(surface->drawable)
{
[surface->drawable retain];
}
}
}}
//NOTE: returned drawable could be nil if we stall for more than 1s, although that never seem to happen in practice?
if(surface->drawable == nil)
{
surface->drawable = [surface->mtlLayer nextDrawable];
if(surface->drawable)
{
[surface->drawable retain];
}
}
}
}
void oc_mtl_surface_prepare(oc_surface_data* interface)
{
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
oc_mtl_surface_acquire_command_buffer(surface);
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
oc_mtl_surface_acquire_command_buffer(surface);
}
void oc_mtl_surface_present(oc_surface_data* interface)
{
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool
{
if(surface->commandBuffer != nil)
{
if(surface->drawable != nil)
{
[surface->commandBuffer presentDrawable: surface->drawable];
[surface->drawable release];
surface->drawable = nil;
}
[surface->commandBuffer commit];
[surface->commandBuffer release];
surface->commandBuffer = nil;
}
}
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool
{
if(surface->commandBuffer != nil)
{
if(surface->drawable != nil)
{
[surface->commandBuffer presentDrawable:surface->drawable];
[surface->drawable release];
surface->drawable = nil;
}
[surface->commandBuffer commit];
[surface->commandBuffer release];
surface->commandBuffer = nil;
}
}
}
void oc_mtl_surface_swap_interval(oc_surface_data* interface, int swap)
{
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool
{
[surface->mtlLayer setDisplaySyncEnabled: (swap ? YES : NO)];
}
oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool
{
[surface->mtlLayer setDisplaySyncEnabled:(swap ? YES : NO)];
}
}
/*
@ -138,7 +141,6 @@ void oc_mtl_surface_set_frame(oc_surface_data* interface, oc_rect frame)
}
*/
//TODO fix that according to real scaling, depending on the monitor settings
static const f32 OC_MTL_SURFACE_CONTENTS_SCALING = 2;
@ -148,135 +150,134 @@ static const int OC_MTL_MAX_FRAMES_IN_FLIGHT = 2;
oc_surface_data* oc_mtl_surface_create_for_window(oc_window window)
{
oc_mtl_surface* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
surface = (oc_mtl_surface*)malloc(sizeof(oc_mtl_surface));
oc_mtl_surface* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
surface = (oc_mtl_surface*)malloc(sizeof(oc_mtl_surface));
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
//NOTE(martin): setup interface functions
surface->interface.api = OC_METAL;
surface->interface.destroy = oc_mtl_surface_destroy;
surface->interface.prepare = oc_mtl_surface_prepare;
surface->interface.deselect = 0;
surface->interface.present = oc_mtl_surface_present;
surface->interface.swapInterval = oc_mtl_surface_swap_interval;
//NOTE(martin): setup interface functions
surface->interface.api = OC_METAL;
surface->interface.destroy = oc_mtl_surface_destroy;
surface->interface.prepare = oc_mtl_surface_prepare;
surface->interface.deselect = 0;
surface->interface.present = oc_mtl_surface_present;
surface->interface.swapInterval = oc_mtl_surface_swap_interval;
@autoreleasepool
{
//-----------------------------------------------------------
//NOTE(martin): create a mtl device and a mtl layer and
//-----------------------------------------------------------
@autoreleasepool
{
//-----------------------------------------------------------
//NOTE(martin): create a mtl device and a mtl layer and
//-----------------------------------------------------------
/*WARN(martin):
/*WARN(martin):
Calling MTLCreateDefaultSystemDevice(), as advised by the doc, hangs Discord's screen sharing...
The workaround I found, which doesn't make sense, is to set the mtlLayer.device to mtlLayer.preferredDevice,
even if mtlLayer.preferredDevice is the same value as returned by MTLCreateDefaultSystemDevice().
This works for now and allows screen sharing while using orca, but we'll have to revisit this when we want
more control over what GPU gets used.
*/
surface->device = nil;
surface->device = nil;
//Select a discrete GPU, if possible
NSArray<id<MTLDevice>>* devices = MTLCopyAllDevices();
for(id<MTLDevice> device in devices)
{
if(!device.isRemovable && !device.isLowPower)
{
surface->device = device;
break;
}
}
if(surface->device == nil)
{
oc_log_warning("Couldn't select a discrete GPU, using first available device\n");
surface->device = devices[0];
}
//Select a discrete GPU, if possible
NSArray<id<MTLDevice>>* devices = MTLCopyAllDevices();
for(id<MTLDevice> device in devices)
{
if(!device.isRemovable && !device.isLowPower)
{
surface->device = device;
break;
}
}
if(surface->device == nil)
{
oc_log_warning("Couldn't select a discrete GPU, using first available device\n");
surface->device = devices[0];
}
//surface->device = MTLCreateSystemDefaultDevice();
//surface->device = MTLCreateSystemDefaultDevice();
surface->mtlLayer = [CAMetalLayer layer];
[surface->mtlLayer retain];
surface->mtlLayer.device = surface->device;
surface->mtlLayer = [CAMetalLayer layer];
[surface->mtlLayer retain];
surface->mtlLayer.device = surface->device;
[surface->mtlLayer setOpaque:NO];
surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
[surface->interface.layer.caLayer addSublayer:(CALayer*)surface->mtlLayer];
[surface->mtlLayer setOpaque:NO];
surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
[surface->interface.layer.caLayer addSublayer: (CALayer*)surface->mtlLayer];
//-----------------------------------------------------------
//NOTE(martin): set the size and scaling
//-----------------------------------------------------------
NSRect frame = [[windowData->osx.nsWindow contentView] frame];
CGSize size = frame.size;
surface->mtlLayer.frame = (CGRect){ { 0, 0 }, size };
size.width *= OC_MTL_SURFACE_CONTENTS_SCALING;
size.height *= OC_MTL_SURFACE_CONTENTS_SCALING;
surface->mtlLayer.drawableSize = size;
surface->mtlLayer.contentsScale = OC_MTL_SURFACE_CONTENTS_SCALING;
//-----------------------------------------------------------
//NOTE(martin): set the size and scaling
//-----------------------------------------------------------
NSRect frame = [[windowData->osx.nsWindow contentView] frame];
CGSize size = frame.size;
surface->mtlLayer.frame = (CGRect){{0, 0}, size};
size.width *= OC_MTL_SURFACE_CONTENTS_SCALING;
size.height *= OC_MTL_SURFACE_CONTENTS_SCALING;
surface->mtlLayer.drawableSize = size;
surface->mtlLayer.contentsScale = OC_MTL_SURFACE_CONTENTS_SCALING;
surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
//NOTE(martin): handling resizing
// surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
// surface->mtlLayer.needsDisplayOnBoundsChange = YES;
//NOTE(martin): handling resizing
// surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
// surface->mtlLayer.needsDisplayOnBoundsChange = YES;
//-----------------------------------------------------------
//NOTE(martin): create a command queue
//-----------------------------------------------------------
surface->commandQueue = [surface->device newCommandQueue];
[surface->commandQueue retain];
//-----------------------------------------------------------
//NOTE(martin): create a command queue
//-----------------------------------------------------------
surface->commandQueue = [surface->device newCommandQueue];
[surface->commandQueue retain];
//NOTE(martin): command buffer and drawable are set on demand and at the end of each present() call
surface->drawable = nil;
surface->commandBuffer = nil;
}
}
return((oc_surface_data*)surface);
//NOTE(martin): command buffer and drawable are set on demand and at the end of each present() call
surface->drawable = nil;
surface->commandBuffer = nil;
}
}
return ((oc_surface_data*)surface);
}
void* oc_mtl_surface_layer(oc_surface surface)
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
return(mtlSurface->mtlLayer);
}
else
{
return(nil);
}
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
return (mtlSurface->mtlLayer);
}
else
{
return (nil);
}
}
void* oc_mtl_surface_drawable(oc_surface surface)
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_drawable(mtlSurface);
return(mtlSurface->drawable);
}
else
{
return(nil);
}
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_drawable(mtlSurface);
return (mtlSurface->drawable);
}
else
{
return (nil);
}
}
void* oc_mtl_surface_command_buffer(oc_surface surface)
{
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_command_buffer(mtlSurface);
return(mtlSurface->commandBuffer);
}
else
{
return(nil);
}
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->api == OC_METAL)
{
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_command_buffer(mtlSurface);
return (mtlSurface->commandBuffer);
}
else
{
return (nil);
}
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: wgl_surface.c
* @author: Martin Fouilleul
@ -6,273 +6,272 @@
* @revision:
*
*****************************************************************/
#include"app/win32_app.h"
#include"graphics_surface.h"
#include"gl_loader.h"
#include "app/win32_app.h"
#include "gl_loader.h"
#include "graphics_surface.h"
#include<GL/wglext.h>
#include"util/macros.h"
#include "util/macros.h"
#include <GL/wglext.h>
#define OC_WGL_PROC_LIST \
OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \
OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \
OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \
OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT) \
#define OC_WGL_PROC_LIST \
OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \
OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \
OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \
OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT)
//NOTE: wgl function pointers declarations
#define OC_WGL_PROC(type, name) OC_CAT3(PFN, type, PROC) name = 0;
OC_WGL_PROC_LIST
OC_WGL_PROC_LIST
#undef OC_WGL_PROC
//NOTE: wgl loader
typedef struct oc_wgl_dummy_context
{
bool init;
HWND hWnd;
HDC hDC;
HGLRC glContext;
bool init;
HWND hWnd;
HDC hDC;
HGLRC glContext;
} oc_wgl_dummy_context;
static oc_wgl_dummy_context oc_wglDummyContext = {0};
static oc_wgl_dummy_context oc_wglDummyContext = { 0 };
static void oc_wgl_init()
{
if(!oc_wglDummyContext.init)
{
//NOTE: create a dummy window
WNDCLASS windowClass = {.style = CS_OWNDC,
.lpfnWndProc = DefWindowProc,
.hInstance = GetModuleHandleW(NULL),
.lpszClassName = "oc_wgl_helper_window_class",
.hCursor = LoadCursor(0, IDC_ARROW)};
if(!oc_wglDummyContext.init)
{
//NOTE: create a dummy window
WNDCLASS windowClass = { .style = CS_OWNDC,
.lpfnWndProc = DefWindowProc,
.hInstance = GetModuleHandleW(NULL),
.lpszClassName = "oc_wgl_helper_window_class",
.hCursor = LoadCursor(0, IDC_ARROW) };
if(!RegisterClass(&windowClass))
{
//TODO: error
goto quit;
}
if(!RegisterClass(&windowClass))
{
//TODO: error
goto quit;
}
oc_wglDummyContext.hWnd = CreateWindow("oc_wgl_helper_window_class",
"dummy",
WS_OVERLAPPEDWINDOW,
0, 0, 100, 100,
0, 0, windowClass.hInstance, 0);
oc_wglDummyContext.hWnd = CreateWindow("oc_wgl_helper_window_class",
"dummy",
WS_OVERLAPPEDWINDOW,
0, 0, 100, 100,
0, 0, windowClass.hInstance, 0);
if(!oc_wglDummyContext.hWnd)
{
//TODO: error
goto quit;
}
oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd);
if(!oc_wglDummyContext.hWnd)
{
//TODO: error
goto quit;
}
oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd);
PIXELFORMATDESCRIPTOR pixelFormatDesc =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
PIXELFORMATDESCRIPTOR pixelFormatDesc = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int pixelFormat = ChoosePixelFormat(oc_wglDummyContext.hDC, &pixelFormatDesc);
SetPixelFormat(oc_wglDummyContext.hDC, pixelFormat, &pixelFormatDesc);
int pixelFormat = ChoosePixelFormat(oc_wglDummyContext.hDC, &pixelFormatDesc);
SetPixelFormat(oc_wglDummyContext.hDC, pixelFormat, &pixelFormatDesc);
oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC);
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC);
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
//NOTE(martin): now load WGL extension functions
#define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress( #name );
OC_WGL_PROC_LIST
#undef OC_WGL_PROC
//NOTE(martin): now load WGL extension functions
#define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress(#name);
OC_WGL_PROC_LIST
#undef OC_WGL_PROC
oc_wglDummyContext.init = true;
}
else
{
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
}
quit:;
oc_wglDummyContext.init = true;
}
else
{
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
}
quit:;
}
#undef OC_WGL_PROC_LIST
typedef struct oc_wgl_surface
{
oc_surface_data interface;
oc_surface_data interface;
HDC hDC;
HGLRC glContext;
HDC hDC;
HGLRC glContext;
//NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs
// from different contexts might select different implementations (eg. depending on context version/pixel format)
oc_gl_api api;
//NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs
// from different contexts might select different implementations (eg. depending on context version/pixel format)
oc_gl_api api;
} oc_wgl_surface;
void oc_wgl_surface_destroy(oc_surface_data* interface)
{
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
if(surface->glContext == wglGetCurrentContext())
{
wglMakeCurrent(NULL, NULL);
}
wglDeleteContext(surface->glContext);
if(surface->glContext == wglGetCurrentContext())
{
wglMakeCurrent(NULL, NULL);
}
wglDeleteContext(surface->glContext);
oc_surface_cleanup(interface);
oc_surface_cleanup(interface);
free(surface);
free(surface);
}
void oc_wgl_surface_prepare(oc_surface_data* interface)
{
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
wglMakeCurrent(surface->hDC, surface->glContext);
oc_gl_select_api(&surface->api);
wglMakeCurrent(surface->hDC, surface->glContext);
oc_gl_select_api(&surface->api);
}
void oc_wgl_surface_present(oc_surface_data* interface)
{
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
SwapBuffers(surface->hDC);
SwapBuffers(surface->hDC);
}
void oc_wgl_surface_deselect(oc_surface_data* interface)
{
wglMakeCurrent(NULL, NULL);
oc_gl_deselect_api();
wglMakeCurrent(NULL, NULL);
oc_gl_deselect_api();
}
void oc_wgl_surface_swap_interval(oc_surface_data* interface, int swap)
{
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
wglSwapIntervalEXT(swap);
oc_wgl_surface* surface = (oc_wgl_surface*)interface;
wglSwapIntervalEXT(swap);
}
void* oc_wgl_get_proc(const char* name)
{
void* p = wglGetProcAddress(name);
if( p == 0
|| p == (void*)0x01
|| p == (void*)0x02
|| p == (void*)0x03
|| p == (void*)(-1))
{
//TODO: should we avoid re-loading every time?
HMODULE module = LoadLibrary("opengl32.dll");
p = (void*)GetProcAddress(module, name);
}
return(p);
void* p = wglGetProcAddress(name);
if(p == 0
|| p == (void*)0x01
|| p == (void*)0x02
|| p == (void*)0x03
|| p == (void*)(-1))
{
//TODO: should we avoid re-loading every time?
HMODULE module = LoadLibrary("opengl32.dll");
p = (void*)GetProcAddress(module, name);
}
return (p);
}
oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
{
oc_wgl_surface* surface = 0;
oc_wgl_surface* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
oc_wgl_init();
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
oc_wgl_init();
//NOTE: fill surface data and load api
surface = oc_malloc_type(oc_wgl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_wgl_surface));
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
//NOTE: fill surface data and load api
surface = oc_malloc_type(oc_wgl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_wgl_surface));
oc_surface_init_for_window((oc_surface_data*)surface, windowData);
surface->interface.api = OC_GL;
surface->interface.destroy = oc_wgl_surface_destroy;
surface->interface.prepare = oc_wgl_surface_prepare;
surface->interface.present = oc_wgl_surface_present;
surface->interface.swapInterval = oc_wgl_surface_swap_interval;
surface->interface.deselect = oc_wgl_surface_deselect;
surface->interface.api = OC_GL;
surface->interface.destroy = oc_wgl_surface_destroy;
surface->interface.prepare = oc_wgl_surface_prepare;
surface->interface.present = oc_wgl_surface_present;
surface->interface.swapInterval = oc_wgl_surface_swap_interval;
surface->interface.deselect = oc_wgl_surface_deselect;
surface->hDC = GetDC(surface->interface.layer.hWnd);
surface->hDC = GetDC(surface->interface.layer.hWnd);
//NOTE(martin): create the pixel format and gl context
PIXELFORMATDESCRIPTOR pixelFormatDesc =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
//NOTE(martin): create the pixel format and gl context
PIXELFORMATDESCRIPTOR pixelFormatDesc = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int pixelFormatAttrs[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_TRANSPARENT_ARB, TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0};
int pixelFormatAttrs[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_TRANSPARENT_ARB, TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0
};
u32 numFormats = 0;
int pixelFormat = 0;
u32 numFormats = 0;
int pixelFormat = 0;
wglChoosePixelFormatARB(surface->hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats);
wglChoosePixelFormatARB(surface->hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats);
if(!pixelFormat)
{
//TODO: error
}
SetPixelFormat(surface->hDC, pixelFormat, &pixelFormatDesc);
if(!pixelFormat)
{
//TODO: error
}
SetPixelFormat(surface->hDC, pixelFormat, &pixelFormatDesc);
int contextAttrs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0};
int contextAttrs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs);
surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs);
if(!surface->glContext)
{
//TODO error
int error = GetLastError();
printf("error: %i\n", error);
}
if(!surface->glContext)
{
//TODO error
int error = GetLastError();
printf("error: %i\n", error);
}
//NOTE: make gl context current and load api
wglMakeCurrent(surface->hDC, surface->glContext);
wglSwapIntervalEXT(1);
oc_gl_load_gl44(&surface->api, oc_wgl_get_proc);
}
}
return((oc_surface_data*)surface);
//NOTE: make gl context current and load api
wglMakeCurrent(surface->hDC, surface->glContext);
wglSwapIntervalEXT(1);
oc_gl_load_gl44(&surface->api, oc_wgl_get_proc);
}
}
return ((oc_surface_data*)surface);
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: wgl_surface.c
* @author: Martin Fouilleul
@ -9,7 +9,7 @@
#ifndef __WGL_SURFACE_H_
#define __WGL_SURFACE_H_
#include"graphics_surface.h"
#include "graphics_surface.h"
oc_surface_data* oc_wgl_surface_create_for_window(oc_window window);

View File

@ -1,14 +1,14 @@
#include "platform/platform_debug.h"
#include <features.h>
#include"platform/platform_debug.h"
#undef assert
#ifdef NDEBUG
#define assert(x) (void)0
#define assert(x) (void)0
#else
#define assert(x) OC_ASSERT(x)
#define assert(x) OC_ASSERT(x)
#endif
#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
#define static_assert _Static_assert
#define static_assert _Static_assert
#endif

View File

@ -1,134 +1,134 @@
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define EDEADLK 35
#define ENAMETOOLONG 36
#define ENOLCK 37
#define ENOSYS 38
#define ENOTEMPTY 39
#define ELOOP 40
#define EWOULDBLOCK EAGAIN
#define ENOMSG 42
#define EIDRM 43
#define ECHRNG 44
#define EL2NSYNC 45
#define EL3HLT 46
#define EL3RST 47
#define ELNRNG 48
#define EUNATCH 49
#define ENOCSI 50
#define EL2HLT 51
#define EBADE 52
#define EBADR 53
#define EXFULL 54
#define ENOANO 55
#define EBADRQC 56
#define EBADSLT 57
#define EDEADLOCK EDEADLK
#define EBFONT 59
#define ENOSTR 60
#define ENODATA 61
#define ETIME 62
#define ENOSR 63
#define ENONET 64
#define ENOPKG 65
#define EREMOTE 66
#define ENOLINK 67
#define EADV 68
#define ESRMNT 69
#define ECOMM 70
#define EPROTO 71
#define EMULTIHOP 72
#define EDOTDOT 73
#define EBADMSG 74
#define EOVERFLOW 75
#define ENOTUNIQ 76
#define EBADFD 77
#define EREMCHG 78
#define ELIBACC 79
#define ELIBBAD 80
#define ELIBSCN 81
#define ELIBMAX 82
#define ELIBEXEC 83
#define EILSEQ 84
#define ERESTART 85
#define ESTRPIPE 86
#define EUSERS 87
#define ENOTSOCK 88
#define EDESTADDRREQ 89
#define EMSGSIZE 90
#define EPROTOTYPE 91
#define ENOPROTOOPT 92
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define EDEADLK 35
#define ENAMETOOLONG 36
#define ENOLCK 37
#define ENOSYS 38
#define ENOTEMPTY 39
#define ELOOP 40
#define EWOULDBLOCK EAGAIN
#define ENOMSG 42
#define EIDRM 43
#define ECHRNG 44
#define EL2NSYNC 45
#define EL3HLT 46
#define EL3RST 47
#define ELNRNG 48
#define EUNATCH 49
#define ENOCSI 50
#define EL2HLT 51
#define EBADE 52
#define EBADR 53
#define EXFULL 54
#define ENOANO 55
#define EBADRQC 56
#define EBADSLT 57
#define EDEADLOCK EDEADLK
#define EBFONT 59
#define ENOSTR 60
#define ENODATA 61
#define ETIME 62
#define ENOSR 63
#define ENONET 64
#define ENOPKG 65
#define EREMOTE 66
#define ENOLINK 67
#define EADV 68
#define ESRMNT 69
#define ECOMM 70
#define EPROTO 71
#define EMULTIHOP 72
#define EDOTDOT 73
#define EBADMSG 74
#define EOVERFLOW 75
#define ENOTUNIQ 76
#define EBADFD 77
#define EREMCHG 78
#define ELIBACC 79
#define ELIBBAD 80
#define ELIBSCN 81
#define ELIBMAX 82
#define ELIBEXEC 83
#define EILSEQ 84
#define ERESTART 85
#define ESTRPIPE 86
#define EUSERS 87
#define ENOTSOCK 88
#define EDESTADDRREQ 89
#define EMSGSIZE 90
#define EPROTOTYPE 91
#define ENOPROTOOPT 92
#define EPROTONOSUPPORT 93
#define ESOCKTNOSUPPORT 94
#define EOPNOTSUPP 95
#define ENOTSUP EOPNOTSUPP
#define EPFNOSUPPORT 96
#define EAFNOSUPPORT 97
#define EADDRINUSE 98
#define EADDRNOTAVAIL 99
#define ENETDOWN 100
#define ENETUNREACH 101
#define ENETRESET 102
#define ECONNABORTED 103
#define ECONNRESET 104
#define ENOBUFS 105
#define EISCONN 106
#define ENOTCONN 107
#define ESHUTDOWN 108
#define ETOOMANYREFS 109
#define ETIMEDOUT 110
#define ECONNREFUSED 111
#define EHOSTDOWN 112
#define EHOSTUNREACH 113
#define EALREADY 114
#define EINPROGRESS 115
#define ESTALE 116
#define EUCLEAN 117
#define ENOTNAM 118
#define ENAVAIL 119
#define EISNAM 120
#define EREMOTEIO 121
#define EDQUOT 122
#define ENOMEDIUM 123
#define EMEDIUMTYPE 124
#define ECANCELED 125
#define ENOKEY 126
#define EKEYEXPIRED 127
#define EKEYREVOKED 128
#define EKEYREJECTED 129
#define EOWNERDEAD 130
#define EOPNOTSUPP 95
#define ENOTSUP EOPNOTSUPP
#define EPFNOSUPPORT 96
#define EAFNOSUPPORT 97
#define EADDRINUSE 98
#define EADDRNOTAVAIL 99
#define ENETDOWN 100
#define ENETUNREACH 101
#define ENETRESET 102
#define ECONNABORTED 103
#define ECONNRESET 104
#define ENOBUFS 105
#define EISCONN 106
#define ENOTCONN 107
#define ESHUTDOWN 108
#define ETOOMANYREFS 109
#define ETIMEDOUT 110
#define ECONNREFUSED 111
#define EHOSTDOWN 112
#define EHOSTUNREACH 113
#define EALREADY 114
#define EINPROGRESS 115
#define ESTALE 116
#define EUCLEAN 117
#define ENOTNAM 118
#define ENAVAIL 119
#define EISNAM 120
#define EREMOTEIO 121
#define EDQUOT 122
#define ENOMEDIUM 123
#define EMEDIUMTYPE 124
#define ECANCELED 125
#define ENOKEY 126
#define EKEYEXPIRED 127
#define EKEYREVOKED 128
#define EKEYREJECTED 129
#define EOWNERDEAD 130
#define ENOTRECOVERABLE 131
#define ERFKILL 132
#define EHWPOISON 133
#define ERFKILL 132
#define EHWPOISON 133

View File

@ -1,8 +1,9 @@
#ifndef _ERRNO_H
#ifndef _ERRNO_H
#define _ERRNO_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include <features.h>
@ -10,13 +11,14 @@ extern "C" {
#include <bits/errno.h>
#ifdef __GNUC__
__attribute__((const))
__attribute__((const))
#endif
int *__errno_location(void);
int*
__errno_location(void);
#define errno (*__errno_location())
#ifdef _GNU_SOURCE
extern char *program_invocation_short_name, *program_invocation_name;
extern char *program_invocation_short_name, *program_invocation_name;
#endif
#ifdef __cplusplus
@ -24,4 +26,3 @@ extern char *program_invocation_short_name, *program_invocation_name;
#endif
#endif

View File

@ -2,10 +2,11 @@
#define _FLOAT_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
int __flt_rounds(void);
int __flt_rounds(void);
#define FLT_ROUNDS (__flt_rounds())
#define FLT_RADIX 2

View File

@ -2,90 +2,99 @@
#define _MATH_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
// NOTE(orca): not doing anything fancy for float_t and double_t
typedef float float_t;
typedef double double_t;
// NOTE(orca): not doing anything fancy for float_t and double_t
typedef float float_t;
typedef double double_t;
#define NAN __builtin_nanf("")
#define INFINITY __builtin_inff()
#define NAN __builtin_nanf("")
#define INFINITY __builtin_inff()
#define FP_NAN 0
#define FP_INFINITE 1
#define FP_ZERO 2
#define FP_NAN 0
#define FP_INFINITE 1
#define FP_ZERO 2
#define FP_SUBNORMAL 3
#define FP_NORMAL 4
#define FP_NORMAL 4
int __fpclassify(double);
int __fpclassifyf(float);
int __fpclassifyl(long double);
int __fpclassify(double);
int __fpclassifyf(float);
int __fpclassifyl(long double);
static __inline unsigned __FLOAT_BITS(float __f)
{
union {float __f; unsigned __i;} __u;
__u.__f = __f;
return __u.__i;
}
static __inline unsigned long long __DOUBLE_BITS(double __f)
{
union {double __f; unsigned long long __i;} __u;
__u.__f = __f;
return __u.__i;
}
static __inline unsigned __FLOAT_BITS(float __f)
{
union
{
float __f;
unsigned __i;
} __u;
#define fpclassify(x) ( \
sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \
sizeof(x) == sizeof(double) ? __fpclassify(x) : \
__fpclassifyl(x) )
__u.__f = __f;
return __u.__i;
}
#define isinf(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \
__fpclassifyl(x) == FP_INFINITE)
static __inline unsigned long long __DOUBLE_BITS(double __f)
{
union
{
double __f;
unsigned long long __i;
} __u;
#define isnan(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \
__fpclassifyl(x) == FP_NAN)
__u.__f = __f;
return __u.__i;
}
double acos(double);
#define fpclassify(x) ( \
sizeof(x) == sizeof(float) ? __fpclassifyf(x) : sizeof(x) == sizeof(double) ? __fpclassify(x) \
: __fpclassifyl(x))
double ceil(double);
#define isinf(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \
: __fpclassifyl(x) == FP_INFINITE)
double cos(double);
float cosf(float);
#define isnan(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \
: __fpclassifyl(x) == FP_NAN)
double fabs(double);
double acos(double);
double floor(double);
double ceil(double);
double fmod(double, double);
double cos(double);
float cosf(float);
double pow(double, double);
double fabs(double);
double scalbn(double, int);
double floor(double);
double sin(double);
float sinf(float);
double fmod(double, double);
double sqrt(double);
float sqrtf(float);
double pow(double, double);
#define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log_2 e */
#define M_LOG10E 0.43429448190325182765 /* log_10 e */
#define M_LN2 0.69314718055994530942 /* log_e 2 */
#define M_LN10 2.30258509299404568402 /* log_e 10 */
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_PI_4 0.78539816339744830962 /* pi/4 */
#define M_1_PI 0.31830988618379067154 /* 1/pi */
#define M_2_PI 0.63661977236758134308 /* 2/pi */
#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
double scalbn(double, int);
double sin(double);
float sinf(float);
double sqrt(double);
float sqrtf(float);
#define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log_2 e */
#define M_LOG10E 0.43429448190325182765 /* log_10 e */
#define M_LN2 0.69314718055994530942 /* log_e 2 */
#define M_LN10 2.30258509299404568402 /* log_e 10 */
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_PI_4 0.78539816339744830962 /* pi/4 */
#define M_1_PI 0.31830988618379067154 /* 1/pi */
#define M_2_PI 0.63661977236758134308 /* 2/pi */
#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
#ifdef __cplusplus
}

View File

@ -1,4 +1,4 @@
/************************************************************//**
/************************************************************/ /**
*
* @file: stdarg.h
* @author: Martin Fouilleul

View File

@ -2,12 +2,13 @@
#define _STDLIB_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#define abort(...) OC_ABORT(__VA_ARGS__)
int abs (int);
int abs(int);
#ifdef __cplusplus
}

View File

@ -1,13 +1,13 @@
#include"stb/stb_sprintf.h"
#include "stb/stb_sprintf.h"
void* memset(void* b, int c, size_t n);
void* memcpy(void *restrict dst, const void *restrict src, size_t n);
void* memmove(void *dst, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void* memcpy(void* restrict dst, const void* restrict src, size_t n);
void* memmove(void* dst, const void* src, size_t n);
int memcmp(const void* s1, const void* s2, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
char* strcpy(char *restrict s1, const char *restrict s2);
size_t strlen(const char* s);
int strcmp(const char* s1, const char* s2);
int strncmp(const char* s1, const char* s2, size_t n);
char* strcpy(char* restrict s1, const char* restrict s2);
#define vsnprintf stbsp_vsnprintf

View File

@ -51,21 +51,21 @@
#include "libm.h"
static const double
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
double __cos(double x, double y)
{
double_t hz,z,r,w;
double_t hz, z, r, w;
z = x*x;
w = z*z;
r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
z = x * x;
w = z * z;
r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));
hz = 0.5 * z;
w = 1.0 - hz;
return w + (((1.0 - w) - hz) + (z * r - x * y));
}

View File

@ -18,18 +18,18 @@
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
static const double
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
float __cosdf(double x)
{
double_t r, w, z;
double_t r, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = C2+z*C3;
return ((1.0+z*C0) + w*C1) + (w*z)*r;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x * x;
w = z * z;
r = C2 + z * C3;
return ((1.0 + z * C0) + w * C1) + (w * z) * r;
}

View File

@ -2,7 +2,7 @@
int errno;
int *__errno_location(void)
int* __errno_location(void)
{
// NOTE(orca): We might need a better solution if we eventually support wasm threads.
return &errno;

View File

@ -2,5 +2,5 @@
double __math_invalid(double x)
{
return (x - x) / (x - x);
return (x - x) / (x - x);
}

View File

@ -2,5 +2,5 @@
float __math_invalidf(float x)
{
return (x - x) / (x - x);
return (x - x) / (x - x);
}

View File

@ -2,5 +2,5 @@
double __math_oflow(uint32_t sign)
{
return __math_xflow(sign, 0x1p769);
return __math_xflow(sign, 0x1p769);
}

View File

@ -2,5 +2,5 @@
double __math_uflow(uint32_t sign)
{
return __math_xflow(sign, 0x1p-767);
return __math_xflow(sign, 0x1p-767);
}

View File

@ -3,6 +3,6 @@
double __math_xflow(uint32_t sign, double y)
{
// NOTE(orca): no fp barriers
// return eval_as_double(fp_barrier(sign ? -y : y) * y);
return eval_as_double((sign ? -y : y) * y);
// return eval_as_double(fp_barrier(sign ? -y : y) * y);
return eval_as_double((sign ? -y : y) * y);
}

View File

@ -19,10 +19,10 @@
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
/*
@ -35,156 +35,190 @@
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const double
toint = 1.5/EPS,
pio4 = 0x1.921fb54442d18p-1,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
toint = 1.5 / EPS,
pio4 = 0x1.921fb54442d18p-1,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
int __rem_pio2(double x, double *y)
int __rem_pio2(double x, double* y)
{
union {double f; uint64_t i;} u = {x};
double_t z,w,t,r,fn;
double tx[3],ty[2];
uint32_t ix;
int sign, n, ex, ey, i;
union
{
double f;
uint64_t i;
} u = { x };
sign = u.i>>63;
ix = u.i>>32 & 0x7fffffff;
if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
goto medium; /* cancellation -- use medium case */
if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
if (!sign) {
z = x - pio2_1; /* one round good to 85 bits */
y[0] = z - pio2_1t;
y[1] = (z-y[0]) - pio2_1t;
return 1;
} else {
z = x + pio2_1;
y[0] = z + pio2_1t;
y[1] = (z-y[0]) + pio2_1t;
return -1;
}
} else {
if (!sign) {
z = x - 2*pio2_1;
y[0] = z - 2*pio2_1t;
y[1] = (z-y[0]) - 2*pio2_1t;
return 2;
} else {
z = x + 2*pio2_1;
y[0] = z + 2*pio2_1t;
y[1] = (z-y[0]) + 2*pio2_1t;
return -2;
}
}
}
if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
goto medium;
if (!sign) {
z = x - 3*pio2_1;
y[0] = z - 3*pio2_1t;
y[1] = (z-y[0]) - 3*pio2_1t;
return 3;
} else {
z = x + 3*pio2_1;
y[0] = z + 3*pio2_1t;
y[1] = (z-y[0]) + 3*pio2_1t;
return -3;
}
} else {
if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
goto medium;
if (!sign) {
z = x - 4*pio2_1;
y[0] = z - 4*pio2_1t;
y[1] = (z-y[0]) - 4*pio2_1t;
return 4;
} else {
z = x + 4*pio2_1;
y[0] = z + 4*pio2_1t;
y[1] = (z-y[0]) + 4*pio2_1t;
return -4;
}
}
}
if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
medium:
/* rint(x/(pi/2)) */
fn = (double_t)x*invpio2 + toint - toint;
n = (int32_t)fn;
r = x - fn*pio2_1;
w = fn*pio2_1t; /* 1st round, good to 85 bits */
/* Matters with directed rounding. */
if (predict_false(r - w < -pio4)) {
n--;
fn--;
r = x - fn*pio2_1;
w = fn*pio2_1t;
} else if (predict_false(r - w > pio4)) {
n++;
fn++;
r = x - fn*pio2_1;
w = fn*pio2_1t;
}
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
ex = ix>>20;
if (ex - ey > 16) { /* 2nd round, good to 118 bits */
t = r;
w = fn*pio2_2;
r = t - w;
w = fn*pio2_2t - ((t-r)-w);
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
t = r;
w = fn*pio2_3;
r = t - w;
w = fn*pio2_3t - ((t-r)-w);
y[0] = r - w;
}
}
y[1] = (r - y[0]) - w;
return n;
}
/*
double_t z, w, t, r, fn;
double tx[3], ty[2];
uint32_t ix;
int sign, n, ex, ey, i;
sign = u.i >> 63;
ix = u.i >> 32 & 0x7fffffff;
if(ix <= 0x400f6a7a)
{ /* |x| ~<= 5pi/4 */
if((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
goto medium; /* cancellation -- use medium case */
if(ix <= 0x4002d97c)
{ /* |x| ~<= 3pi/4 */
if(!sign)
{
z = x - pio2_1; /* one round good to 85 bits */
y[0] = z - pio2_1t;
y[1] = (z - y[0]) - pio2_1t;
return 1;
}
else
{
z = x + pio2_1;
y[0] = z + pio2_1t;
y[1] = (z - y[0]) + pio2_1t;
return -1;
}
}
else
{
if(!sign)
{
z = x - 2 * pio2_1;
y[0] = z - 2 * pio2_1t;
y[1] = (z - y[0]) - 2 * pio2_1t;
return 2;
}
else
{
z = x + 2 * pio2_1;
y[0] = z + 2 * pio2_1t;
y[1] = (z - y[0]) + 2 * pio2_1t;
return -2;
}
}
}
if(ix <= 0x401c463b)
{ /* |x| ~<= 9pi/4 */
if(ix <= 0x4015fdbc)
{ /* |x| ~<= 7pi/4 */
if(ix == 0x4012d97c) /* |x| ~= 3pi/2 */
goto medium;
if(!sign)
{
z = x - 3 * pio2_1;
y[0] = z - 3 * pio2_1t;
y[1] = (z - y[0]) - 3 * pio2_1t;
return 3;
}
else
{
z = x + 3 * pio2_1;
y[0] = z + 3 * pio2_1t;
y[1] = (z - y[0]) + 3 * pio2_1t;
return -3;
}
}
else
{
if(ix == 0x401921fb) /* |x| ~= 4pi/2 */
goto medium;
if(!sign)
{
z = x - 4 * pio2_1;
y[0] = z - 4 * pio2_1t;
y[1] = (z - y[0]) - 4 * pio2_1t;
return 4;
}
else
{
z = x + 4 * pio2_1;
y[0] = z + 4 * pio2_1t;
y[1] = (z - y[0]) + 4 * pio2_1t;
return -4;
}
}
}
if(ix < 0x413921fb)
{ /* |x| ~< 2^20*(pi/2), medium size */
medium:
/* rint(x/(pi/2)) */
fn = (double_t)x * invpio2 + toint - toint;
n = (int32_t)fn;
r = x - fn * pio2_1;
w = fn * pio2_1t; /* 1st round, good to 85 bits */
/* Matters with directed rounding. */
if(predict_false(r - w < -pio4))
{
n--;
fn--;
r = x - fn * pio2_1;
w = fn * pio2_1t;
}
else if(predict_false(r - w > pio4))
{
n++;
fn++;
r = x - fn * pio2_1;
w = fn * pio2_1t;
}
y[0] = r - w;
u.f = y[0];
ey = u.i >> 52 & 0x7ff;
ex = ix >> 20;
if(ex - ey > 16)
{ /* 2nd round, good to 118 bits */
t = r;
w = fn * pio2_2;
r = t - w;
w = fn * pio2_2t - ((t - r) - w);
y[0] = r - w;
u.f = y[0];
ey = u.i >> 52 & 0x7ff;
if(ex - ey > 49)
{ /* 3rd round, good to 151 bits, covers all cases */
t = r;
w = fn * pio2_3;
r = t - w;
w = fn * pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
y[1] = (r - y[0]) - w;
return n;
}
/*
* all other (large) arguments
*/
if (ix >= 0x7ff00000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
/* set z = scalbn(|x|,-ilogb(x)+23) */
u.f = x;
u.i &= (uint64_t)-1>>12;
u.i |= (uint64_t)(0x3ff + 23)<<52;
z = u.f;
for (i=0; i < 2; i++) {
tx[i] = (double)(int32_t)z;
z = (z-tx[i])*0x1p24;
}
tx[i] = z;
/* skip zero terms, first term is non-zero */
while (tx[i] == 0.0)
i--;
n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
if (sign) {
y[0] = -ty[0];
y[1] = -ty[1];
return -n;
}
y[0] = ty[0];
y[1] = ty[1];
return n;
if(ix >= 0x7ff00000)
{ /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
/* set z = scalbn(|x|,-ilogb(x)+23) */
u.f = x;
u.i &= (uint64_t)-1 >> 12;
u.i |= (uint64_t)(0x3ff + 23) << 52;
z = u.f;
for(i = 0; i < 2; i++)
{
tx[i] = (double)(int32_t)z;
z = (z - tx[i]) * 0x1p24;
}
tx[i] = z;
/* skip zero terms, first term is non-zero */
while(tx[i] == 0.0)
i--;
n = __rem_pio2_large(tx, ty, (int)(ix >> 20) - (0x3ff + 23), i + 1, 1);
if(sign)
{
y[0] = -ty[0];
y[1] = -ty[1];
return -n;
}
y[0] = ty[0];
y[1] = ty[1];
return n;
}

File diff suppressed because it is too large Load Diff

View File

@ -22,10 +22,10 @@
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
/*
@ -34,53 +34,64 @@
* pio2_1t: pi/2 - pio2_1
*/
static const double
toint = 1.5/EPS,
pio4 = 0x1.921fb6p-1,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
toint = 1.5 / EPS,
pio4 = 0x1.921fb6p-1,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
int __rem_pio2f(float x, double *y)
int __rem_pio2f(float x, double* y)
{
union {float f; uint32_t i;} u = {x};
double tx[1],ty[1];
double_t fn;
uint32_t ix;
int n, sign, e0;
union
{
float f;
uint32_t i;
} u = { x };
ix = u.i & 0x7fffffff;
/* 25+53 bit pi is good enough for medium size */
if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
/* Use a specialized rint() to get fn. */
fn = (double_t)x*invpio2 + toint - toint;
n = (int32_t)fn;
*y = x - fn*pio2_1 - fn*pio2_1t;
/* Matters with directed rounding. */
if (predict_false(*y < -pio4)) {
n--;
fn--;
*y = x - fn*pio2_1 - fn*pio2_1t;
} else if (predict_false(*y > pio4)) {
n++;
fn++;
*y = x - fn*pio2_1 - fn*pio2_1t;
}
return n;
}
if(ix>=0x7f800000) { /* x is inf or NaN */
*y = x-x;
return 0;
}
/* scale x into [2^23, 2^24-1] */
sign = u.i>>31;
e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */
u.i = ix - (e0<<23);
tx[0] = u.f;
n = __rem_pio2_large(tx,ty,e0,1,0);
if (sign) {
*y = -ty[0];
return -n;
}
*y = ty[0];
return n;
double tx[1], ty[1];
double_t fn;
uint32_t ix;
int n, sign, e0;
ix = u.i & 0x7fffffff;
/* 25+53 bit pi is good enough for medium size */
if(ix < 0x4dc90fdb)
{ /* |x| ~< 2^28*(pi/2), medium size */
/* Use a specialized rint() to get fn. */
fn = (double_t)x * invpio2 + toint - toint;
n = (int32_t)fn;
*y = x - fn * pio2_1 - fn * pio2_1t;
/* Matters with directed rounding. */
if(predict_false(*y < -pio4))
{
n--;
fn--;
*y = x - fn * pio2_1 - fn * pio2_1t;
}
else if(predict_false(*y > pio4))
{
n++;
fn++;
*y = x - fn * pio2_1 - fn * pio2_1t;
}
return n;
}
if(ix >= 0x7f800000)
{ /* x is inf or NaN */
*y = x - x;
return 0;
}
/* scale x into [2^23, 2^24-1] */
sign = u.i >> 31;
e0 = (ix >> 23) - (0x7f + 23); /* e0 = ilogb(|x|)-23, positive */
u.i = ix - (e0 << 23);
tx[0] = u.f;
n = __rem_pio2_large(tx, ty, e0, 1, 0);
if(sign)
{
*y = -ty[0];
return -n;
}
*y = ty[0];
return n;
}

View File

@ -42,23 +42,23 @@
#include "libm.h"
static const double
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
double __sin(double x, double y, int iy)
{
double_t z,r,v,w;
double_t z, r, v, w;
z = x*x;
w = z*z;
r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
v = z*x;
if (iy == 0)
return x + v*(S1 + z*r);
else
return x - ((z*(0.5*y - v*r) - y) - v*S1);
z = x * x;
w = z * z;
r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);
v = z * x;
if(iy == 0)
return x + v * (S1 + z * r);
else
return x - ((z * (0.5 * y - v * r) - y) - v * S1);
}

View File

@ -18,19 +18,19 @@
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
static const double
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
float __sindf(double x)
{
double_t r, s, w, z;
double_t r, s, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = S3 + z*S4;
s = z*x;
return (x + s*(S1 + z*S2)) + s*w*r;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x * x;
w = z * z;
r = S3 + z * S4;
s = z * x;
return (x + s * (S1 + z * S2)) + s * w * r;
}

View File

@ -2,5 +2,5 @@
int abs(int a)
{
return a>0 ? a : -a;
return a > 0 ? a : -a;
}

View File

@ -36,66 +36,70 @@
#include "libm.h"
static const double
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
static double R(double z)
{
double_t p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
return p/q;
double_t p, q;
p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
return p / q;
}
double acos(double x)
{
double z,w,s,c,df;
uint32_t hx,ix;
double z, w, s, c, df;
uint32_t hx, ix;
GET_HIGH_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if (ix >= 0x3ff00000) {
uint32_t lx;
GET_HIGH_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if(ix >= 0x3ff00000)
{
uint32_t lx;
GET_LOW_WORD(lx,x);
if ((ix-0x3ff00000 | lx) == 0) {
/* acos(1)=0, acos(-1)=pi */
if (hx >> 31)
return 2*pio2_hi + 0x1p-120f;
return 0;
}
return 0/(x-x);
}
/* |x| < 0.5 */
if (ix < 0x3fe00000) {
if (ix <= 0x3c600000) /* |x| < 2**-57 */
return pio2_hi + 0x1p-120f;
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
}
/* x < -0.5 */
if (hx >> 31) {
z = (1.0+x)*0.5;
s = sqrt(z);
w = R(z)*s-pio2_lo;
return 2*(pio2_hi - (s+w));
}
/* x > 0.5 */
z = (1.0-x)*0.5;
s = sqrt(z);
df = s;
SET_LOW_WORD(df,0);
c = (z-df*df)/(s+df);
w = R(z)*s+c;
return 2*(df+w);
GET_LOW_WORD(lx, x);
if((ix - 0x3ff00000 | lx) == 0)
{
/* acos(1)=0, acos(-1)=pi */
if(hx >> 31)
return 2 * pio2_hi + 0x1p-120f;
return 0;
}
return 0 / (x - x);
}
/* |x| < 0.5 */
if(ix < 0x3fe00000)
{
if(ix <= 0x3c600000) /* |x| < 2**-57 */
return pio2_hi + 0x1p-120f;
return pio2_hi - (x - (pio2_lo - x * R(x * x)));
}
/* x < -0.5 */
if(hx >> 31)
{
z = (1.0 + x) * 0.5;
s = sqrt(z);
w = R(z) * s - pio2_lo;
return 2 * (pio2_hi - (s + w));
}
/* x > 0.5 */
z = (1.0 - x) * 0.5;
s = sqrt(z);
df = s;
SET_LOW_WORD(df, 0);
c = (z - df * df) / (s + df);
w = R(z) * s + c;
return 2 * (df + w);
}

View File

@ -1,31 +1,37 @@
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
static const double_t toint = 1/EPS;
static const double_t toint = 1 / EPS;
double ceil(double x)
{
union {double f; uint64_t i;} u = {x};
int e = u.i >> 52 & 0x7ff;
double_t y;
union
{
double f;
uint64_t i;
} u = { x };
if (e >= 0x3ff+52 || x == 0)
return x;
/* y = int(x) - x, where int(x) is an integer neighbor of x */
if (u.i >> 63)
y = x - toint + toint - x;
else
y = x + toint - toint - x;
/* special case because of non-nearest rounding modes */
if (e <= 0x3ff-1) {
FORCE_EVAL(y);
return u.i >> 63 ? -0.0 : 1;
}
if (y < 0)
return x + y + 1;
return x + y;
int e = u.i >> 52 & 0x7ff;
double_t y;
if(e >= 0x3ff + 52 || x == 0)
return x;
/* y = int(x) - x, where int(x) is an integer neighbor of x */
if(u.i >> 63)
y = x - toint + toint - x;
else
y = x + toint - toint - x;
/* special case because of non-nearest rounding modes */
if(e <= 0x3ff - 1)
{
FORCE_EVAL(y);
return u.i >> 63 ? -0.0 : 1;
}
if(y < 0)
return x + y + 1;
return x + y;
}

View File

@ -44,34 +44,40 @@
double cos(double x)
{
double y[2];
uint32_t ix;
unsigned n;
double y[2];
uint32_t ix;
unsigned n;
GET_HIGH_WORD(ix, x);
ix &= 0x7fffffff;
GET_HIGH_WORD(ix, x);
ix &= 0x7fffffff;
/* |x| ~< pi/4 */
if (ix <= 0x3fe921fb) {
if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */
/* raise inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
return 1.0;
}
return __cos(x, 0);
}
/* |x| ~< pi/4 */
if(ix <= 0x3fe921fb)
{
if(ix < 0x3e46a09e)
{ /* |x| < 2**-27 * sqrt(2) */
/* raise inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
return 1.0;
}
return __cos(x, 0);
}
/* cos(Inf or NaN) is NaN */
if (ix >= 0x7ff00000)
return x-x;
/* cos(Inf or NaN) is NaN */
if(ix >= 0x7ff00000)
return x - x;
/* argument reduction */
n = __rem_pio2(x, y);
switch (n&3) {
case 0: return __cos(y[0], y[1]);
case 1: return -__sin(y[0], y[1], 1);
case 2: return -__cos(y[0], y[1]);
default:
return __sin(y[0], y[1], 1);
}
/* argument reduction */
n = __rem_pio2(x, y);
switch(n & 3)
{
case 0:
return __cos(y[0], y[1]);
case 1:
return -__sin(y[0], y[1], 1);
case 2:
return -__cos(y[0], y[1]);
default:
return __sin(y[0], y[1], 1);
}
}

View File

@ -18,61 +18,71 @@
/* Small multiples of pi/2 rounded to double precision. */
static const double
c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
c1pio2 = 1 * M_PI_2, /* 0x3FF921FB, 0x54442D18 */
c2pio2 = 2 * M_PI_2, /* 0x400921FB, 0x54442D18 */
c3pio2 = 3 * M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
c4pio2 = 4 * M_PI_2; /* 0x401921FB, 0x54442D18 */
float cosf(float x)
{
double y;
uint32_t ix;
unsigned n, sign;
double y;
uint32_t ix;
unsigned n, sign;
GET_FLOAT_WORD(ix, x);
sign = ix >> 31;
ix &= 0x7fffffff;
GET_FLOAT_WORD(ix, x);
sign = ix >> 31;
ix &= 0x7fffffff;
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
if (ix < 0x39800000) { /* |x| < 2**-12 */
/* raise inexact if x != 0 */
FORCE_EVAL(x + 0x1p120f);
return 1.0f;
}
return __cosdf(x);
}
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */
return -__cosdf(sign ? x+c2pio2 : x-c2pio2);
else {
if (sign)
return __sindf(x + c1pio2);
else
return __sindf(c1pio2 - x);
}
}
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */
return __cosdf(sign ? x+c4pio2 : x-c4pio2);
else {
if (sign)
return __sindf(-x - c3pio2);
else
return __sindf(x - c3pio2);
}
}
if(ix <= 0x3f490fda)
{ /* |x| ~<= pi/4 */
if(ix < 0x39800000)
{ /* |x| < 2**-12 */
/* raise inexact if x != 0 */
FORCE_EVAL(x + 0x1p120f);
return 1.0f;
}
return __cosdf(x);
}
if(ix <= 0x407b53d1)
{ /* |x| ~<= 5*pi/4 */
if(ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */
return -__cosdf(sign ? x + c2pio2 : x - c2pio2);
else
{
if(sign)
return __sindf(x + c1pio2);
else
return __sindf(c1pio2 - x);
}
}
if(ix <= 0x40e231d5)
{ /* |x| ~<= 9*pi/4 */
if(ix > 0x40afeddf) /* |x| ~> 7*pi/4 */
return __cosdf(sign ? x + c4pio2 : x - c4pio2);
else
{
if(sign)
return __sindf(-x - c3pio2);
else
return __sindf(x - c3pio2);
}
}
/* cos(Inf or NaN) is NaN */
if (ix >= 0x7f800000)
return x-x;
/* cos(Inf or NaN) is NaN */
if(ix >= 0x7f800000)
return x - x;
/* general argument reduction needed */
n = __rem_pio2f(x,&y);
switch (n&3) {
case 0: return __cosdf(y);
case 1: return __sindf(-y);
case 2: return -__cosdf(y);
default:
return __sindf(y);
}
/* general argument reduction needed */
n = __rem_pio2f(x, &y);
switch(n & 3)
{
case 0:
return __cosdf(y);
case 1:
return __sindf(-y);
case 2:
return -__cosdf(y);
default:
return __sindf(y);
}
}

View File

@ -12,15 +12,17 @@
#define EXP_POLY_ORDER 5
#define EXP_USE_TOINT_NARROW 0
#define EXP2_POLY_ORDER 5
extern const struct exp_data {
double invln2N;
double shift;
double negln2hiN;
double negln2loN;
double poly[4]; /* Last four coefficients. */
double exp2_shift;
double exp2_poly[EXP2_POLY_ORDER];
uint64_t tab[2*(1 << EXP_TABLE_BITS)];
extern const struct exp_data
{
double invln2N;
double shift;
double negln2hiN;
double negln2loN;
double poly[4]; /* Last four coefficients. */
double exp2_shift;
double exp2_poly[EXP2_POLY_ORDER];
uint64_t tab[2 * (1 << EXP_TABLE_BITS)];
} __exp_data;
#endif

View File

@ -3,7 +3,12 @@
double fabs(double x)
{
union {double f; uint64_t i;} u = {x};
u.i &= -1ULL/2;
return u.f;
union
{
double f;
uint64_t i;
} u = { x };
u.i &= -1ULL / 2;
return u.f;
}

View File

@ -1,31 +1,37 @@
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
static const double_t toint = 1/EPS;
static const double_t toint = 1 / EPS;
double floor(double x)
{
union {double f; uint64_t i;} u = {x};
int e = u.i >> 52 & 0x7ff;
double_t y;
union
{
double f;
uint64_t i;
} u = { x };
if (e >= 0x3ff+52 || x == 0)
return x;
/* y = int(x) - x, where int(x) is an integer neighbor of x */
if (u.i >> 63)
y = x - toint + toint - x;
else
y = x + toint - toint - x;
/* special case because of non-nearest rounding modes */
if (e <= 0x3ff-1) {
FORCE_EVAL(y);
return u.i >> 63 ? -1 : 0;
}
if (y > 0)
return x + y - 1;
return x + y;
int e = u.i >> 52 & 0x7ff;
double_t y;
if(e >= 0x3ff + 52 || x == 0)
return x;
/* y = int(x) - x, where int(x) is an integer neighbor of x */
if(u.i >> 63)
y = x - toint + toint - x;
else
y = x + toint - toint - x;
/* special case because of non-nearest rounding modes */
if(e <= 0x3ff - 1)
{
FORCE_EVAL(y);
return u.i >> 63 ? -1 : 0;
}
if(y > 0)
return x + y - 1;
return x + y;
}

Some files were not shown because too many files have changed in this diff Show More