Auto-formatting with clang-format
This commit is contained in:
parent
0d920670a2
commit
94b9cb2bbf
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
DisableFormat: true
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
1253
sketches/ui/main.c
1253
sketches/ui/main.c
File diff suppressed because it is too large
Load Diff
246
src/app/app.c
246
src/app/app.c
|
@ -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);
|
||||
}
|
||||
|
|
651
src/app/app.h
651
src/app/app.h
|
@ -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_
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_
|
||||
|
|
2667
src/app/osx_app.m
2667
src/app/osx_app.m
File diff suppressed because it is too large
Load Diff
2067
src/app/win32_app.c
2067
src/app/win32_app.c
File diff suppressed because it is too large
Load Diff
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
16694
src/graphics/gl_loader.c
16694
src/graphics/gl_loader.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/************************************************************//**
|
||||
/************************************************************/ /**
|
||||
*
|
||||
* @file: stdarg.h
|
||||
* @author: Martin Fouilleul
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
double __math_invalid(double x)
|
||||
{
|
||||
return (x - x) / (x - x);
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
float __math_invalidf(float x)
|
||||
{
|
||||
return (x - x) / (x - x);
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
double __math_oflow(uint32_t sign)
|
||||
{
|
||||
return __math_xflow(sign, 0x1p769);
|
||||
return __math_xflow(sign, 0x1p769);
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
double __math_uflow(uint32_t sign)
|
||||
{
|
||||
return __math_xflow(sign, 0x1p-767);
|
||||
return __math_xflow(sign, 0x1p-767);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
int abs(int a)
|
||||
{
|
||||
return a>0 ? a : -a;
|
||||
return a > 0 ? a : -a;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue