Auto-formatting with clang-format

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

View File

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

1
ext/.clang-format Normal file
View File

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

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -7,14 +7,17 @@
* *
*****************************************************************/ *****************************************************************/
#include"orca.h" #include "glsl_shaders.h"
#include"math.h" #include "math.h"
#include"glsl_shaders.h" #include "orca.h"
//---------------------------------------------------------------- //----------------------------------------------------------------
//NOTE(martin): GL vertex struct and identifiers //NOTE(martin): GL vertex struct and identifiers
//---------------------------------------------------------------- //----------------------------------------------------------------
typedef struct Vertex { float x, y; } Vertex; typedef struct Vertex
{
float x, y;
} Vertex;
typedef struct advect_program typedef struct advect_program
{ {
@ -156,7 +159,6 @@ GLuint compile_shader(const char* vs, const char* fs)
glAttachShader(prog, fragmentShader); glAttachShader(prog, fragmentShader);
glLinkProgram(prog); glLinkProgram(prog);
//TODO errors //TODO errors
int status = 0; int status = 0;
glGetProgramiv(prog, GL_LINK_STATUS, &status); glGetProgramiv(prog, GL_LINK_STATUS, &status);
@ -181,7 +183,7 @@ GLuint compile_shader(const char* vs, const char* fs)
oc_log_error("gl error %i\n", err); oc_log_error("gl error %i\n", err);
} }
return(prog); return (prog);
} }
void init_advect(advect_program* program) void init_advect(advect_program* program)
@ -284,7 +286,6 @@ void init_blit_residue(blit_residue_program* program)
program->bTex = glGetUniformLocation(program->prog, "bTex"); program->bTex = glGetUniformLocation(program->prog, "bTex");
} }
GLuint create_texture(int width, int height, GLenum internalFormat, GLenum format, GLenum type, char* initData) GLuint create_texture(int width, int height, GLenum internalFormat, GLenum format, GLenum type, char* initData)
{ {
GLuint texture; GLuint texture;
@ -295,7 +296,7 @@ GLuint create_texture(int width, int height, GLenum internalFormat, GLenum forma
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
return(texture); return (texture);
} }
GLuint create_fbo(GLuint texture) GLuint create_fbo(GLuint texture)
@ -305,7 +306,7 @@ GLuint create_fbo(GLuint texture)
glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
return(fbo); return (fbo);
} }
void init_frame_buffer(frame_buffer* framebuffer, void init_frame_buffer(frame_buffer* framebuffer,
@ -316,7 +317,7 @@ void init_frame_buffer(frame_buffer* framebuffer,
GLenum type, GLenum type,
char* initData) char* initData)
{ {
for(int i=0; i<2; i++) for(int i = 0; i < 2; i++)
{ {
framebuffer->textures[i] = create_texture(width, height, internalFormat, format, type, initData); framebuffer->textures[i] = create_texture(width, height, internalFormat, format, type, initData);
framebuffer->fbos[i] = create_fbo(framebuffer->textures[i]); framebuffer->fbos[i] = create_fbo(framebuffer->textures[i]);
@ -347,18 +348,18 @@ void frame_buffer_swap(frame_buffer* buffer)
#define texWidth (256) #define texWidth (256)
#define texHeight (256) #define texHeight (256)
float colorInitData[texWidth][texHeight][4] = {0}; float colorInitData[texWidth][texHeight][4] = { 0 };
float velocityInitData[texWidth][texHeight][4] = {0}; float velocityInitData[texWidth][texHeight][4] = { 0 };
const float EPSILON = 1., const float EPSILON = 1.,
INV_GRID_SIZE = 1./(float)texWidth, INV_GRID_SIZE = 1. / (float)texWidth,
DELTA = 1./120.; DELTA = 1. / 120.;
const GLenum TEX_INTERNAL_FORMAT = GL_RGBA32F; const GLenum TEX_INTERNAL_FORMAT = GL_RGBA32F;
const GLenum TEX_FORMAT = GL_RGBA; const GLenum TEX_FORMAT = GL_RGBA;
const GLenum TEX_TYPE = GL_FLOAT; const GLenum TEX_TYPE = GL_FLOAT;
#define square(x) ((x)*(x)) #define square(x) ((x) * (x))
/* /*
void reset_texture(GLuint texture, float width, float height, char* initData) void reset_texture(GLuint texture, float width, float height, char* initData)
@ -401,12 +402,11 @@ typedef struct mouse_input
} mouse_input; } mouse_input;
mouse_input mouseInput = {0}; mouse_input mouseInput = { 0 };
int frameWidth = 800; int frameWidth = 800;
int frameHeight = 600; int frameHeight = 600;
ORCA_EXPORT void oc_on_mouse_down(int button) ORCA_EXPORT void oc_on_mouse_down(int button)
{ {
mouseInput.down = true; mouseInput.down = true;
@ -427,15 +427,15 @@ ORCA_EXPORT void oc_on_mouse_move(float x, float y, float dx, float dy)
void init_color_checker() void init_color_checker()
{ {
for(int i=0; i<texHeight; i++) for(int i = 0; i < texHeight; i++)
{ {
for(int j=0; j<texWidth; j++) for(int j = 0; j < texWidth; j++)
{ {
float u = j/(float)texWidth; float u = j / (float)texWidth;
float v = i/(float)texWidth; float v = i / (float)texWidth;
float value = ((int)(u*10)%2) == ((int)(v*10)%2) ? 1. : 0.; float value = ((int)(u * 10) % 2) == ((int)(v * 10) % 2) ? 1. : 0.;
for(int k = 0; k<3; k++) for(int k = 0; k < 3; k++)
{ {
colorInitData[i][j][k] = value; colorInitData[i][j][k] = value;
} }
@ -446,15 +446,14 @@ void init_color_checker()
void init_velocity_vortex() void init_velocity_vortex()
{ {
for(int i=0; i<texHeight; i++) for(int i = 0; i < texHeight; i++)
{ {
for(int j=0; j<texWidth; j++) for(int j = 0; j < texWidth; j++)
{ {
float x = 2*j/(float)texWidth - 1; float x = 2 * j / (float)texWidth - 1;
float y = 2*i/(float)texWidth - 1; float y = 2 * i / (float)texWidth - 1;
velocityInitData[i][j][0] = sinf(2*M_PI*y); velocityInitData[i][j][0] = sinf(2 * M_PI * y);
velocityInitData[i][j][1] = sinf(2*M_PI*x); velocityInitData[i][j][1] = sinf(2 * M_PI * x);
} }
} }
} }
@ -506,14 +505,13 @@ void apply_splat(float splatPosX, float splatPosY, float radius, float splatVelX
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
frame_buffer_swap(&colorBuffer); frame_buffer_swap(&colorBuffer);
} }
void jacobi_solve(frame_buffer* x, frame_buffer* b, float invGridSize, int iterationCount) void jacobi_solve(frame_buffer* x, frame_buffer* b, float invGridSize, int iterationCount)
{ {
glUseProgram(jacobiProgram.prog); glUseProgram(jacobiProgram.prog);
for(int i=0; i<iterationCount; i++) for(int i = 0; i < iterationCount; i++)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, x->fbos[1]); glBindFramebuffer(GL_FRAMEBUFFER, x->fbos[1]);
@ -585,20 +583,20 @@ void input_splat(float t)
// account for margin // account for margin
float margin = 32; float margin = 32;
float offset = margin/texWidth; float offset = margin / texWidth;
float ratio = 1 - 2*margin/texWidth; float ratio = 1 - 2 * margin / texWidth;
float splatPosX = (mouseInput.x/frameWidth)*ratio + offset; float splatPosX = (mouseInput.x / frameWidth) * ratio + offset;
float splatPosY = (1 - mouseInput.y/frameHeight)*ratio + offset; float splatPosY = (1 - mouseInput.y / frameHeight) * ratio + offset;
float splatVelX = (10000.*DELTA*mouseInput.deltaX/frameWidth)*ratio; float splatVelX = (10000. * DELTA * mouseInput.deltaX / frameWidth) * ratio;
float splatVelY = (-10000.*DELTA*mouseInput.deltaY/frameWidth)*ratio; float splatVelY = (-10000. * DELTA * mouseInput.deltaY / frameWidth) * ratio;
float intensity = 100*sqrtf(square(ratio*mouseInput.deltaX/frameWidth) + square(ratio*mouseInput.deltaY/frameHeight)); float intensity = 100 * sqrtf(square(ratio * mouseInput.deltaX / frameWidth) + square(ratio * mouseInput.deltaY / frameHeight));
float r = intensity * (sinf(2*M_PI*0.1*t) + 1); float r = intensity * (sinf(2 * M_PI * 0.1 * t) + 1);
float g = 0.5*intensity * (cosf(2*M_PI*0.1/M_E*t + 654) + 1); float g = 0.5 * intensity * (cosf(2 * M_PI * 0.1 / M_E * t + 654) + 1);
float b = intensity * (sinf(2*M_PI*0.1/M_SQRT2*t + 937) + 1); float b = intensity * (sinf(2 * M_PI * 0.1 / M_SQRT2 * t + 937) + 1);
float radius = 0.005; float radius = 0.005;
@ -609,7 +607,7 @@ void input_splat(float t)
} }
} }
float testDiv[texWidth/2][texWidth/2][4]; float testDiv[texWidth / 2][texWidth / 2][4];
oc_surface surface; oc_surface surface;
@ -620,8 +618,8 @@ ORCA_EXPORT void oc_on_init()
surface = oc_surface_gles(); surface = oc_surface_gles();
oc_surface_select(surface); oc_surface_select(surface);
// init_color_checker(); // init_color_checker();
// init_velocity_vortex(); // init_velocity_vortex();
// init programs // init programs
init_advect(&advectProgram); init_advect(&advectProgram);
@ -643,57 +641,55 @@ ORCA_EXPORT void oc_on_init()
init_frame_buffer(&velocityBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)velocityInitData); init_frame_buffer(&velocityBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)velocityInitData);
int gridFactor = 1; int gridFactor = 1;
for(int i=0; i<MULTIGRID_COUNT; i++) for(int i = 0; i < MULTIGRID_COUNT; i++)
{ {
oc_log_info("create div buffer %i", i); oc_log_info("create div buffer %i", i);
init_frame_buffer(&divBuffer[i], texWidth/gridFactor, texHeight/gridFactor, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, 0); init_frame_buffer(&divBuffer[i], texWidth / gridFactor, texHeight / gridFactor, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, 0);
oc_log_info("create pressure buffer %i", i); oc_log_info("create pressure buffer %i", i);
init_frame_buffer(&pressureBuffer[i], texWidth/gridFactor, texHeight/gridFactor, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, 0); init_frame_buffer(&pressureBuffer[i], texWidth / gridFactor, texHeight / gridFactor, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, 0);
gridFactor *= 2; gridFactor *= 2;
} }
// init vertex buffer // init vertex buffer
static Vertex vertices[6] = static Vertex vertices[6] = {
{ { -1, -1 },
{-1, -1}, { 1, -1 },
{ 1, -1}, { 1, 1 },
{ 1, 1}, { -1, -1 },
{-1, -1}, { 1, 1 },
{ 1, 1}, { -1, 1 }
{ -1, 1}
}; };
//WARN: we assume blitProgram.pos == advectProgram.pos, is there a situation where it wouldn't be true?? //WARN: we assume blitProgram.pos == advectProgram.pos, is there a situation where it wouldn't be true??
GLuint vertexBuffer = 0; GLuint vertexBuffer = 0;
glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(Vertex), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vertex), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(blitProgram.pos, 2, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(blitProgram.pos, 2, GL_FLOAT, GL_FALSE, 0, 0);
for(int i = 0; i < texWidth / 2; i++)
for(int i=0; i<texWidth/2; i++)
{ {
for(int j=0; j<texHeight/2; j++) for(int j = 0; j < texHeight / 2; j++)
{ {
testDiv[i][j][0] = 0.5 + 0.5*cosf(j/100.*3.14159 + i/100.*1.2139); testDiv[i][j][0] = 0.5 + 0.5 * cosf(j / 100. * 3.14159 + i / 100. * 1.2139);
} }
} }
} }
ORCA_EXPORT void oc_on_resize(u32 width, u32 height) ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
{ {
frameWidth = width*2; frameWidth = width * 2;
frameHeight = height*2; frameHeight = height * 2;
} }
ORCA_EXPORT void oc_on_frame_refresh() ORCA_EXPORT void oc_on_frame_refresh()
{ {
float aspectRatio = texWidth/texHeight; //TODO replace with actual aspect ratio? float aspectRatio = texWidth / texHeight; //TODO replace with actual aspect ratio?
static float t = 0; static float t = 0;
t += 1./60.; t += 1. / 60.;
oc_surface_select(surface); oc_surface_select(surface);
@ -772,7 +768,6 @@ ORCA_EXPORT void oc_on_frame_refresh()
input_splat(t); input_splat(t);
//NOTE: compute divergence of advected velocity //NOTE: compute divergence of advected velocity
glUseProgram(divProgram.prog); glUseProgram(divProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, divBuffer[0].fbos[1]); glBindFramebuffer(GL_FRAMEBUFFER, divBuffer[0].fbos[1]);
@ -789,34 +784,31 @@ ORCA_EXPORT void oc_on_frame_refresh()
glBindFramebuffer(GL_FRAMEBUFFER, pressureBuffer[0].fbos[1]); glBindFramebuffer(GL_FRAMEBUFFER, pressureBuffer[0].fbos[1]);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
#if 0 #if 0
multigrid_clear(&pressureBuffer[0]); multigrid_clear(&pressureBuffer[0]);
jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, texWidth*texHeight); jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, texWidth*texHeight);
#else #else
multigrid_clear(&pressureBuffer[0]); multigrid_clear(&pressureBuffer[0]);
for(int i=0; i<1; i++) for(int i = 0; i < 1; i++)
{ {
jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 2); jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 2);
multigrid_coarsen_residual(&divBuffer[1], &pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE); multigrid_coarsen_residual(&divBuffer[1], &pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE);
multigrid_clear(&pressureBuffer[1]); multigrid_clear(&pressureBuffer[1]);
jacobi_solve(&pressureBuffer[1], &divBuffer[1], 2*INV_GRID_SIZE, 2); jacobi_solve(&pressureBuffer[1], &divBuffer[1], 2 * INV_GRID_SIZE, 2);
multigrid_coarsen_residual(&divBuffer[2], &pressureBuffer[1], &divBuffer[1], 2*INV_GRID_SIZE); multigrid_coarsen_residual(&divBuffer[2], &pressureBuffer[1], &divBuffer[1], 2 * INV_GRID_SIZE);
multigrid_clear(&pressureBuffer[2]); multigrid_clear(&pressureBuffer[2]);
jacobi_solve(&pressureBuffer[2], &divBuffer[2], 4*INV_GRID_SIZE, 30); jacobi_solve(&pressureBuffer[2], &divBuffer[2], 4 * INV_GRID_SIZE, 30);
multigrid_prolongate_and_correct(&pressureBuffer[1], &pressureBuffer[2], 2*INV_GRID_SIZE); multigrid_prolongate_and_correct(&pressureBuffer[1], &pressureBuffer[2], 2 * INV_GRID_SIZE);
jacobi_solve(&pressureBuffer[1], &divBuffer[1], 2*INV_GRID_SIZE, 8); jacobi_solve(&pressureBuffer[1], &divBuffer[1], 2 * INV_GRID_SIZE, 8);
multigrid_prolongate_and_correct(&pressureBuffer[0], &pressureBuffer[1], INV_GRID_SIZE); multigrid_prolongate_and_correct(&pressureBuffer[0], &pressureBuffer[1], INV_GRID_SIZE);
jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 4); jacobi_solve(&pressureBuffer[0], &divBuffer[0], INV_GRID_SIZE, 4);
} }
#endif #endif
//NOTE: subtract pressure gradient to advected velocity //NOTE: subtract pressure gradient to advected velocity
glUseProgram(subtractProgram.prog); glUseProgram(subtractProgram.prog);
@ -862,12 +854,13 @@ ORCA_EXPORT void oc_on_frame_refresh()
glViewport(0, 0, frameWidth, frameHeight); glViewport(0, 0, frameWidth, frameHeight);
float displayMatrix[16] = { float displayMatrix[16] = {
1/aspectRatio, 0, 0, 0, 1 / aspectRatio, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1 }; 0, 0, 0, 1
};
/* /*
glUseProgram(blitResidueProgram.prog); glUseProgram(blitResidueProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -883,7 +876,7 @@ ORCA_EXPORT void oc_on_frame_refresh()
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
//*/ //*/
//* //*
glUseProgram(blitProgram.prog); glUseProgram(blitProgram.prog);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -896,7 +889,7 @@ ORCA_EXPORT void oc_on_frame_refresh()
glUniformMatrix4fv(blitProgram.mvp, 1, GL_FALSE, displayMatrix); glUniformMatrix4fv(blitProgram.mvp, 1, GL_FALSE, displayMatrix);
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
/*/ /*/
//NOTE: recompute divergence of (corrected) velocity //NOTE: recompute divergence of (corrected) velocity
glUseProgram(divProgram.prog); glUseProgram(divProgram.prog);

View File

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

View File

@ -10,19 +10,28 @@ uniform sampler2D tex;
vec3 color_map(float v) vec3 color_map(float v)
{ {
float logv = log(abs(v))/log(10.0); float logv = log(abs(v)) / log(10.0);
float f = floor(logv + 7.0); float f = floor(logv + 7.0);
float i = floor(4.0*(logv + 7.0 - f)); float i = floor(4.0 * (logv + 7.0 - f));
if(f < 0.0) return vec3(0.0); if(f < 0.0)
if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0); return vec3(0.0);
if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0); if(f < 1.0)
if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0); return mix(vec3(1.0, 0.0, 0.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 < 2.0)
if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0); return mix(vec3(0.0, 1.0, 0.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 < 3.0)
if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0); return mix(vec3(0.0, 0.0, 1.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); 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); return vec3(1.0);
} }

View File

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

View File

@ -11,43 +11,52 @@ uniform sampler2D bTex;
float x(ivec2 coord) float x(ivec2 coord)
{ {
if( coord.x <= 0 if(coord.x <= 0
|| coord.x >= textureSize(xTex, 0).x || coord.x >= textureSize(xTex, 0).x
|| coord.y <= 0 || coord.y <= 0
|| coord.y >= textureSize(xTex, 0).y) || coord.y >= textureSize(xTex, 0).y)
{ {
return(0.); return (0.);
} }
return(texelFetch(xTex, coord, 0).x); return (texelFetch(xTex, coord, 0).x);
} }
float b(ivec2 coord) float b(ivec2 coord)
{ {
if( coord.x <= 0 if(coord.x <= 0
|| coord.x >= textureSize(bTex, 0).x || coord.x >= textureSize(bTex, 0).x
|| coord.y <= 0 || coord.y <= 0
|| coord.y >= textureSize(bTex, 0).y) || coord.y >= textureSize(bTex, 0).y)
{ {
return(0.); return (0.);
} }
return(texelFetch(bTex, coord, 0).x); return (texelFetch(bTex, coord, 0).x);
} }
vec3 color_map(float v) vec3 color_map(float v)
{ {
float logv = log(abs(v))/log(10.0); float logv = log(abs(v)) / log(10.0);
float f = floor(logv + 7.0); float f = floor(logv + 7.0);
float i = floor(4.0*(logv + 7.0 - f)); float i = floor(4.0 * (logv + 7.0 - f));
if(f < 0.0) return vec3(0.0); if(f < 0.0)
if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0); return vec3(0.0);
if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0); if(f < 1.0)
if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0); return mix(vec3(1.0, 0.0, 0.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 < 2.0)
if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0); return mix(vec3(0.0, 1.0, 0.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 < 3.0)
if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0); return mix(vec3(0.0, 0.0, 1.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); 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); return vec3(1.0);
} }
@ -60,6 +69,6 @@ void main()
float bl = x(pixelCoord + ivec2(-1, -1)); float bl = x(pixelCoord + ivec2(-1, -1));
float br = x(pixelCoord + ivec2(1, -1)); float br = x(pixelCoord + ivec2(1, -1));
float residue = b(pixelCoord) - (-tl - tr - bl - br + 4.*x(pixelCoord)); float residue = b(pixelCoord) - (-tl - tr - bl - br + 4. * x(pixelCoord));
fragColor = vec4(color_map(residue), 1); fragColor = vec4(color_map(residue), 1);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
#include <orca.h> #include <orca.h>
oc_vec2 frameSize = {100, 100}; oc_vec2 frameSize = { 100, 100 };
oc_surface surface; oc_surface surface;
@ -45,7 +45,7 @@ ORCA_EXPORT void oc_on_init(void)
int extensionCount = 0; int extensionCount = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); 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); const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
oc_log_info("GLES extension %i: %s\n", i, extension); oc_log_info("GLES extension %i: %s\n", i, extension);
@ -63,14 +63,14 @@ ORCA_EXPORT void oc_on_init(void)
glLinkProgram(program); glLinkProgram(program);
glUseProgram(program); glUseProgram(program);
GLfloat vertices[] = { 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
};
GLuint buffer; GLuint buffer;
glGenBuffers(1, &buffer); glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -85,7 +85,7 @@ ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
ORCA_EXPORT void oc_on_frame_refresh(void) ORCA_EXPORT void oc_on_frame_refresh(void)
{ {
f32 aspect = frameSize.x/frameSize.y; f32 aspect = frameSize.x / frameSize.y;
oc_surface_select(surface); oc_surface_select(surface);
@ -96,11 +96,11 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
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, GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0, -sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1}; 0, 0, 0, 1 };
alpha += 2*M_PI/120; alpha += 2 * M_PI / 120;
glUniformMatrix4fv(0, 1, false, matrix); glUniformMatrix4fv(0, 1, false, matrix);

View File

@ -1,12 +1,12 @@
#include"orca.h" #include "orca.h"
oc_vec2 frameSize = {100, 100}; oc_vec2 frameSize = { 100, 100 };
oc_surface surface; oc_surface surface;
oc_canvas canvas; oc_canvas canvas;
oc_font font; oc_font font;
oc_ui_context ui; oc_ui_context ui;
oc_arena textArena = {0}; oc_arena textArena = { 0 };
ORCA_EXPORT void oc_on_init(void) ORCA_EXPORT void oc_on_init(void)
{ {
@ -25,11 +25,11 @@ ORCA_EXPORT void oc_on_init(void)
char* buffer = oc_arena_push(oc_scratch(), size); char* buffer = oc_arena_push(oc_scratch(), size);
oc_file_read(file, size, buffer); oc_file_read(file, size, buffer);
oc_file_close(file); oc_file_close(file);
oc_unicode_range ranges[5] = {OC_UNICODE_BASIC_LATIN, oc_unicode_range ranges[5] = { OC_UNICODE_BASIC_LATIN,
OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
OC_UNICODE_LATIN_EXTENDED_A, OC_UNICODE_LATIN_EXTENDED_A,
OC_UNICODE_LATIN_EXTENDED_B, OC_UNICODE_LATIN_EXTENDED_B,
OC_UNICODE_SPECIALS}; OC_UNICODE_SPECIALS };
// TODO: Decide whether we're using strings or explicit pointer + length // 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); font = oc_font_create_from_memory(oc_str8_from_buffer(size, buffer), 5, ranges);
} }
@ -45,24 +45,23 @@ ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
frameSize.y = height; 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) void widget_begin_view(char* str)
{ {
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_Y, oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_Y,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.layout.align.x = OC_UI_ALIGN_CENTER, .layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START}, .layout.align.y = OC_UI_ALIGN_START },
OC_UI_STYLE_LAYOUT); OC_UI_STYLE_LAYOUT);
oc_ui_box_begin(str, OC_UI_FLAG_DRAW_BORDER); oc_ui_box_begin(str, OC_UI_FLAG_DRAW_BORDER);
oc_ui_label(str); oc_ui_label(str);
} }
void widget_end_view(void) void widget_end_view(void)
@ -74,12 +73,12 @@ void widget_end_view(void)
ORCA_EXPORT void oc_on_frame_refresh(void) ORCA_EXPORT void oc_on_frame_refresh(void)
{ {
oc_ui_style defaultStyle = {.bgColor = {0}, oc_ui_style defaultStyle = { .bgColor = { 0 },
.color = {1, 1, 1, 1}, .color = { 1, 1, 1, 1 },
.font = font, .font = font,
.fontSize = 16, .fontSize = 16,
.borderColor = {0.278, 0.333, 0.412, 1}, .borderColor = { 0.278, 0.333, 0.412, 1 },
.borderSize = 2}; .borderSize = 2 };
oc_ui_style_mask defaultMask = OC_UI_STYLE_BG_COLOR oc_ui_style_mask defaultMask = OC_UI_STYLE_BG_COLOR
| OC_UI_STYLE_COLOR | OC_UI_STYLE_COLOR
@ -92,41 +91,41 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
{ {
oc_ui_style_match_before(oc_ui_pattern_all(), &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}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 1}, .size.height = { OC_UI_SIZE_PARENT, 1 },
.layout.axis = OC_UI_AXIS_Y, .layout.axis = OC_UI_AXIS_Y,
.layout.align.x = OC_UI_ALIGN_CENTER, .layout.align.x = OC_UI_ALIGN_CENTER,
.layout.align.y = OC_UI_ALIGN_START, .layout.align.y = OC_UI_ALIGN_START,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.bgColor = {0.11, 0.11, 0.11, 1}}, .bgColor = { 0.11, 0.11, 0.11, 1 } },
OC_UI_STYLE_SIZE OC_UI_STYLE_SIZE
| OC_UI_STYLE_LAYOUT | OC_UI_STYLE_LAYOUT
| OC_UI_STYLE_BG_COLOR); | OC_UI_STYLE_BG_COLOR);
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND) oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_CHILDREN}, .size.height = { OC_UI_SIZE_CHILDREN },
.layout.align.x = OC_UI_ALIGN_CENTER}, .layout.align.x = OC_UI_ALIGN_CENTER },
OC_UI_STYLE_SIZE OC_UI_STYLE_SIZE
|OC_UI_STYLE_LAYOUT_ALIGN_X); | OC_UI_STYLE_LAYOUT_ALIGN_X);
oc_ui_container("title", 0) oc_ui_container("title", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.fontSize = 26}, OC_UI_STYLE_FONT_SIZE); oc_ui_style_next(&(oc_ui_style){ .fontSize = 26 }, OC_UI_STYLE_FONT_SIZE);
oc_ui_label("Orca UI Demo"); oc_ui_label("Orca UI Demo");
if(oc_ui_box_sig(oc_ui_box_top()).hovering) if(oc_ui_box_sig(oc_ui_box_top()).hovering)
{ {
oc_ui_tooltip("tooltip") oc_ui_tooltip("tooltip")
{ {
oc_ui_style_next(&(oc_ui_style){.bgColor = {1, 0.99, 0.82, 1}}, oc_ui_style_next(&(oc_ui_style){ .bgColor = { 1, 0.99, 0.82, 1 } },
OC_UI_STYLE_BG_COLOR); OC_UI_STYLE_BG_COLOR);
oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND) oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND)
{ {
oc_ui_style_next(&(oc_ui_style){.color = {0, 0, 0, 1}}, oc_ui_style_next(&(oc_ui_style){ .color = { 0, 0, 0, 1 } },
OC_UI_STYLE_COLOR); OC_UI_STYLE_COLOR);
oc_ui_label("That is a tooltip!"); oc_ui_label("That is a tooltip!");
@ -165,35 +164,35 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 1, 1}}, .size.height = { OC_UI_SIZE_PARENT, 1, 1 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X}, OC_UI_STYLE_LAYOUT_AXIS); 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_container("contents", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = {OC_UI_SIZE_PARENT, 1}}, .size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
oc_ui_container("left", 0) oc_ui_container("left", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X, oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.size.width = {OC_UI_SIZE_PARENT, 1}, .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.5}}, .size.height = { OC_UI_SIZE_PARENT, 0.5 } },
OC_UI_STYLE_LAYOUT_AXIS OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_LAYOUT_SPACING | OC_UI_STYLE_LAYOUT_SPACING
|OC_UI_STYLE_LAYOUT_MARGIN_X | OC_UI_STYLE_LAYOUT_MARGIN_X
|OC_UI_STYLE_LAYOUT_MARGIN_Y | OC_UI_STYLE_LAYOUT_MARGIN_Y
|OC_UI_STYLE_SIZE); | OC_UI_STYLE_SIZE);
oc_ui_container("up", 0) oc_ui_container("up", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = {OC_UI_SIZE_PARENT, 1}}, .size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
widget_view("Buttons") widget_view("Buttons")
{ {
@ -213,16 +212,15 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = {OC_UI_SIZE_PARENT, 1}}, .size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
oc_ui_pattern pattern = { 0 };
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_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_match_after(pattern,
&(oc_ui_style){.bgColor = {0, 1, 0, 1}, &(oc_ui_style){ .bgColor = { 0, 1, 0, 1 },
.color = {1, 1, 1, 1}}, .color = { 1, 1, 1, 1 } },
OC_UI_STYLE_COLOR | OC_UI_STYLE_BG_COLOR); OC_UI_STYLE_COLOR | OC_UI_STYLE_BG_COLOR);
widget_view("checkboxes") widget_view("checkboxes")
@ -237,36 +235,36 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X, oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.size.width = {OC_UI_SIZE_PARENT, 1}, .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.5}}, .size.height = { OC_UI_SIZE_PARENT, 0.5 } },
OC_UI_STYLE_LAYOUT_AXIS OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_SIZE); | OC_UI_STYLE_SIZE);
oc_ui_container("down", 0) oc_ui_container("down", 0)
{ {
widget_view("Vertical Sliders") widget_view("Vertical Sliders")
{ {
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X, oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 10}, .layout.spacing = 10 },
OC_UI_STYLE_LAYOUT_AXIS OC_UI_STYLE_LAYOUT_AXIS
|OC_UI_STYLE_LAYOUT_SPACING); | OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("contents", 0) oc_ui_container("contents", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = {OC_UI_SIZE_PIXELS, 200}}, .size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider1 = 0; static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1); oc_ui_slider("slider1", 0.2, &slider1);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = {OC_UI_SIZE_PIXELS, 200}}, .size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider2 = 0; static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2); oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 20}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 20 },
.size.height = {OC_UI_SIZE_PIXELS, 200}}, .size.height = { OC_UI_SIZE_PIXELS, 200 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider3 = 0; static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3); oc_ui_slider("slider3", 0.2, &slider3);
@ -275,20 +273,20 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
widget_view("Horizontal Sliders") widget_view("Horizontal Sliders")
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = {OC_UI_SIZE_PIXELS, 20}}, .size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider1 = 0; static f32 slider1 = 0;
oc_ui_slider("slider1", 0.2, &slider1); oc_ui_slider("slider1", 0.2, &slider1);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = {OC_UI_SIZE_PIXELS, 20}}, .size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider2 = 0; static f32 slider2 = 0;
oc_ui_slider("slider2", 0.2, &slider2); oc_ui_slider("slider2", 0.2, &slider2);
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 200}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 200 },
.size.height = {OC_UI_SIZE_PIXELS, 20}}, .size.height = { OC_UI_SIZE_PIXELS, 20 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static f32 slider3 = 0; static f32 slider3 = 0;
oc_ui_slider("slider3", 0.2, &slider3); oc_ui_slider("slider3", 0.2, &slider3);
@ -296,22 +294,22 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 0.5}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 0.5 },
.size.height = {OC_UI_SIZE_PARENT, 1}}, .size.height = { OC_UI_SIZE_PARENT, 1 } },
OC_UI_STYLE_SIZE); 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}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.33}}, .size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
widget_view("Text box") widget_view("Text box")
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 300}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 300 },
.size.height = {OC_UI_SIZE_TEXT}}, .size.height = { OC_UI_SIZE_TEXT } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
static oc_str8 text = {0}; static oc_str8 text = { 0 };
oc_ui_text_box_result res = oc_ui_text_box("textbox", oc_scratch(), text); oc_ui_text_box_result res = oc_ui_text_box("textbox", oc_scratch(), text);
if(res.changed) if(res.changed)
{ {
@ -320,47 +318,47 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.33}}, .size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
widget_view("Test") widget_view("Test")
{ {
oc_ui_pattern pattern = {0}; 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_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_match_after(pattern, &(oc_ui_style){ .bgColor = { 0.3, 0.3, 1, 1 } }, OC_UI_STYLE_BG_COLOR);
static int selected = 0; static int selected = 0;
oc_str8 options[] = {OC_STR8("option 1"), oc_str8 options[] = { OC_STR8("option 1"),
OC_STR8("option 2"), OC_STR8("option 2"),
OC_STR8("long option 3"), OC_STR8("long option 3"),
OC_STR8("option 4"), OC_STR8("option 4"),
OC_STR8("option 5")}; OC_STR8("option 5") };
oc_ui_select_popup_info info = {.selectedIndex = selected, oc_ui_select_popup_info info = { .selectedIndex = selected,
.optionCount = 5, .optionCount = 5,
.options = options}; .options = options };
oc_ui_select_popup_info result = oc_ui_select_popup("popup", &info); oc_ui_select_popup_info result = oc_ui_select_popup("popup", &info);
selected = result.selectedIndex; selected = result.selectedIndex;
} }
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.33}}, .size.height = { OC_UI_SIZE_PARENT, 0.33 } },
OC_UI_STYLE_SIZE); OC_UI_STYLE_SIZE);
widget_view("Color") widget_view("Color")
{ {
oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 },
.size.height = {OC_UI_SIZE_PARENT, 0.7}, .size.height = { OC_UI_SIZE_PARENT, 0.7 },
.layout.axis = OC_UI_AXIS_X}, .layout.axis = OC_UI_AXIS_X },
OC_UI_STYLE_SIZE OC_UI_STYLE_SIZE
|OC_UI_STYLE_LAYOUT_AXIS); | OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_panel("Panel", OC_UI_FLAG_DRAW_BORDER) 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_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X },
OC_UI_STYLE_LAYOUT_AXIS); OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("contents", 0) oc_ui_container("contents", 0)
{ {
oc_ui_style_next(&(oc_ui_style){.layout.spacing = 20}, oc_ui_style_next(&(oc_ui_style){ .layout.spacing = 20 },
OC_UI_STYLE_LAYOUT_SPACING); OC_UI_STYLE_LAYOUT_SPACING);
oc_ui_container("buttons", 0) oc_ui_container("buttons", 0)
{ {
@ -370,10 +368,10 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
oc_ui_button("Button D"); oc_ui_button("Button D");
} }
oc_ui_style_next(&(oc_ui_style){.layout.axis = OC_UI_AXIS_X, oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_X,
.layout.spacing = 20}, .layout.spacing = 20 },
OC_UI_STYLE_LAYOUT_SPACING OC_UI_STYLE_LAYOUT_SPACING
|OC_UI_STYLE_LAYOUT_AXIS); | OC_UI_STYLE_LAYOUT_AXIS);
oc_ui_container("buttons2", 0) oc_ui_container("buttons2", 0)
{ {
@ -385,13 +383,11 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
} }
} }
} }
} }
} }
} }
} }
oc_canvas_set_current(canvas); oc_canvas_set_current(canvas);
oc_surface_select(surface); oc_surface_select(surface);
oc_ui_draw(); oc_ui_draw();

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,21 +6,21 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdlib.h> #include <errno.h>
#include<string.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
int main() int main()
{ {
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -30,7 +30,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
log_error("couldn't create surface\n"); log_error("couldn't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
@ -39,11 +39,11 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
log_error("Error: couldn't create canvas\n"); log_error("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
//NOTE: create atlas //NOTE: create atlas
mem_arena permanentArena = {0}; mem_arena permanentArena = { 0 };
mem_arena_init(&permanentArena); mem_arena_init(&permanentArena);
mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000); mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000);
@ -70,7 +70,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -84,8 +85,8 @@ int main()
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(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(image2.image, image2.rect, (mp_rect){ 300, 200, 300, 300 });
mg_render(surface, canvas); mg_render(surface, canvas);
mg_surface_present(surface); mg_surface_present(surface);
@ -102,5 +103,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,19 +6,18 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdlib.h> #include <errno.h>
#include<stdio.h> #include <stdio.h>
#include<string.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
#define LOG_SUBSYSTEM "Main" #define LOG_SUBSYSTEM "Main"
mg_font create_font() mg_font create_font()
{ {
//NOTE(martin): create font //NOTE(martin): create font
@ -29,7 +28,7 @@ mg_font create_font()
if(!fontFile) if(!fontFile)
{ {
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil()); return (mg_font_nil());
} }
unsigned char* fontData = 0; unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END); fseek(fontFile, 0, SEEK_END);
@ -39,16 +38,16 @@ mg_font create_font()
fread(fontData, 1, fontDataSize, fontFile); fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile); fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A, UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B, UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS}; UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData); free(fontData);
return(font); return (font);
} }
int main() int main()
@ -56,7 +55,7 @@ int main()
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -66,7 +65,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
printf("Error: couldn't create surface\n"); printf("Error: couldn't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
@ -75,7 +74,7 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas\n"); printf("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
mg_font font = create_font(); mg_font font = create_font();
@ -102,7 +101,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
@ -112,44 +112,45 @@ int main()
if(event->key.code == MP_KEY_LEFT) if(event->key.code == MP_KEY_LEFT)
{ {
x-=0.3*factor; x -= 0.3 * factor;
} }
else if(event->key.code == MP_KEY_RIGHT) else if(event->key.code == MP_KEY_RIGHT)
{ {
x+=0.3*factor; x += 0.3 * factor;
} }
else if(event->key.code == MP_KEY_UP) else if(event->key.code == MP_KEY_UP)
{ {
y-=0.3*factor; y -= 0.3 * factor;
} }
else if(event->key.code == MP_KEY_DOWN) else if(event->key.code == MP_KEY_DOWN)
{ {
y+=0.3*factor; y += 0.3 * factor;
} }
} }
} break; }
break;
default: default:
break; break;
} }
} }
if(x-200 < 0) if(x - 200 < 0)
{ {
x = 200; x = 200;
dx = speed; dx = speed;
} }
if(x+200 > contentRect.w) if(x + 200 > contentRect.w)
{ {
x = contentRect.w - 200; x = contentRect.w - 200;
dx = -speed; dx = -speed;
} }
if(y-200 < 0) if(y - 200 < 0)
{ {
y = 200; y = 200;
dy = speed; dy = speed;
} }
if(y+200 > contentRect.h) if(y + 200 > contentRect.h)
{ {
y = contentRect.h - 200; y = contentRect.h - 200;
dy = -speed; dy = -speed;
@ -174,30 +175,30 @@ int main()
mg_set_color_rgba(0, 0, 0, 1); mg_set_color_rgba(0, 0, 0, 1);
mg_set_width(20); mg_set_width(20);
mg_move_to(x-100, y+100); 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_cubic_to(x - 50, y + 150 + frown, x + 50, y + 150 + frown, x + 100, y + 100);
mg_stroke(); mg_stroke();
// eyes // eyes
mg_ellipse_fill(x-70, y-50, 30, 50); mg_ellipse_fill(x - 70, y - 50, 30, 50);
mg_ellipse_fill(x+70, y-50, 30, 50); mg_ellipse_fill(x + 70, y - 50, 30, 50);
// text // text
mg_set_color_rgba(0, 0, 1, 1); mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font); mg_set_font(font);
mg_set_font_size(12); mg_set_font_size(12);
mg_move_to(50, 600-50); mg_move_to(50, 600 - 50);
str8 text = str8_pushf(mem_scratch(), str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...", "Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_text_outlines(text); mg_text_outlines(text);
mg_fill(); mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_surface_prepare(surface); mg_surface_prepare(surface);
mg_render(surface, canvas); mg_render(surface, canvas);
@ -214,5 +215,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,22 +6,22 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include <errno.h>
#include<stdlib.h> #include <stdio.h>
#include<string.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
int main() int main()
{ {
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -31,7 +31,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
log_error("couldn't create surface\n"); log_error("couldn't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
@ -40,7 +40,7 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas\n"); printf("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
//NOTE: create image //NOTE: create image
@ -67,7 +67,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -80,7 +81,7 @@ int main()
mg_clear(); 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, mg_matrix_push((mg_mat2x3){0.707, -0.707, 200,
0.707, 0.707, 100}); 0.707, 0.707, 100});
mg_set_image(image); mg_set_image(image);
@ -99,10 +100,8 @@ int main()
mg_image_draw(image2, (mp_rect){300, 200, 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(image, (mp_rect){ 100, 100, 300, 300 });
mg_image_draw(image2, (mp_rect){300, 200, 300, 300}); mg_image_draw(image2, (mp_rect){ 300, 200, 300, 300 });
mg_render(surface, canvas); mg_render(surface, canvas);
mg_surface_present(surface); mg_surface_present(surface);
@ -117,5 +116,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,16 +1,16 @@
#include<stdlib.h> #include <stdio.h>
#include<stdio.h> #include <stdlib.h>
#define MG_INCLUDE_GL_API 1 #define MG_INCLUDE_GL_API 1
#include"milepost.h" #include "milepost.h"
int main() int main()
{ {
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -20,32 +20,32 @@ int main()
if(mg_surface_is_nil(surface1)) if(mg_surface_is_nil(surface1))
{ {
printf("Error: couldn't create surface 1\n"); printf("Error: couldn't create surface 1\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface1, 0); mg_surface_swap_interval(surface1, 0);
//* //*
mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS); mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS);
if(mg_surface_is_nil(surface2)) if(mg_surface_is_nil(surface2))
{ {
printf("Error: couldn't create surface 2\n"); printf("Error: couldn't create surface 2\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface2, 0); mg_surface_swap_interval(surface2, 0);
//*/ //*/
mg_canvas canvas1 = mg_canvas_create(); mg_canvas canvas1 = mg_canvas_create();
if(mg_canvas_is_nil(canvas1)) if(mg_canvas_is_nil(canvas1))
{ {
printf("Error: couldn't create canvas 1\n"); printf("Error: couldn't create canvas 1\n");
return(-1); return (-1);
} }
//* //*
mg_canvas canvas2 = mg_canvas_create(); mg_canvas canvas2 = mg_canvas_create();
if(mg_canvas_is_nil(canvas2)) if(mg_canvas_is_nil(canvas2))
{ {
printf("Error: couldn't create canvas 2\n"); printf("Error: couldn't create canvas 2\n");
return(-1); return (-1);
} }
//*/ //*/
// start app // start app
mp_window_center(window); mp_window_center(window);
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
@ -64,7 +64,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -82,7 +83,7 @@ int main()
mg_render(surface1, canvas1); mg_render(surface1, canvas1);
//* //*
mg_surface_prepare(surface2); mg_surface_prepare(surface2);
mg_canvas_set_current(canvas2); mg_canvas_set_current(canvas2);
@ -93,7 +94,7 @@ int main()
mg_rectangle_fill(300, 300, 300, 200); mg_rectangle_fill(300, 300, 300, 200);
mg_render(surface2, canvas2); mg_render(surface2, canvas2);
//*/ //*/
mg_surface_present(surface1); mg_surface_present(surface1);
mg_surface_present(surface2); mg_surface_present(surface2);
@ -110,5 +111,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,64 +1,63 @@
#include<stdio.h> #include <stdio.h>
#include<stdlib.h> #include <stdlib.h>
#define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE #define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE
#define LOG_COMPILE_DEBUG #define LOG_COMPILE_DEBUG
#include"milepost.h" #include "milepost.h"
#define LOG_SUBSYSTEM "Main" #define LOG_SUBSYSTEM "Main"
static const char* TEST_STRING = static const char* TEST_STRING =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam enim, aliquam in placerat luctus, rutrum in quam. " "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 " "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. " "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" "Etiam malesuada vulputate hendrerit. Cras ultricies diam in lectus finibus, eu laoreet diam rutrum.\n"
"\n" "\n"
"Etiam dictum orci arcu, ac fermentum leo dapibus lacinia. Integer vitae elementum ex. Vestibulum tempor nunc eu hendrerit " "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 " "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 " "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 " "quis, placerat nec enim. Nulla facilisi. Morbi vitae nibh ligula. Suspendisse in molestie magna, eget aliquet mauris. Sed "
"aliquam faucibus magna.\n" "aliquam faucibus magna.\n"
"\n" "\n"
"Sed metus odio, imperdiet et consequat non, faucibus nec risus. Suspendisse facilisis sem neque, id scelerisque dui mattis sit " "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, " "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. " "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. " "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, " "Vestibulum et orci ligula. Sed scelerisque nunc non nisi aliquam, vel eleifend felis suscipit. Integer posuere sapien elit, "
"lacinia ultricies nibh sodales nec.\n" "lacinia ultricies nibh sodales nec.\n"
"\n" "\n"
"Etiam aliquam purus sit amet purus ultricies tristique. Nunc maximus nunc quis magna ornare, vel interdum urna fermentum. " "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 " "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 " "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 " "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, " "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 " "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 " "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" "purus imperdiet nisi, non ultricies libero ipsum eu augue. Mauris at luctus enim.\n"
"\n" "\n"
"Aliquam sed tortor a justo pulvinar dictum consectetur eu felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices " "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. " "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. " "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 " "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. " "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" "Etiam aliquam lacinia consectetur. Phasellus nulla ipsum, viverra non nulla in, rhoncus posuere nunc.\n"
"\n" "\n"
"Phasellus efficitur commodo tellus, eget lobortis erat porta quis. Aenean condimentum tortor ut neque dapibus, vitae vulputate quam " "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. " "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 " "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 " "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 " "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" "semper magna mollis luctus. Donec eu dolor ut ante ullamcorper porta. Mauris et est tristique libero pharetra faucibus.\n"
"\n" "\n"
"Duis ut elementum sem. Praesent commodo erat nec sem ultricies sollicitudin. Suspendisse a pellentesque sapien. Nunc ac magna a dui " "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 " "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 " "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 " "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 " "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 " "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."; "sit amet, malesuada enim. Mauris ultricies nibh orci.";
mg_font create_font(const char* path) mg_font create_font(const char* path)
{ {
@ -70,7 +69,7 @@ mg_font create_font(const char* path)
if(!fontFile) if(!fontFile)
{ {
log_error("Could not load font file '%s'\n", fontPathCString); log_error("Could not load font file '%s'\n", fontPathCString);
return(mg_font_nil()); return (mg_font_nil());
} }
unsigned char* fontData = 0; unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END); fseek(fontFile, 0, SEEK_END);
@ -80,26 +79,29 @@ mg_font create_font(const char* path)
fread(fontData, 1, fontDataSize, fontFile); fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile); fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A, UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B, UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS}; UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData); free(fontData);
return(font); return (font);
} }
enum { FONT_COUNT = 3 }; enum
{
FONT_COUNT = 3
};
int main() int main()
{ {
mp_init(); mp_init();
mp_clock_init(); mp_clock_init();
mp_rect rect = {.x = 100, .y = 100, .w = 980, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 980, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
mp_rect contentRect = mp_window_get_content_rect(window); mp_rect contentRect = mp_window_get_content_rect(window);
@ -110,26 +112,26 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
log_error("couldn't create surface\n"); log_error("couldn't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
mg_canvas canvas = mg_canvas_create(); mg_canvas canvas = mg_canvas_create();
int fontIndex = 0; int fontIndex = 0;
mg_font fonts[FONT_COUNT] = {create_font("../../resources/OpenSansLatinSubset.ttf"), mg_font fonts[FONT_COUNT] = { create_font("../../resources/OpenSansLatinSubset.ttf"),
create_font("../../sketches/resources/CMUSerif-Roman.ttf"), create_font("../../sketches/resources/CMUSerif-Roman.ttf"),
create_font("../../sketches/resources/Courier.ttf")}; create_font("../../sketches/resources/Courier.ttf") };
mg_font_extents extents[FONT_COUNT]; mg_font_extents extents[FONT_COUNT];
f32 fontScales[FONT_COUNT]; f32 fontScales[FONT_COUNT];
f32 lineHeights[FONT_COUNT]; f32 lineHeights[FONT_COUNT];
for(int i=0; i<FONT_COUNT; i++) for(int i = 0; i < FONT_COUNT; i++)
{ {
extents[i] = mg_font_get_extents(fonts[i]); extents[i] = mg_font_get_extents(fonts[i]);
fontScales[i] = mg_font_get_scale_for_em_pixels(fonts[i], 14); 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); lineHeights[i] = fontScales[i] * (extents[i].ascent + extents[i].descent + extents[i].leading);
} }
int codePointCount = utf8_codepoint_count_for_string(STR8((char*)TEST_STRING)); int codePointCount = utf8_codepoint_count_for_string(STR8((char*)TEST_STRING));
@ -137,7 +139,7 @@ int main()
utf8_to_codepoints(codePointCount, codePoints, STR8((char*)TEST_STRING)); utf8_to_codepoints(codePointCount, codePoints, STR8((char*)TEST_STRING));
u32 glyphCount = 0; u32 glyphCount = 0;
for(int i=0; i<codePointCount; i++) for(int i = 0; i < codePointCount; i++)
{ {
if(codePoints[i] != ' ' && codePoints[i] != '\n') if(codePoints[i] != ' ' && codePoints[i] != '\n')
{ {
@ -152,13 +154,13 @@ int main()
f64 frameTime = 0; f64 frameTime = 0;
bool tracked = false; bool tracked = false;
vec2 trackPoint = {0}; vec2 trackPoint = { 0 };
f32 zoom = 1; f32 zoom = 1;
f32 startX = 10; f32 startX = 10;
f32 startY = 10 + lineHeights[fontIndex]; f32 startY = 10 + lineHeights[fontIndex];
mp_input_state inputState = {0}; mp_input_state inputState = { 0 };
while(!mp_should_quit()) while(!mp_should_quit())
{ {
@ -175,7 +177,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_MOUSE_BUTTON: case MP_EVENT_MOUSE_BUTTON:
{ {
@ -185,36 +188,39 @@ int main()
{ {
tracked = true; tracked = true;
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = mousePos.x/zoom - startX; trackPoint.x = mousePos.x / zoom - startX;
trackPoint.y = mousePos.y/zoom - startY; trackPoint.y = mousePos.y / zoom - startY;
} }
else else
{ {
tracked = false; tracked = false;
} }
} }
} break; }
break;
case MP_EVENT_MOUSE_WHEEL: case MP_EVENT_MOUSE_WHEEL:
{ {
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
f32 trackX = mousePos.x/zoom - startX; f32 trackX = mousePos.x / zoom - startX;
f32 trackY = mousePos.y/zoom - startY; f32 trackY = mousePos.y / zoom - startY;
zoom *= 1 + event->mouse.deltaY * 0.01; zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.2, 10); zoom = Clamp(zoom, 0.2, 10);
startX = mousePos.x/zoom - trackX; startX = mousePos.x / zoom - trackX;
startY = mousePos.y/zoom - trackY; startY = mousePos.y / zoom - trackY;
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS) if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS)
{ {
fontIndex = (fontIndex+1)%FONT_COUNT; fontIndex = (fontIndex + 1) % FONT_COUNT;
} }
} break; }
break;
default: default:
break; break;
@ -224,14 +230,14 @@ int main()
if(tracked) if(tracked)
{ {
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x/zoom - trackPoint.x; startX = mousePos.x / zoom - trackPoint.x;
startY = mousePos.y/zoom - trackPoint.y; startY = mousePos.y / zoom - trackPoint.y;
} }
f32 textX = startX; f32 textX = startX;
f32 textY = startY; f32 textY = startY;
/* /*
mg_set_color_rgba(1, 1, 1, 1); mg_set_color_rgba(1, 1, 1, 1);
mg_clear(); mg_clear();
mg_set_color_rgba(1, 0, 0, 1); mg_set_color_rgba(1, 0, 0, 1);
@ -241,8 +247,8 @@ int main()
} }
*/ */
mg_matrix_push((mg_mat2x3){zoom, 0, 0, mg_matrix_push((mg_mat2x3){ zoom, 0, 0,
0, zoom, 0}); 0, zoom, 0 });
mg_set_color_rgba(1, 1, 1, 1); mg_set_color_rgba(1, 1, 1, 1);
mg_clear(); mg_clear();
@ -258,7 +264,7 @@ int main()
{ {
bool lineBreak = false; bool lineBreak = false;
int subIndex = 0; int subIndex = 0;
for(; (startIndex+subIndex) < codePointCount && subIndex < 120; subIndex++) for(; (startIndex + subIndex) < codePointCount && subIndex < 120; subIndex++)
{ {
if(codePoints[startIndex + subIndex] == '\n') if(codePoints[startIndex + subIndex] == '\n')
{ {
@ -267,9 +273,9 @@ int main()
} }
u32 glyphs[512]; u32 glyphs[512];
mg_font_get_glyph_indices(fonts[fontIndex], (str32){subIndex, codePoints+startIndex}, (str32){512, glyphs}); mg_font_get_glyph_indices(fonts[fontIndex], (str32){ subIndex, codePoints + startIndex }, (str32){ 512, glyphs });
mg_glyph_outlines((str32){subIndex, glyphs}); mg_glyph_outlines((str32){ subIndex, glyphs });
mg_fill(); mg_fill();
textY += lineHeights[fontIndex]; textY += lineHeights[fontIndex];
@ -290,11 +296,10 @@ int main()
"Test program: %i glyphs, frame time = %fs, fps = %f", "Test program: %i glyphs, frame time = %fs, fps = %f",
glyphCount, glyphCount,
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_text_outlines(text); mg_text_outlines(text);
mg_fill(); mg_fill();
f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC); f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC);
mg_surface_prepare(surface); mg_surface_prepare(surface);
@ -308,18 +313,17 @@ int main()
frameTime = (endFrameTime - startFrameTime); frameTime = (endFrameTime - startFrameTime);
printf("frame time: %.2fms (%.2fFPS), draw = %f.2ms, flush = %.2fms, present = %.2fms\n", printf("frame time: %.2fms (%.2fFPS), draw = %f.2ms, flush = %.2fms, present = %.2fms\n",
frameTime*1000, frameTime * 1000,
1./frameTime, 1. / frameTime,
(startFlushTime - startFrameTime)*1000, (startFlushTime - startFrameTime) * 1000,
(startPresentTime - startFlushTime)*1000, (startPresentTime - startFlushTime) * 1000,
(endFrameTime - startPresentTime)*1000); (endFrameTime - startPresentTime) * 1000);
mp_input_next_frame(&inputState); mp_input_next_frame(&inputState);
mem_arena_clear(mem_scratch()); mem_arena_clear(mem_scratch());
} }
for(int i = 0; i < FONT_COUNT; i++)
for(int i=0; i<FONT_COUNT; i++)
{ {
mg_font_destroy(fonts[i]); mg_font_destroy(fonts[i]);
} }
@ -328,5 +332,5 @@ int main()
mp_window_destroy(window); mp_window_destroy(window);
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,22 +6,22 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include <errno.h>
#include<stdlib.h> #include <stdio.h>
#include<string.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
int main() int main()
{ {
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -33,7 +33,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
printf("Error: couldn't create surface\n"); printf("Error: couldn't create surface\n");
return(-1); return (-1);
} }
//TODO: create canvas //TODO: create canvas
@ -42,7 +42,7 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas\n"); printf("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
// start app // start app
@ -65,7 +65,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
@ -73,22 +74,23 @@ int main()
{ {
if(event->key.code == MP_KEY_LEFT) if(event->key.code == MP_KEY_LEFT)
{ {
x-=1; x -= 1;
} }
if(event->key.code == MP_KEY_RIGHT) if(event->key.code == MP_KEY_RIGHT)
{ {
x+=1; x += 1;
} }
if(event->key.code == MP_KEY_UP) if(event->key.code == MP_KEY_UP)
{ {
y-=1; y -= 1;
} }
if(event->key.code == MP_KEY_DOWN) if(event->key.code == MP_KEY_DOWN)
{ {
y+=1; y += 1;
} }
} }
} break; }
break;
default: default:
break; break;
@ -135,7 +137,7 @@ int main()
mg_set_color_rgba(1, 0.5, 0, 1); mg_set_color_rgba(1, 0.5, 0, 1);
mg_fill(); mg_fill();
/* /*
mg_set_joint(MG_JOINT_NONE); mg_set_joint(MG_JOINT_NONE);
mg_set_max_joint_excursion(20); mg_set_max_joint_excursion(20);
@ -174,7 +176,7 @@ int main()
*/ */
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_render(surface, canvas); mg_render(surface, canvas);
mg_surface_present(surface); mg_surface_present(surface);
@ -189,5 +191,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,12 +1,12 @@
#include<stdlib.h> #include <stdio.h>
#include<stdio.h> #include <stdlib.h>
#define MG_INCLUDE_GL_API 1 #define MG_INCLUDE_GL_API 1
#include"milepost.h" #include "milepost.h"
mg_surface surface = {0}; mg_surface surface = { 0 };
mg_canvas canvas = {0}; mg_canvas canvas = { 0 };
i32 render_thread(void* user) i32 render_thread(void* user)
{ {
@ -20,7 +20,8 @@ i32 render_thread(void* user)
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -42,7 +43,7 @@ i32 render_thread(void* user)
mem_arena_clear(mem_scratch()); mem_arena_clear(mem_scratch());
} }
return(0); return (0);
} }
int main() int main()
@ -50,7 +51,7 @@ int main()
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -60,7 +61,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
printf("Error: couldn't create surface 1\n"); printf("Error: couldn't create surface 1\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
@ -68,7 +69,7 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas 1\n"); printf("Error: couldn't create canvas 1\n");
return(-1); return (-1);
} }
mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS); mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS);
@ -94,5 +95,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,17 +6,17 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdlib.h> #include <stdio.h>
#include<stdio.h> #include <stdlib.h>
#include<string.h> #include <string.h>
#include"milepost.h" #include "milepost.h"
int main() int main()
{ {
mp_init(); mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
@ -27,7 +27,7 @@ int main()
while(!mp_should_quit()) while(!mp_should_quit())
{ {
mp_pump_events(0); mp_pump_events(0);
mp_event *event = 0; mp_event* event = 0;
while((event = mp_next_event(mem_scratch())) != 0) while((event = mp_next_event(mem_scratch())) != 0)
{ {
switch(event->type) switch(event->type)
@ -35,7 +35,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_WINDOW_RESIZE: case MP_EVENT_WINDOW_RESIZE:
{ {
@ -48,7 +49,8 @@ int main()
event->move.content.y, event->move.content.y,
event->move.content.w, event->move.content.w,
event->move.content.h); event->move.content.h);
} break; }
break;
case MP_EVENT_WINDOW_MOVE: case MP_EVENT_WINDOW_MOVE:
{ {
@ -61,7 +63,8 @@ int main()
event->move.content.y, event->move.content.y,
event->move.content.w, event->move.content.w,
event->move.content.h); event->move.content.h);
} break; }
break;
case MP_EVENT_MOUSE_MOVE: case MP_EVENT_MOUSE_MOVE:
{ {
@ -70,43 +73,50 @@ int main()
event->mouse.y, event->mouse.y,
event->mouse.deltaX, event->mouse.deltaX,
event->mouse.deltaY); event->mouse.deltaY);
} break; }
break;
case MP_EVENT_MOUSE_WHEEL: case MP_EVENT_MOUSE_WHEEL:
{ {
printf("mouse wheel, delta = {%f, %f}\n", printf("mouse wheel, delta = {%f, %f}\n",
event->mouse.deltaX, event->mouse.deltaX,
event->mouse.deltaY); event->mouse.deltaY);
} break; }
break;
case MP_EVENT_MOUSE_ENTER: case MP_EVENT_MOUSE_ENTER:
{ {
printf("mouse enter\n"); printf("mouse enter\n");
} break; }
break;
case MP_EVENT_MOUSE_LEAVE: case MP_EVENT_MOUSE_LEAVE:
{ {
printf("mouse leave\n"); printf("mouse leave\n");
} break; }
break;
case MP_EVENT_MOUSE_BUTTON: case MP_EVENT_MOUSE_BUTTON:
{ {
printf("mouse button %i: %i\n", printf("mouse button %i: %i\n",
event->key.code, event->key.code,
event->key.action == MP_KEY_PRESS ? 1 : 0); event->key.action == MP_KEY_PRESS ? 1 : 0);
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
printf("key %i: %s\n", printf("key %i: %s\n",
event->key.code, event->key.code,
event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat")); event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat"));
} break; }
break;
case MP_EVENT_KEYBOARD_CHAR: case MP_EVENT_KEYBOARD_CHAR:
{ {
printf("entered char %s\n", event->character.sequence); printf("entered char %s\n", event->character.sequence);
} break; }
break;
default: default:
break; break;
@ -117,5 +127,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,16 +6,16 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include <errno.h>
#include<stdlib.h> #include <stdio.h>
#include<string.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#define MG_INCLUDE_GL_API #define MG_INCLUDE_GL_API
#include"milepost.h" #include "milepost.h"
unsigned int program; unsigned int program;
@ -59,7 +59,8 @@ void compile_shader(GLuint shader, const char* source)
} }
GLfloat vertices[] = { 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 typedef struct app_data
{ {
@ -78,12 +79,14 @@ void process_event(app_data* app, mp_event event)
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_WINDOW_RESIZE: case MP_EVENT_WINDOW_RESIZE:
{ {
log_info("resizing window!\n"); log_info("resizing window!\n");
} break; }
break;
default: default:
break; break;
@ -99,18 +102,17 @@ void update_and_render(app_data* app)
static float alpha = 0; static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y; //f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600; f32 aspect = 800 / (f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0, -sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1}; 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); glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -136,12 +138,12 @@ i32 render(void* user)
glGenBuffers(1, &app->vertexBuffer); glGenBuffers(1, &app->vertexBuffer);
GLfloat vertices[] = { 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
};
glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram(); program = glCreateProgram();
@ -177,7 +179,7 @@ i32 render(void* user)
mem_arena_clear(mem_scratch()); mem_arena_clear(mem_scratch());
} }
return(0); return (0);
} }
int main() int main()
@ -185,7 +187,7 @@ int main()
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); mp_window window = mp_window_create(windowRect, "test", 0);
//NOTE: create surface //NOTE: create surface
@ -193,20 +195,19 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
printf("Error: couldn't create surface\n"); printf("Error: couldn't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 1); mg_surface_swap_interval(surface, 1);
mg_surface_deselect(); mg_surface_deselect();
// start app // start app
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
mp_window_focus(window); mp_window_focus(window);
//TODO: start thread //TODO: start thread
app_data app = {.window = window, app_data app = { .window = window,
.surface = surface}; .surface = surface };
mp_thread* renderThread = mp_thread_create(render, &app); mp_thread* renderThread = mp_thread_create(render, &app);
@ -222,5 +223,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,22 +1,22 @@
#include<stdlib.h> #include <stdlib.h>
#include<string.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #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 #define MG_INCLUDE_GL_API 1
#include"milepost.h" #include "milepost.h"
#define LOG_SUBSYSTEM "Main" #define LOG_SUBSYSTEM "Main"
#ifdef OS_WIN64 #ifdef OS_WIN64
#include<process.h> #include <process.h>
#include<io.h> #include <io.h>
#include<fcntl.h> #include <fcntl.h>
#define dup2 _dup2 #define dup2 _dup2
#define pipe(fds) _pipe(fds, 256, O_BINARY) #define pipe(fds) _pipe(fds, 256, O_BINARY)
@ -25,41 +25,40 @@
#define process_id HANDLE #define process_id HANDLE
process_id spawn_child(char* program, char** argv) process_id spawn_child(char* program, char** argv)
{ {
return((process_id)_spawnv(P_NOWAIT, program, argv)); return ((process_id)_spawnv(P_NOWAIT, program, argv));
} }
void terminate_child(process_id child) void terminate_child(process_id child)
{ {
TerminateProcess(child, 0); TerminateProcess(child, 0);
} }
#elif OS_MACOS #elif OS_MACOS
#include<unistd.h> #include <unistd.h>
#include<signal.h> #include <signal.h>
#define process_id pid_t #define process_id pid_t
process_id spawn_child(char* program, char** argv) process_id spawn_child(char* program, char** argv)
{ {
pid_t pid = fork(); pid_t pid = fork();
if(!pid) if(!pid)
{ {
char* envp[] = {0}; char* envp[] = { 0 };
execve(program, argv, envp); execve(program, argv, envp);
assert(0); assert(0);
} }
return(pid); return (pid);
} }
void terminate_child(process_id child) void terminate_child(process_id child)
{ {
kill(child, SIGTERM); kill(child, SIGTERM);
} }
#endif #endif
unsigned int program; unsigned int program;
const char* vshaderSource = const char* vshaderSource =
@ -105,7 +104,7 @@ int child_main(int writeFd)
{ {
mp_init(); mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface //NOTE: create surface
@ -125,12 +124,12 @@ int child_main(int writeFd)
glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = { 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
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram(); program = glCreateProgram();
@ -161,7 +160,7 @@ int child_main(int writeFd)
while(!mp_should_quit()) while(!mp_should_quit())
{ {
mp_pump_events(0); mp_pump_events(0);
mp_event event = {0}; mp_event event = { 0 };
while(mp_next_event(&event)) while(mp_next_event(&event))
{ {
switch(event.type) switch(event.type)
@ -169,7 +168,8 @@ int child_main(int writeFd)
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -181,24 +181,23 @@ int child_main(int writeFd)
mp_rect rect = mg_surface_get_frame(surface); mp_rect rect = mg_surface_get_frame(surface);
vec2 scaling = mg_surface_contents_scaling(surface); vec2 scaling = mg_surface_contents_scaling(surface);
glViewport(0, 0, rect.w*scaling.x, rect.h*scaling.y); glViewport(0, 0, rect.w * scaling.x, rect.h * scaling.y);
glClearColor(0.3, 0.3, 1, 1); glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0; static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y; //f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600; f32 aspect = 800 / (f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0, -sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1}; 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); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -210,7 +209,7 @@ int child_main(int writeFd)
mp_terminate(); mp_terminate();
return(0); return (0);
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -223,18 +222,18 @@ int main(int argc, char** argv)
{ {
int writeFd = atoi(argv[2]); int writeFd = atoi(argv[2]);
printf("child process created with file desc %i\n", writeFd); printf("child process created with file desc %i\n", writeFd);
return(child_main(writeFd)); return (child_main(writeFd));
} }
else else
{ {
return(-1); return (-1);
} }
} }
// setvbuf( stdout, NULL, _IONBF, 0 ); // setvbuf( stdout, NULL, _IONBF, 0 );
mp_init(); mp_init();
//NOTE: create main window //NOTE: create main window
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface client //NOTE: create surface client
@ -248,7 +247,7 @@ int main(int argc, char** argv)
char writeDescStr[64]; char writeDescStr[64];
snprintf(writeDescStr, 64, "%i", fileDesc[1]); snprintf(writeDescStr, 64, "%i", fileDesc[1]);
char* args[] = {"bin/example_surface_sharing", "--child", writeDescStr, 0}; 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);
@ -266,7 +265,7 @@ int main(int argc, char** argv)
while(!mp_should_quit()) while(!mp_should_quit())
{ {
mp_pump_events(0); mp_pump_events(0);
mp_event event = {0}; mp_event event = { 0 };
while(mp_next_event(&event)) while(mp_next_event(&event))
{ {
switch(event.type) switch(event.type)
@ -274,7 +273,8 @@ int main(int argc, char** argv)
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -287,5 +287,5 @@ int main(int argc, char** argv)
terminate_child(child); terminate_child(child);
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,17 +6,17 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdlib.h> #include <errno.h>
#include<string.h> #include <stdio.h>
#include<stdio.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
#include"tiger.c" #include "tiger.c"
mg_font create_font() mg_font create_font()
{ {
@ -28,7 +28,7 @@ mg_font create_font()
if(!fontFile) if(!fontFile)
{ {
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil()); return (mg_font_nil());
} }
unsigned char* fontData = 0; unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END); fseek(fontFile, 0, SEEK_END);
@ -38,16 +38,16 @@ mg_font create_font()
fread(fontData, 1, fontDataSize, fontFile); fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile); fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A, UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B, UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS}; UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData); free(fontData);
return(font); return (font);
} }
int main() int main()
@ -55,7 +55,7 @@ int main()
mp_init(); mp_init();
mp_clock_init(); //TODO put that in mp_init()? mp_clock_init(); //TODO put that in mp_init()?
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -65,7 +65,7 @@ int main()
if(mg_surface_is_nil(surface)) if(mg_surface_is_nil(surface))
{ {
log_error("Couln't create surface\n"); log_error("Couln't create surface\n");
return(-1); return (-1);
} }
mg_surface_swap_interval(surface, 0); mg_surface_swap_interval(surface, 0);
@ -75,7 +75,7 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas\n"); printf("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
mg_font font = create_font(); mg_font font = create_font();
@ -85,7 +85,7 @@ int main()
mp_window_focus(window); mp_window_focus(window);
bool tracked = false; bool tracked = false;
vec2 trackPoint = {0}; vec2 trackPoint = { 0 };
f32 zoom = 1; f32 zoom = 1;
f32 startX = 300, startY = 200; f32 startX = 300, startY = 200;
@ -94,7 +94,7 @@ int main()
f64 frameTime = 0; f64 frameTime = 0;
mp_input_state inputState = {0}; mp_input_state inputState = { 0 };
while(!mp_should_quit()) while(!mp_should_quit())
{ {
@ -111,7 +111,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_MOUSE_BUTTON: case MP_EVENT_MOUSE_BUTTON:
{ {
@ -121,28 +122,30 @@ int main()
{ {
tracked = true; tracked = true;
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
trackPoint.x = (mousePos.x - startX)/zoom; trackPoint.x = (mousePos.x - startX) / zoom;
trackPoint.y = (mousePos.y - startY)/zoom; trackPoint.y = (mousePos.y - startY) / zoom;
} }
else else
{ {
tracked = false; tracked = false;
} }
} }
} break; }
break;
case MP_EVENT_MOUSE_WHEEL: case MP_EVENT_MOUSE_WHEEL:
{ {
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
f32 pinX = (mousePos.x - startX)/zoom; f32 pinX = (mousePos.x - startX) / zoom;
f32 pinY = (mousePos.y - startY)/zoom; f32 pinY = (mousePos.y - startY) / zoom;
zoom *= 1 + event->mouse.deltaY * 0.01; zoom *= 1 + event->mouse.deltaY * 0.01;
zoom = Clamp(zoom, 0.5, 5); zoom = Clamp(zoom, 0.5, 5);
startX = mousePos.x - pinX*zoom; startX = mousePos.x - pinX * zoom;
startY = mousePos.y - pinY*zoom; startY = mousePos.y - pinY * zoom;
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
@ -164,7 +167,8 @@ int main()
{ {
zoom += 0.001; zoom += 0.001;
} }
} break; }
break;
case MP_KEY_DOWN: case MP_KEY_DOWN:
{ {
@ -176,10 +180,12 @@ int main()
{ {
zoom -= 0.001; zoom -= 0.001;
} }
} break; }
break;
} }
} }
} break; }
break;
default: default:
break; break;
@ -189,8 +195,8 @@ int main()
if(tracked) if(tracked)
{ {
vec2 mousePos = mp_mouse_position(&inputState); vec2 mousePos = mp_mouse_position(&inputState);
startX = mousePos.x - trackPoint.x*zoom; startX = mousePos.x - trackPoint.x * zoom;
startY = mousePos.y - trackPoint.y*zoom; startY = mousePos.y - trackPoint.y * zoom;
} }
mg_surface_prepare(surface); mg_surface_prepare(surface);
@ -198,8 +204,8 @@ int main()
mg_set_color_rgba(1, 0, 1, 1); mg_set_color_rgba(1, 0, 1, 1);
mg_clear(); mg_clear();
mg_matrix_push((mg_mat2x3){zoom, 0, startX, mg_matrix_push((mg_mat2x3){ zoom, 0, startX,
0, zoom, startY}); 0, zoom, startY });
draw_tiger(singlePath, singlePathIndex); draw_tiger(singlePath, singlePathIndex);
@ -215,18 +221,18 @@ int main()
mg_set_color_rgba(0, 0, 1, 1); mg_set_color_rgba(0, 0, 1, 1);
mg_set_font(font); mg_set_font(font);
mg_set_font_size(12); mg_set_font_size(12);
mg_move_to(50, 600-50); mg_move_to(50, 600 - 50);
str8 text = str8_pushf(mem_scratch(), str8 text = str8_pushf(mem_scratch(),
"Milepost vector graphics test program (frame time = %fs, fps = %f)...", "Milepost vector graphics test program (frame time = %fs, fps = %f)...",
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_text_outlines(text); mg_text_outlines(text);
mg_fill(); mg_fill();
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
frameTime, frameTime,
1./frameTime); 1. / frameTime);
mg_render(surface, canvas); mg_render(surface, canvas);
mg_surface_present(surface); mg_surface_present(surface);
@ -243,5 +249,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -4857,5 +4857,4 @@ void draw_tiger(bool singlePath, int singlePathIndex)
mg_set_color_rgba(0.000, 0.000, 0.000, 1); mg_set_color_rgba(0.000, 0.000, 0.000, 1);
mg_stroke(); mg_stroke();
} }
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,14 +6,14 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include <stdio.h>
#include<string.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#define MG_INCLUDE_GL_API #define MG_INCLUDE_GL_API
#include"milepost.h" #include "milepost.h"
unsigned int program; unsigned int program;
@ -60,7 +60,7 @@ int main()
{ {
mp_init(); mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface //NOTE: create surface
@ -77,12 +77,12 @@ int main()
glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = { 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
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram(); program = glCreateProgram();
@ -107,7 +107,7 @@ int main()
glUseProgram(program); glUseProgram(program);
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
// mp_window_focus(window); // mp_window_focus(window);
while(!mp_should_quit()) while(!mp_should_quit())
{ {
@ -120,7 +120,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
@ -134,18 +135,17 @@ int main()
static float alpha = 0; static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y; //f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600; f32 aspect = 800 / (f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0, -sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1}; 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); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -159,5 +159,5 @@ int main()
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,15 +6,15 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include <stdio.h>
#include<stdlib.h> #include <stdlib.h>
#include<string.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#define MG_INCLUDE_GL_API 1 #define MG_INCLUDE_GL_API 1
#include"milepost.h" #include "milepost.h"
unsigned int program; unsigned int program;
@ -61,7 +61,7 @@ int main()
{ {
mp_init(); mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
mp_window window = mp_window_create(rect, "test", 0); mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface //NOTE: create surface
@ -77,12 +77,12 @@ int main()
glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = { 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
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram(); program = glCreateProgram();
@ -107,7 +107,7 @@ int main()
glUseProgram(program); glUseProgram(program);
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
// mp_window_focus(window); // mp_window_focus(window);
while(!mp_should_quit()) while(!mp_should_quit())
{ {
@ -120,32 +120,32 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
default: default:
break; break;
} }
} }
// mg_surface_prepare(surface); // mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1); glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0; static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y; //f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600; f32 aspect = 800 / (f32)600;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0, -sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1}; 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); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -161,5 +161,5 @@ int main()
mp_window_destroy(window); mp_window_destroy(window);
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

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

View File

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

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: main.cpp * @file: main.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,19 +6,19 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include<stdlib.h> #include <errno.h>
#include<string.h> #include <stdio.h>
#include<stdio.h> #include <stdlib.h>
#include<errno.h> #include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC #define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h> #include <math.h>
#include"milepost.h" #include "milepost.h"
void debug_print_indent(int indent) void debug_print_indent(int indent)
{ {
for(int i=0; i<indent; i++) for(int i = 0; i < indent; i++)
{ {
printf(" "); printf(" ");
} }
@ -60,7 +60,8 @@ void debug_print_rule(ui_style_rule* rule)
{ {
printf("dragging: "); printf("dragging: ");
} }
} break; }
break;
case UI_SEL_KEY: case UI_SEL_KEY:
printf("key=0x%llx: ", selector->key.hash); printf("key=0x%llx: ", selector->key.hash);
@ -73,6 +74,7 @@ void debug_print_rule(ui_style_rule* rule)
} }
printf("=> font size = %f\n", rule->style->fontSize); printf("=> font size = %f\n", rule->style->fontSize);
} }
void debug_print_size(ui_box* box, ui_axis axis, int indent) void debug_print_size(ui_box* box, ui_axis axis, int indent)
{ {
debug_print_indent(indent); debug_print_indent(indent);
@ -100,7 +102,6 @@ void debug_print_size(ui_box* box, ui_axis axis, int indent)
printf("pixels: %f\n", value); printf("pixels: %f\n", value);
break; break;
} }
} }
void debug_print_styles(ui_box* box, int indent) void debug_print_styles(ui_box* box, int indent)
@ -121,7 +122,7 @@ void debug_print_styles(ui_box* box, int indent)
printf("before rules:\n"); printf("before rules:\n");
for_list(&box->beforeRules, rule, ui_style_rule, boxElt) for_list(&box->beforeRules, rule, ui_style_rule, boxElt)
{ {
debug_print_indent(indent+1); debug_print_indent(indent + 1);
debug_print_rule(rule); debug_print_rule(rule);
} }
} }
@ -132,7 +133,7 @@ void debug_print_styles(ui_box* box, int indent)
printf("after rules:\n"); printf("after rules:\n");
for_list(&box->afterRules, rule, ui_style_rule, boxElt) for_list(&box->afterRules, rule, ui_style_rule, boxElt)
{ {
debug_print_indent(indent+1); debug_print_indent(indent + 1);
debug_print_rule(rule); debug_print_rule(rule);
} }
} }
@ -159,7 +160,7 @@ mg_font create_font()
if(!fontFile) if(!fontFile)
{ {
log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil()); return (mg_font_nil());
} }
unsigned char* fontData = 0; unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END); fseek(fontFile, 0, SEEK_END);
@ -169,31 +170,30 @@ mg_font create_font()
fread(fontData, 1, fontDataSize, fontFile); fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile); fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A, UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B, UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS}; UNICODE_RANGE_SPECIALS };
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData); free(fontData);
return(font); return (font);
} }
void widget_begin_view(char* str) void widget_begin_view(char* str)
{ {
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_Y, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_Y,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.layout.align.x = UI_ALIGN_CENTER, .layout.align.x = UI_ALIGN_CENTER,
.layout.align.y = UI_ALIGN_START}, .layout.align.y = UI_ALIGN_START },
UI_STYLE_LAYOUT); UI_STYLE_LAYOUT);
ui_box_begin(str, UI_FLAG_DRAW_BORDER); ui_box_begin(str, UI_FLAG_DRAW_BORDER);
ui_label(str); ui_label(str);
} }
void widget_end_view(void) void widget_end_view(void)
@ -212,7 +212,7 @@ int main()
ui_init(&context); ui_init(&context);
ui_set_context(&context); ui_set_context(&context);
mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 };
mp_window window = mp_window_create(windowRect, "test", 0); 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);
@ -227,12 +227,12 @@ int main()
if(mg_canvas_is_nil(canvas)) if(mg_canvas_is_nil(canvas))
{ {
printf("Error: couldn't create canvas\n"); printf("Error: couldn't create canvas\n");
return(-1); return (-1);
} }
mg_font font = create_font(); mg_font font = create_font();
mem_arena textArena = {0}; mem_arena textArena = { 0 };
mem_arena_init(&textArena); mem_arena_init(&textArena);
// start app // start app
@ -256,8 +256,8 @@ int main()
case MP_EVENT_WINDOW_CLOSE: case MP_EVENT_WINDOW_CLOSE:
{ {
mp_request_quit(); mp_request_quit();
} break; }
break;
case MP_EVENT_KEYBOARD_KEY: case MP_EVENT_KEYBOARD_KEY:
{ {
@ -265,7 +265,8 @@ int main()
{ {
printDebugStyle = true; printDebugStyle = true;
} }
} break; }
break;
default: default:
break; break;
@ -273,12 +274,12 @@ int main()
} }
//TEST UI //TEST UI
ui_style defaultStyle = {.bgColor = {0}, ui_style defaultStyle = { .bgColor = { 0 },
.color = {1, 1, 1, 1}, .color = { 1, 1, 1, 1 },
.font = font, .font = font,
.fontSize = 16, .fontSize = 16,
.borderColor = {1, 0, 0, 1}, .borderColor = { 1, 0, 0, 1 },
.borderSize = 2}; .borderSize = 2 };
ui_style_mask defaultMask = UI_STYLE_BG_COLOR ui_style_mask defaultMask = UI_STYLE_BG_COLOR
| UI_STYLE_COLOR | UI_STYLE_COLOR
@ -292,48 +293,48 @@ int main()
ui_box* root = 0; ui_box* root = 0;
mp_rect frameRect = mg_surface_get_frame(surface); mp_rect frameRect = mg_surface_get_frame(surface);
vec2 frameSize = {frameRect.w, frameRect.h}; vec2 frameSize = { frameRect.w, frameRect.h };
ui_frame(frameSize, &defaultStyle, defaultMask) ui_frame(frameSize, &defaultStyle, defaultMask)
{ {
root = ui_box_top(); root = ui_box_top();
ui_style_match_before(ui_pattern_all(), &defaultStyle, defaultMask); ui_style_match_before(ui_pattern_all(), &defaultStyle, defaultMask);
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 1}, .size.height = { UI_SIZE_PARENT, 1 },
.layout.axis = UI_AXIS_Y, .layout.axis = UI_AXIS_Y,
.layout.align.x = UI_ALIGN_CENTER, .layout.align.x = UI_ALIGN_CENTER,
.layout.align.y = UI_ALIGN_START, .layout.align.y = UI_ALIGN_START,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.bgColor = {0.11, 0.11, 0.11, 1}}, .bgColor = { 0.11, 0.11, 0.11, 1 } },
UI_STYLE_SIZE UI_STYLE_SIZE
| UI_STYLE_LAYOUT | UI_STYLE_LAYOUT
| UI_STYLE_BG_COLOR); | UI_STYLE_BG_COLOR);
ui_container("background", UI_FLAG_DRAW_BACKGROUND) ui_container("background", UI_FLAG_DRAW_BACKGROUND)
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_CHILDREN}, .size.height = { UI_SIZE_CHILDREN },
.layout.align.x = UI_ALIGN_CENTER}, .layout.align.x = UI_ALIGN_CENTER },
UI_STYLE_SIZE UI_STYLE_SIZE
|UI_STYLE_LAYOUT_ALIGN_X); | UI_STYLE_LAYOUT_ALIGN_X);
ui_container("title", debugFlags) ui_container("title", debugFlags)
{ {
ui_style_next(&(ui_style){.fontSize = 26}, UI_STYLE_FONT_SIZE); ui_style_next(&(ui_style){ .fontSize = 26 }, UI_STYLE_FONT_SIZE);
ui_label("Milepost UI Demo"); ui_label("Milepost UI Demo");
if(ui_box_sig(ui_box_top()).hovering) if(ui_box_sig(ui_box_top()).hovering)
{ {
ui_tooltip("tooltip") ui_tooltip("tooltip")
{ {
ui_style_next(&(ui_style){.bgColor = {1, 0.99, 0.82, 1}}, ui_style_next(&(ui_style){ .bgColor = { 1, 0.99, 0.82, 1 } },
UI_STYLE_BG_COLOR); UI_STYLE_BG_COLOR);
ui_container("background", UI_FLAG_DRAW_BACKGROUND) ui_container("background", UI_FLAG_DRAW_BACKGROUND)
{ {
ui_style_next(&(ui_style){.color = {0, 0, 0, 1}}, ui_style_next(&(ui_style){ .color = { 0, 0, 0, 1 } },
UI_STYLE_COLOR); UI_STYLE_COLOR);
ui_label("That is a tooltip!"); ui_label("That is a tooltip!");
@ -372,43 +373,43 @@ int main()
} }
} }
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 1, 1}}, .size.height = { UI_SIZE_PARENT, 1, 1 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, UI_STYLE_LAYOUT_AXIS); ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X }, UI_STYLE_LAYOUT_AXIS);
ui_container("contents", debugFlags) ui_container("contents", debugFlags)
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 },
.size.height = {UI_SIZE_PARENT, 1}, .size.height = { UI_SIZE_PARENT, 1 },
.borderColor = {0, 0, 1, 1}}, .borderColor = { 0, 0, 1, 1 } },
UI_STYLE_SIZE UI_STYLE_SIZE
|UI_STYLE_BORDER_COLOR); | UI_STYLE_BORDER_COLOR);
ui_container("left", debugFlags) ui_container("left", debugFlags)
{ {
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X,
.layout.spacing = 10, .layout.spacing = 10,
.layout.margin.x = 10, .layout.margin.x = 10,
.layout.margin.y = 10, .layout.margin.y = 10,
.size.width = {UI_SIZE_PARENT, 1}, .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.5}}, .size.height = { UI_SIZE_PARENT, 0.5 } },
UI_STYLE_LAYOUT_AXIS UI_STYLE_LAYOUT_AXIS
|UI_STYLE_LAYOUT_SPACING | UI_STYLE_LAYOUT_SPACING
|UI_STYLE_LAYOUT_MARGIN_X | UI_STYLE_LAYOUT_MARGIN_X
|UI_STYLE_LAYOUT_MARGIN_Y | UI_STYLE_LAYOUT_MARGIN_Y
|UI_STYLE_SIZE); | UI_STYLE_SIZE);
ui_container("up", debugFlags) ui_container("up", debugFlags)
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 },
.size.height = {UI_SIZE_PARENT, 1}}, .size.height = { UI_SIZE_PARENT, 1 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
widget_view("Buttons") widget_view("Buttons")
{ {
if(ui_button("Test Dialog").clicked) if(ui_button("Test Dialog").clicked)
{ {
char* options[] = {"Accept", "Reject"}; char* options[] = { "Accept", "Reject" };
int res = mp_alert_popup("test dialog", "dialog message", 2, options); int res = mp_alert_popup("test dialog", "dialog message", 2, options);
if(res >= 0) if(res >= 0)
{ {
@ -422,7 +423,7 @@ int main()
if(ui_button("Open").clicked) if(ui_button("Open").clicked)
{ {
char* filters[] = {"md"}; char* filters[] = { "md" };
str8 file = mp_open_dialog(mem_scratch(), "Open File", "C:\\Users", 1, filters, false); str8 file = mp_open_dialog(mem_scratch(), "Open File", "C:\\Users", 1, filters, false);
printf("selected file %.*s\n", (int)file.len, file.ptr); printf("selected file %.*s\n", (int)file.len, file.ptr);
} }
@ -434,16 +435,15 @@ int main()
} }
} }
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 },
.size.height = {UI_SIZE_PARENT, 1}}, .size.height = { UI_SIZE_PARENT, 1 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
ui_pattern pattern = { 0 };
ui_pattern pattern = {0}; ui_pattern_push(mem_scratch(), &pattern, (ui_selector){ .kind = UI_SEL_TAG, .tag = ui_tag_make("checkbox") });
ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TAG, .tag = ui_tag_make("checkbox")});
ui_style_match_after(pattern, ui_style_match_after(pattern,
&(ui_style){.bgColor = {0, 1, 0, 1}, &(ui_style){ .bgColor = { 0, 1, 0, 1 },
.color = {1, 1, 1, 1}}, .color = { 1, 1, 1, 1 } },
UI_STYLE_COLOR | UI_STYLE_BG_COLOR); UI_STYLE_COLOR | UI_STYLE_BG_COLOR);
widget_view("checkboxes") widget_view("checkboxes")
@ -458,36 +458,36 @@ int main()
} }
} }
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X,
.size.width = {UI_SIZE_PARENT, 1}, .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.5}}, .size.height = { UI_SIZE_PARENT, 0.5 } },
UI_STYLE_LAYOUT_AXIS UI_STYLE_LAYOUT_AXIS
|UI_STYLE_SIZE); | UI_STYLE_SIZE);
ui_container("down", debugFlags) ui_container("down", debugFlags)
{ {
widget_view("Vertical Sliders") widget_view("Vertical Sliders")
{ {
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X,
.layout.spacing = 10}, .layout.spacing = 10 },
UI_STYLE_LAYOUT_AXIS UI_STYLE_LAYOUT_AXIS
|UI_STYLE_LAYOUT_SPACING); | UI_STYLE_LAYOUT_SPACING);
ui_container("contents", 0) ui_container("contents", 0)
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 },
.size.height = {UI_SIZE_PIXELS, 200}}, .size.height = { UI_SIZE_PIXELS, 200 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider1 = 0; static f32 slider1 = 0;
ui_slider("slider1", 0.2, &slider1); ui_slider("slider1", 0.2, &slider1);
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 },
.size.height = {UI_SIZE_PIXELS, 200}}, .size.height = { UI_SIZE_PIXELS, 200 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider2 = 0; static f32 slider2 = 0;
ui_slider("slider2", 0.2, &slider2); ui_slider("slider2", 0.2, &slider2);
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 },
.size.height = {UI_SIZE_PIXELS, 200}}, .size.height = { UI_SIZE_PIXELS, 200 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider3 = 0; static f32 slider3 = 0;
ui_slider("slider3", 0.2, &slider3); ui_slider("slider3", 0.2, &slider3);
@ -496,20 +496,20 @@ int main()
widget_view("Horizontal Sliders") widget_view("Horizontal Sliders")
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 },
.size.height = {UI_SIZE_PIXELS, 20}}, .size.height = { UI_SIZE_PIXELS, 20 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider1 = 0; static f32 slider1 = 0;
ui_slider("slider1", 0.2, &slider1); ui_slider("slider1", 0.2, &slider1);
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 },
.size.height = {UI_SIZE_PIXELS, 20}}, .size.height = { UI_SIZE_PIXELS, 20 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider2 = 0; static f32 slider2 = 0;
ui_slider("slider2", 0.2, &slider2); ui_slider("slider2", 0.2, &slider2);
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 },
.size.height = {UI_SIZE_PIXELS, 20}}, .size.height = { UI_SIZE_PIXELS, 20 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static f32 slider3 = 0; static f32 slider3 = 0;
ui_slider("slider3", 0.2, &slider3); ui_slider("slider3", 0.2, &slider3);
@ -517,22 +517,22 @@ int main()
} }
} }
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 },
.size.height = {UI_SIZE_PARENT, 1}}, .size.height = { UI_SIZE_PARENT, 1 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
ui_container("right", debugFlags) ui_container("right", debugFlags)
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.33}}, .size.height = { UI_SIZE_PARENT, 0.33 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
widget_view("Text box") widget_view("Text box")
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 300}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 300 },
.size.height = {UI_SIZE_TEXT}}, .size.height = { UI_SIZE_TEXT } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
static str8 text = {0}; static str8 text = { 0 };
ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text); ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text);
if(res.changed) if(res.changed)
{ {
@ -541,47 +541,47 @@ int main()
} }
} }
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.33}}, .size.height = { UI_SIZE_PARENT, 0.33 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
widget_view("Test") widget_view("Test")
{ {
ui_pattern pattern = {0}; ui_pattern pattern = { 0 };
ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TEXT, .text = STR8("panel")}); ui_pattern_push(mem_scratch(), &pattern, (ui_selector){ .kind = UI_SEL_TEXT, .text = STR8("panel") });
ui_style_match_after(pattern, &(ui_style){.bgColor = {0.3, 0.3, 1, 1}}, UI_STYLE_BG_COLOR); ui_style_match_after(pattern, &(ui_style){ .bgColor = { 0.3, 0.3, 1, 1 } }, UI_STYLE_BG_COLOR);
static int selected = 0; static int selected = 0;
str8 options[] = {STR8("option 1"), str8 options[] = { STR8("option 1"),
STR8("option 2"), STR8("option 2"),
STR8("long option 3"), STR8("long option 3"),
STR8("option 4"), STR8("option 4"),
STR8("option 5")}; STR8("option 5") };
ui_select_popup_info info = {.selectedIndex = selected, ui_select_popup_info info = { .selectedIndex = selected,
.optionCount = 5, .optionCount = 5,
.options = options}; .options = options };
ui_select_popup_info result = ui_select_popup("popup", &info); ui_select_popup_info result = ui_select_popup("popup", &info);
selected = result.selectedIndex; selected = result.selectedIndex;
} }
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.33}}, .size.height = { UI_SIZE_PARENT, 0.33 } },
UI_STYLE_SIZE); UI_STYLE_SIZE);
widget_view("Color") widget_view("Color")
{ {
ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 },
.size.height = {UI_SIZE_PARENT, 0.7}, .size.height = { UI_SIZE_PARENT, 0.7 },
.layout.axis = UI_AXIS_X}, .layout.axis = UI_AXIS_X },
UI_STYLE_SIZE UI_STYLE_SIZE
|UI_STYLE_LAYOUT_AXIS); | UI_STYLE_LAYOUT_AXIS);
ui_panel("Panel", UI_FLAG_DRAW_BORDER) ui_panel("Panel", UI_FLAG_DRAW_BORDER)
{ {
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X },
UI_STYLE_LAYOUT_AXIS); UI_STYLE_LAYOUT_AXIS);
ui_container("contents", 0) ui_container("contents", 0)
{ {
ui_style_next(&(ui_style){.layout.spacing = 20}, ui_style_next(&(ui_style){ .layout.spacing = 20 },
UI_STYLE_LAYOUT_SPACING); UI_STYLE_LAYOUT_SPACING);
ui_container("buttons", 0) ui_container("buttons", 0)
{ {
@ -591,10 +591,10 @@ int main()
ui_button("Button D"); ui_button("Button D");
} }
ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X,
.layout.spacing = 20}, .layout.spacing = 20 },
UI_STYLE_LAYOUT_SPACING UI_STYLE_LAYOUT_SPACING
|UI_STYLE_LAYOUT_AXIS); | UI_STYLE_LAYOUT_AXIS);
ui_container("buttons2", 0) ui_container("buttons2", 0)
{ {
@ -606,7 +606,6 @@ int main()
} }
} }
} }
} }
} }
} }
@ -629,5 +628,5 @@ int main()
mg_surface_destroy(surface); mg_surface_destroy(surface);
mp_terminate(); mp_terminate();
return(0); return (0);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: app.c * @file: app.c
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,10 +6,10 @@
* @revision: * @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 // Window handles
@ -18,7 +18,7 @@ oc_app oc_appData = {0};
void oc_init_window_handles() void oc_init_window_handles()
{ {
oc_list_init(&oc_appData.windowFreeList); oc_list_init(&oc_appData.windowFreeList);
for(int i=0; i<OC_APP_MAX_WINDOWS; i++) for(int i = 0; i < OC_APP_MAX_WINDOWS; i++)
{ {
oc_appData.windowPool[i].generation = 1; oc_appData.windowPool[i].generation = 1;
oc_list_append(&oc_appData.windowFreeList, &oc_appData.windowPool[i].freeListElt); oc_list_append(&oc_appData.windowFreeList, &oc_appData.windowPool[i].freeListElt);
@ -27,47 +27,47 @@ void oc_init_window_handles()
bool oc_window_handle_is_null(oc_window window) bool oc_window_handle_is_null(oc_window window)
{ {
return(window.h == 0); return (window.h == 0);
} }
oc_window oc_window_null_handle() oc_window oc_window_null_handle()
{ {
return((oc_window){.h = 0}); return ((oc_window){ .h = 0 });
} }
oc_window_data* oc_window_alloc() 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) oc_window_data* oc_window_ptr_from_handle(oc_window handle)
{ {
u32 index = handle.h>>32; u32 index = handle.h >> 32;
u32 generation = handle.h & 0xffffffff; u32 generation = handle.h & 0xffffffff;
if(index >= OC_APP_MAX_WINDOWS) if(index >= OC_APP_MAX_WINDOWS)
{ {
return(0); return (0);
} }
oc_window_data* window = &oc_appData.windowPool[index]; oc_window_data* window = &oc_appData.windowPool[index];
if(window->generation != generation) if(window->generation != generation)
{ {
return(0); return (0);
} }
else else
{ {
return(window); return (window);
} }
} }
oc_window oc_window_handle_from_ptr(oc_window_data* window) oc_window oc_window_handle_from_ptr(oc_window_data* window)
{ {
OC_DEBUG_ASSERT( (window - oc_appData.windowPool) >= 0 OC_DEBUG_ASSERT((window - oc_appData.windowPool) >= 0
&& (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS); && (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS);
u64 h = ((u64)(window - oc_appData.windowPool))<<32 u64 h = ((u64)(window - oc_appData.windowPool)) << 32
| ((u64)window->generation); | ((u64)window->generation);
return((oc_window){h}); return ((oc_window){ h });
} }
void oc_window_recycle_ptr(oc_window_data* window) void oc_window_recycle_ptr(oc_window_data* window)
@ -152,9 +152,9 @@ oc_event* oc_next_event(oc_arena* arena)
if(event->type == OC_EVENT_PATHDROP) if(event->type == OC_EVENT_PATHDROP)
{ {
u64 pathCount = event->paths.eltCount; u64 pathCount = event->paths.eltCount;
event->paths = (oc_str8_list){0}; event->paths = (oc_str8_list){ 0 };
for(int i=0; i<pathCount; i++) for(int i = 0; i < pathCount; i++)
{ {
if(oc_ringbuffer_read_available(queue) < sizeof(u64)) if(oc_ringbuffer_read_available(queue) < sizeof(u64))
{ {
@ -177,7 +177,7 @@ oc_event* oc_next_event(oc_arena* arena)
} }
} }
} }
return(event); return (event);
} }
//--------------------------------------------------------------- //---------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: platform_app.h * @file: platform_app.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,39 +9,48 @@
#ifndef __APP_H_ #ifndef __APP_H_
#define __APP_H_ #define __APP_H_
#include"util/typedefs.h" #include "util/lists.h"
#include"util/utf8.h" #include "util/memory.h"
#include"util/lists.h" #include "util/typedefs.h"
#include"util/memory.h" #include "util/utf8.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #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, typedef enum
{
OC_MOUSE_CURSOR_ARROW,
OC_MOUSE_CURSOR_RESIZE_0, OC_MOUSE_CURSOR_RESIZE_0,
OC_MOUSE_CURSOR_RESIZE_90, OC_MOUSE_CURSOR_RESIZE_90,
OC_MOUSE_CURSOR_RESIZE_45, OC_MOUSE_CURSOR_RESIZE_45,
OC_MOUSE_CURSOR_RESIZE_135, OC_MOUSE_CURSOR_RESIZE_135,
OC_MOUSE_CURSOR_TEXT } oc_mouse_cursor; OC_MOUSE_CURSOR_TEXT
} oc_mouse_cursor;
typedef i32 oc_window_style; typedef i32 oc_window_style;
static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01<<0, static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01 << 0,
OC_WINDOW_STYLE_FIXED_SIZE = 0x01<<1, OC_WINDOW_STYLE_FIXED_SIZE = 0x01 << 1,
OC_WINDOW_STYLE_NO_CLOSE = 0x01<<2, OC_WINDOW_STYLE_NO_CLOSE = 0x01 << 2,
OC_WINDOW_STYLE_NO_MINIFY = 0x01<<3, OC_WINDOW_STYLE_NO_MINIFY = 0x01 << 3,
OC_WINDOW_STYLE_NO_FOCUS = 0x01<<4, OC_WINDOW_STYLE_NO_FOCUS = 0x01 << 4,
OC_WINDOW_STYLE_FLOAT = 0x01<<5, OC_WINDOW_STYLE_FLOAT = 0x01 << 5,
OC_WINDOW_STYLE_POPUPMENU = 0x01<<6, OC_WINDOW_STYLE_POPUPMENU = 0x01 << 6,
OC_WINDOW_STYLE_NO_BUTTONS = 0x01<<7; OC_WINDOW_STYLE_NO_BUTTONS = 0x01 << 7;
typedef enum { OC_EVENT_NONE, typedef enum
{
OC_EVENT_NONE,
OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key? OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
OC_EVENT_KEYBOARD_KEY, OC_EVENT_KEYBOARD_KEY,
OC_EVENT_KEYBOARD_CHAR, OC_EVENT_KEYBOARD_CHAR,
@ -59,14 +68,20 @@ typedef enum { OC_EVENT_NONE,
OC_EVENT_WINDOW_CLOSE, OC_EVENT_WINDOW_CLOSE,
OC_EVENT_PATHDROP, OC_EVENT_PATHDROP,
OC_EVENT_FRAME, OC_EVENT_FRAME,
OC_EVENT_QUIT } oc_event_type; OC_EVENT_QUIT
} oc_event_type;
typedef enum { OC_KEY_NO_ACTION, typedef enum
{
OC_KEY_NO_ACTION,
OC_KEY_PRESS, OC_KEY_PRESS,
OC_KEY_RELEASE, OC_KEY_RELEASE,
OC_KEY_REPEAT } oc_key_action; OC_KEY_REPEAT
} oc_key_action;
typedef enum { OC_KEY_UNKNOWN = 0, typedef enum
{
OC_KEY_UNKNOWN = 0,
OC_KEY_SPACE = 32, OC_KEY_SPACE = 32,
OC_KEY_APOSTROPHE = 39, /* ' */ OC_KEY_APOSTROPHE = 39, /* ' */
OC_KEY_COMMA = 44, /* , */ OC_KEY_COMMA = 44, /* , */
@ -187,58 +202,63 @@ typedef enum { OC_KEY_UNKNOWN = 0,
OC_KEY_RIGHT_ALT = 346, OC_KEY_RIGHT_ALT = 346,
OC_KEY_RIGHT_SUPER = 347, OC_KEY_RIGHT_SUPER = 347,
OC_KEY_MENU = 348, OC_KEY_MENU = 348,
OC_KEY_COUNT } oc_key_code; OC_KEY_COUNT
} oc_key_code;
typedef enum { typedef enum
{
OC_KEYMOD_NONE = 0x00, OC_KEYMOD_NONE = 0x00,
OC_KEYMOD_ALT = 0x01, OC_KEYMOD_ALT = 0x01,
OC_KEYMOD_SHIFT = 0x02, OC_KEYMOD_SHIFT = 0x02,
OC_KEYMOD_CTRL = 0x04, OC_KEYMOD_CTRL = 0x04,
OC_KEYMOD_CMD = 0x08, OC_KEYMOD_CMD = 0x08,
OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ } oc_keymod_flags; OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */
} oc_keymod_flags;
typedef enum { typedef enum
{
OC_MOUSE_LEFT = 0x00, OC_MOUSE_LEFT = 0x00,
OC_MOUSE_RIGHT = 0x01, OC_MOUSE_RIGHT = 0x01,
OC_MOUSE_MIDDLE = 0x02, OC_MOUSE_MIDDLE = 0x02,
OC_MOUSE_EXT1 = 0x03, OC_MOUSE_EXT1 = 0x03,
OC_MOUSE_EXT2 = 0x04, OC_MOUSE_EXT2 = 0x04,
OC_MOUSE_BUTTON_COUNT } oc_mouse_button; OC_MOUSE_BUTTON_COUNT
} oc_mouse_button;
typedef struct oc_key_event // keyboard and mouse buttons input typedef struct oc_key_event // keyboard and mouse buttons input
{ {
oc_key_action action; oc_key_action action;
i32 code; i32 code;
oc_keymod_flags mods; oc_keymod_flags mods;
char label[8]; char label[8];
u8 labelLen; u8 labelLen;
int clickCount; int clickCount;
} oc_key_event; } oc_key_event;
typedef struct oc_char_event // character input typedef struct oc_char_event // character input
{ {
oc_utf32 codepoint; oc_utf32 codepoint;
char sequence[8]; char sequence[8];
u8 seqLen; u8 seqLen;
} oc_char_event; } oc_char_event;
typedef struct oc_mouse_event // mouse move/scroll typedef struct oc_mouse_event // mouse move/scroll
{ {
f32 x; f32 x;
f32 y; f32 y;
f32 deltaX; f32 deltaX;
f32 deltaY; f32 deltaY;
oc_keymod_flags mods; oc_keymod_flags mods;
} oc_mouse_event; } oc_mouse_event;
typedef struct oc_move_event // window resize / move typedef struct oc_move_event // window resize / move
{ {
oc_rect frame; oc_rect frame;
oc_rect content; oc_rect content;
} oc_move_event; } oc_move_event;
typedef struct oc_event typedef struct oc_event
{ {
//TODO clipboard and path drop //TODO clipboard and path drop
oc_window window; oc_window window;
oc_event_type type; oc_event_type type;
@ -252,135 +272,133 @@ typedef struct oc_event
oc_str8_list paths; oc_str8_list paths;
}; };
} oc_event; } oc_event;
//NOTE: these APIs are not directly available to Orca apps //NOTE: these APIs are not directly available to Orca apps
#if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) #if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// app management // app management
//-------------------------------------------------------------------- //--------------------------------------------------------------------
ORCA_API void oc_init(void); ORCA_API void oc_init(void);
ORCA_API void oc_terminate(void); ORCA_API void oc_terminate(void);
ORCA_API bool oc_should_quit(void); ORCA_API bool oc_should_quit(void);
ORCA_API void oc_cancel_quit(void); ORCA_API void oc_cancel_quit(void);
ORCA_API void oc_request_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 // Main loop and events handling
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/*NOTE: /*NOTE:
oc_pump_events() pumps system events into the event queue. A timeout of 0 polls for events, 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 while a timeout of -1 blocks for events. A timeout > 0 blocks until new events are available
or the timeout elapses. or the timeout elapses.
oc_next_event() get the next event from the event queue, allocating from the passed arena 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 void oc_pump_events(f64 timeout);
ORCA_API oc_event* oc_next_event(oc_arena* arena); ORCA_API oc_event* oc_next_event(oc_arena* arena);
typedef void(*oc_live_resize_callback)(oc_event event, 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); 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 bool oc_window_handle_is_null(oc_window window);
ORCA_API oc_window oc_window_null_handle(void); 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 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_destroy(oc_window window);
ORCA_API void* oc_window_native_pointer(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 bool oc_window_should_close(oc_window window);
ORCA_API void oc_window_request_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 void oc_window_cancel_close(oc_window window);
ORCA_API bool oc_window_is_hidden(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_hide(oc_window window);
ORCA_API void oc_window_show(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_minimized(oc_window window);
ORCA_API bool oc_window_is_maximized(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_minimize(oc_window window);
ORCA_API void oc_window_maximize(oc_window window); ORCA_API void oc_window_maximize(oc_window window);
ORCA_API void oc_window_restore(oc_window window); ORCA_API void oc_window_restore(oc_window window);
ORCA_API bool oc_window_has_focus(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_focus(oc_window window);
ORCA_API void oc_window_unfocus(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_send_to_back(oc_window window);
ORCA_API void oc_window_bring_to_front(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 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_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_position(oc_window window, oc_vec2 position);
ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size); 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 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_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_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_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_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_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 // Clipboard
//-------------------------------------------------------------------- //--------------------------------------------------------------------
ORCA_API void oc_clipboard_clear(void); ORCA_API void oc_clipboard_clear(void);
ORCA_API void oc_clipboard_set_string(oc_str8 string); 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_get_string(oc_arena* arena);
ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing); ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing);
ORCA_API bool oc_clipboard_has_tag(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 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 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, ORCA_API oc_str8 oc_open_dialog(oc_arena* arena,
oc_str8 title, oc_str8 title,
oc_str8 defaultPath, oc_str8 defaultPath,
oc_str8_list filters, oc_str8_list filters,
bool directory); bool directory);
ORCA_API oc_str8 oc_save_dialog(oc_arena* arena, ORCA_API oc_str8 oc_save_dialog(oc_arena* arena,
oc_str8 title, oc_str8 title,
oc_str8 defaultPath, oc_str8 defaultPath,
oc_str8_list filters); oc_str8_list filters);
ORCA_API int oc_alert_popup(oc_str8 title, ORCA_API int oc_alert_popup(oc_str8 title,
oc_str8 message, oc_str8 message,
oc_str8_list options); 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);
//-------------------------------------------------------------------- ORCA_API int oc_directory_create(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);
#endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA)
@ -388,5 +406,4 @@ ORCA_API int oc_directory_create(oc_str8 path);
} // extern "C" } // extern "C"
#endif #endif
#endif //__APP_H_ #endif //__APP_H_

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: app_internal.h * @file: app_internal.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,15 +9,15 @@
#ifndef __APP_INTERNAL_H_ #ifndef __APP_INTERNAL_H_
#define __APP_INTERNAL_H_ #define __APP_INTERNAL_H_
#include"app.h" #include "app.h"
#include"platform/platform.h" #include "platform/platform.h"
#include"util/ringbuffer.h" #include "util/ringbuffer.h"
#if OC_PLATFORM_WINDOWS #if OC_PLATFORM_WINDOWS
#include"win32_app.h" #include "win32_app.h"
#elif OC_PLATFORM_MACOS #elif OC_PLATFORM_MACOS
#include"osx_app.h" #include "osx_app.h"
#else #else
#error "platform not supported yet" #error "platform not supported yet"
#endif #endif
@ -48,7 +48,6 @@ typedef struct oc_window_data
OC_PLATFORM_WINDOW_DATA OC_PLATFORM_WINDOW_DATA
} oc_window_data; } oc_window_data;
//--------------------------------------------------------------- //---------------------------------------------------------------
// Global App State // Global App State
//--------------------------------------------------------------- //---------------------------------------------------------------
@ -59,8 +58,10 @@ typedef struct oc_key_utf8
char label[8]; char label[8];
} oc_key_utf8; } oc_key_utf8;
enum
enum { OC_APP_MAX_WINDOWS = 128 }; {
OC_APP_MAX_WINDOWS = 128
};
typedef struct oc_app typedef struct oc_app
{ {

View File

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

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: osx_app.h * @file: osx_app.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,11 +9,11 @@
#ifndef __OSX_APP_H_ #ifndef __OSX_APP_H_
#define __OSX_APP_H_ #define __OSX_APP_H_
#include"app.h" #include "app.h"
#include"graphics/graphics.h" #include "graphics/graphics.h"
#ifdef __OBJC__ #ifdef __OBJC__
#import<Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#else #else
#define NSWindow void #define NSWindow void
#define NSView void #define NSView void
@ -24,7 +24,7 @@
#define CAContext void #define CAContext void
#endif #endif
#include<Carbon/Carbon.h> #include <Carbon/Carbon.h>
typedef struct oc_osx_window_data typedef struct oc_osx_window_data
{ {
@ -55,25 +55,25 @@ typedef struct oc_osx_app_data
// Surface layer // Surface layer
//----------------------------------------------- //-----------------------------------------------
#ifdef __OBJC__ #ifdef __OBJC__
//NOTE: these private interfaces for surface sharing need to be declared explicitly here //NOTE: these private interfaces for surface sharing need to be declared explicitly here
typedef uint32_t CGSConnectionID; typedef uint32_t CGSConnectionID;
CGSConnectionID CGSMainConnectionID(void); CGSConnectionID CGSMainConnectionID(void);
typedef uint32_t CAContextID; typedef uint32_t CAContextID;
@interface CAContext : NSObject @interface CAContext : NSObject
{ {
} }
+ (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict; + (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict;
@property(readonly) CAContextID contextId; @property(readonly) CAContextID contextId;
@property(retain) CALayer *layer; @property(retain) CALayer* layer;
@end @end
@interface CALayerHost : CALayer @interface CALayerHost : CALayer
{ {
} }
@property CAContextID contextId; @property CAContextID contextId;
@end @end
#endif #endif
typedef struct oc_layer typedef struct oc_layer
@ -82,6 +82,4 @@ typedef struct oc_layer
CAContext* caContext; CAContext* caContext;
} oc_layer; } oc_layer;
#endif //__OSX_APP_H_ #endif //__OSX_APP_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,12 +10,11 @@
#ifndef __WIN32_APP_H_ #ifndef __WIN32_APP_H_
#define __WIN32_APP_H_ #define __WIN32_APP_H_
#include"app.h" #include "app.h"
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define UNICODE #define UNICODE
#include<windows.h> #include <windows.h>
typedef struct oc_win32_window_data typedef struct oc_win32_window_data
{ {
@ -24,6 +23,7 @@ typedef struct oc_win32_window_data
} oc_win32_window_data; } oc_win32_window_data;
typedef struct oc_window_data oc_window_data; typedef struct oc_window_data oc_window_data;
typedef struct oc_layer typedef struct oc_layer
{ {
oc_window_data* parent; oc_window_data* parent;

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: egl_surface.cpp * @file: egl_surface.cpp
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -8,11 +8,11 @@
*****************************************************************/ *****************************************************************/
#define EGL_EGLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES
#include<EGL/egl.h> #include "app/app_internal.h"
#include<EGL/eglext.h> #include "gl_loader.h"
#include"app/app_internal.h" #include "graphics_surface.h"
#include"graphics_surface.h" #include <EGL/egl.h>
#include"gl_loader.h" #include <EGL/eglext.h>
#if OC_PLATFORM_MACOS #if OC_PLATFORM_MACOS
//NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly //NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly
@ -30,7 +30,6 @@
#define oc_gl_load_gles oc_gl_load_gles32 #define oc_gl_load_gles oc_gl_load_gles32
#endif #endif
typedef struct oc_egl_surface typedef struct oc_egl_surface
{ {
oc_surface_data interface; oc_surface_data interface;
@ -104,7 +103,8 @@ void oc_egl_surface_init(oc_egl_surface* surface)
EGLAttrib displayAttribs[] = { EGLAttrib displayAttribs[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
EGL_NONE}; EGL_NONE
};
surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs);
eglInitialize(surface->eglDisplay, NULL, NULL); eglInitialize(surface->eglDisplay, NULL, NULL);
@ -120,12 +120,13 @@ void oc_egl_surface_init(oc_egl_surface* surface)
EGL_SAMPLE_BUFFERS, 0, EGL_SAMPLE_BUFFERS, 0,
EGL_SAMPLES, EGL_DONT_CARE, EGL_SAMPLES, EGL_DONT_CARE,
EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
EGL_NONE }; EGL_NONE
};
int numConfigs = 0; int numConfigs = 0;
eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs);
EGLint const surfaceAttributes[] = {EGL_NONE}; EGLint const surfaceAttributes[] = { EGL_NONE };
surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay,
surface->eglConfig, surface->eglConfig,
nativeLayer, nativeLayer,
@ -138,7 +139,8 @@ void oc_egl_surface_init(oc_egl_surface* surface)
EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE,
EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE,
EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE,
EGL_NONE}; EGL_NONE
};
surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes);
eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext);
@ -161,7 +163,7 @@ oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height)
oc_egl_surface_init(surface); 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_surface_data* oc_egl_surface_create_for_window(oc_window window)
@ -179,5 +181,5 @@ oc_surface_data* oc_egl_surface_create_for_window(oc_window window)
oc_egl_surface_init(surface); oc_egl_surface_init(surface);
} }
} }
return((oc_surface_data*)surface); return ((oc_surface_data*)surface);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: egl_surface.h * @file: egl_surface.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,8 +9,8 @@
#ifndef __EGL_SURFACE_H_ #ifndef __EGL_SURFACE_H_
#define __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_for_window(oc_window window);
oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height); oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height);

View File

@ -8,8 +8,8 @@
#ifndef __GL_API_H__ #ifndef __GL_API_H__
#define __GL_API_H__ #define __GL_API_H__
#include"GL/glcorearb.h" #include "GL/glcorearb.h"
#include"GLES3/gl32.h" #include "GLES3/gl32.h"
typedef struct oc_gl_api typedef struct oc_gl_api
{ {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
#ifndef __GL_LOADER_H__ #ifndef __GL_LOADER_H__
#define __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_gl41(oc_gl_api* api, oc_gl_load_proc loadProc);
void oc_gl_load_gl43(oc_gl_api* api, oc_gl_load_proc loadProc); void oc_gl_load_gl43(oc_gl_api* api, oc_gl_load_proc loadProc);

View File

@ -7,12 +7,16 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathQueueBufferSSBO layout(binding = 0) restrict readonly buffer pathQueueBufferSSBO
{ {
oc_gl_path_queue elements[]; oc_gl_path_queue elements[];
} pathQueueBuffer; }
pathQueueBuffer;
layout(binding = 1) restrict buffer tileQueueBufferSSBO layout(binding = 1) restrict buffer tileQueueBufferSSBO
{ {
oc_gl_tile_queue elements[]; oc_gl_tile_queue elements[];
} tileQueueBuffer; }
tileQueueBuffer;
layout(location = 0) uniform int pathQueueBufferStart; layout(location = 0) uniform int pathQueueBufferStart;
@ -39,7 +43,7 @@ void main()
while(rowIndex < rowCount) while(rowIndex < rowCount)
{ {
int sum = 0; int sum = 0;
for(int x = rowSize-1; x >= 0; x--) for(int x = rowSize - 1; x >= 0; x--)
{ {
int tileIndex = tileQueueBase + rowIndex * rowSize.x + x; int tileIndex = tileQueueBase + rowIndex * rowSize.x + x;
int offset = tileQueueBuffer.elements[tileIndex].windingOffset; int offset = tileQueueBuffer.elements[tileIndex].windingOffset;

View File

@ -7,13 +7,16 @@ layout(std430) buffer;
layout(binding = 0) coherent restrict readonly buffer screenTilesCountBufferSSBO layout(binding = 0) coherent restrict readonly buffer screenTilesCountBufferSSBO
{ {
int elements[]; int elements[];
} screenTilesCountBuffer; }
screenTilesCountBuffer;
layout(binding = 1) coherent restrict writeonly buffer dispatchBufferSSBO layout(binding = 1) coherent restrict writeonly buffer dispatchBufferSSBO
{ {
oc_gl_dispatch_indirect_command elements[]; oc_gl_dispatch_indirect_command elements[];
} dispatchBuffer; }
dispatchBuffer;
layout(location = 0) uniform uint maxWorkGroupCount; layout(location = 0) uniform uint maxWorkGroupCount;

View File

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

View File

@ -7,9 +7,9 @@ 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 x = float(((uint(gl_VertexID) + 2u) / 3u) % 2u);
float y = float(((uint(gl_VertexID) + 1u) / 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); gl_Position = vec4(-1.0f + x * 2.0f, -1.0f + y * 2.0f, 0.0f, 1.0f);
uv = vec2(x, 1-y); uv = vec2(x, 1 - y);
} }

View File

@ -92,7 +92,7 @@ struct oc_gl_dispatch_indirect_command
float ccw(vec2 a, vec2 b, vec2 c) 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_of_segment(vec2 p, oc_gl_segment seg)
@ -104,11 +104,11 @@ int side_of_segment(vec2 p, oc_gl_segment seg)
{ {
if(p.y > seg.box.w) if(p.y > seg.box.w)
{ {
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? -1 : 1; side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? -1 : 1;
} }
else else
{ {
side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? 1 : -1; side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? 1 : -1;
} }
} }
} }
@ -168,19 +168,21 @@ int side_of_segment(vec2 p, oc_gl_segment seg)
case OC_GL_QUADRATIC: case OC_GL_QUADRATIC:
{ {
vec3 ph = {p.x, p.y, 1}; vec3 ph = { p.x, p.y, 1 };
vec3 klm = seg.implicitMatrix * ph; vec3 klm = seg.implicitMatrix * ph;
side = ((klm.x*klm.x - klm.y)*klm.z < 0)? -1 : 1; side = ((klm.x * klm.x - klm.y) * klm.z < 0) ? -1 : 1;
} break; }
break;
case OC_GL_CUBIC: case OC_GL_CUBIC:
{ {
vec3 ph = {p.x, p.y, 1}; vec3 ph = { p.x, p.y, 1 };
vec3 klm = seg.implicitMatrix * ph; vec3 klm = seg.implicitMatrix * ph;
side = (seg.sign*(klm.x*klm.x*klm.x - klm.y*klm.z) < 0)? -1 : 1; side = (seg.sign * (klm.x * klm.x * klm.x - klm.y * klm.z) < 0) ? -1 : 1;
} break; }
break;
} }
} }
} }
return(side); return (side);
} }

View File

@ -7,38 +7,51 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO layout(binding = 0) restrict readonly buffer pathBufferSSBO
{ {
oc_gl_path elements[]; oc_gl_path elements[];
} pathBuffer; }
pathBuffer;
layout(binding = 1) restrict readonly buffer pathQueueBufferSSBO layout(binding = 1) restrict readonly buffer pathQueueBufferSSBO
{ {
oc_gl_path_queue elements[]; oc_gl_path_queue elements[];
} pathQueueBuffer; }
pathQueueBuffer;
layout(binding = 2) restrict readonly buffer tileQueueBufferSSBO layout(binding = 2) restrict readonly buffer tileQueueBufferSSBO
{ {
oc_gl_tile_queue elements[]; oc_gl_tile_queue elements[];
} tileQueueBuffer; }
tileQueueBuffer;
layout(binding = 3) coherent restrict buffer tileOpCountBufferSSBO layout(binding = 3) coherent restrict buffer tileOpCountBufferSSBO
{ {
int elements[]; int elements[];
} tileOpCountBuffer; }
tileOpCountBuffer;
layout(binding = 4) restrict buffer tileOpBufferSSBO layout(binding = 4) restrict buffer tileOpBufferSSBO
{ {
oc_gl_tile_op elements[]; oc_gl_tile_op elements[];
} tileOpBuffer; }
tileOpBuffer;
layout(binding = 5) restrict writeonly buffer screenTilesBufferSSBO layout(binding = 5) restrict writeonly buffer screenTilesBufferSSBO
{ {
oc_gl_screen_tile elements[]; oc_gl_screen_tile elements[];
} screenTilesBuffer; }
screenTilesBuffer;
layout(binding = 6) coherent restrict buffer screenTilesCountBufferSSBO layout(binding = 6) coherent restrict buffer screenTilesCountBufferSSBO
{ {
int elements[]; int elements[];
} screenTilesCountBuffer; }
screenTilesCountBuffer;
layout(location = 0) uniform int tileSize; layout(location = 0) uniform int tileSize;
layout(location = 1) uniform float scale; layout(location = 1) uniform float scale;
@ -64,7 +77,7 @@ void main()
int tileMax = int(xMax * scale) / tileSize; int tileMax = int(xMax * scale) / tileSize;
int pathTileMax = tileMax - pathQueue.area.x; int pathTileMax = tileMax - pathQueue.area.x;
if( pathTileCoord.x >= 0 if(pathTileCoord.x >= 0
&& pathTileCoord.x <= pathTileMax && pathTileCoord.x <= pathTileMax
&& pathTileCoord.y >= 0 && pathTileCoord.y >= 0
&& pathTileCoord.y < pathQueue.area.w) && pathTileCoord.y < pathQueue.area.w)
@ -82,11 +95,11 @@ void main()
int windingOffset = tileQueue.windingOffset; int windingOffset = tileQueue.windingOffset;
int firstOpIndex = tileQueue.first; int firstOpIndex = tileQueue.first;
vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1); vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x + 1, tileCoord.y + 1);
tileBox *= tileSize; tileBox *= tileSize;
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale; vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
if( tileBox.x >= clip.z if(tileBox.x >= clip.z
|| tileBox.z < clip.x || tileBox.z < clip.x
|| tileBox.y >= clip.w || tileBox.y >= clip.w
|| tileBox.w < clip.y) || tileBox.w < clip.y)
@ -121,14 +134,14 @@ void main()
tileOpBuffer.elements[lastOpIndex].next = pathOpIndex; tileOpBuffer.elements[lastOpIndex].next = pathOpIndex;
} }
if( tileBox.x >= clip.x if(tileBox.x >= clip.x
&& tileBox.z < clip.z && tileBox.z < clip.z
&& tileBox.y >= clip.y && tileBox.y >= clip.y
&& tileBox.w < clip.w) && tileBox.w < clip.w)
{ {
tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL; tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL;
if( pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1 if(pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1
&& pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0) && pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0)
{ {
screenTilesBuffer.elements[tileIndex].first = pathOpIndex; screenTilesBuffer.elements[tileIndex].first = pathOpIndex;

View File

@ -7,22 +7,30 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO layout(binding = 0) restrict readonly buffer pathBufferSSBO
{ {
oc_gl_path elements[]; oc_gl_path elements[];
} pathBuffer; }
pathBuffer;
layout(binding = 1) restrict writeonly buffer pathQueueBufferSSBO layout(binding = 1) restrict writeonly buffer pathQueueBufferSSBO
{ {
oc_gl_path_queue elements[]; oc_gl_path_queue elements[];
} pathQueueBuffer; }
pathQueueBuffer;
layout(binding = 2) coherent restrict buffer tileQueueCountBufferSSBO layout(binding = 2) coherent restrict buffer tileQueueCountBufferSSBO
{ {
int elements[]; int elements[];
} tileQueueCountBuffer; }
tileQueueCountBuffer;
layout(binding = 3) restrict writeonly buffer tileQueueBufferSSBO layout(binding = 3) restrict writeonly buffer tileQueueBufferSSBO
{ {
oc_gl_tile_queue elements[]; oc_gl_tile_queue elements[];
} tileQueueBuffer; }
tileQueueBuffer;
layout(location = 0) uniform int tileSize; layout(location = 0) uniform int tileSize;
layout(location = 1) uniform float scale; layout(location = 1) uniform float scale;
@ -41,8 +49,8 @@ void main()
path.box.z, path.box.z,
min(path.box.w, path.clip.w)); min(path.box.w, path.clip.w));
ivec2 firstTile = ivec2(clippedBox.xy*scale)/tileSize; ivec2 firstTile = ivec2(clippedBox.xy * scale) / tileSize;
ivec2 lastTile = ivec2(clippedBox.zw*scale)/tileSize; ivec2 lastTile = ivec2(clippedBox.zw * scale) / tileSize;
int nTilesX = max(0, lastTile.x - firstTile.x + 1); int nTilesX = max(0, lastTile.x - firstTile.x + 1);
int nTilesY = max(0, lastTile.y - firstTile.y + 1); int nTilesY = max(0, lastTile.y - firstTile.y + 1);
@ -60,7 +68,7 @@ void main()
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY); pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY);
pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex; pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex;
for(int i=0; i<tileCount; i++) for(int i = 0; i < tileCount; i++)
{ {
tileQueueBuffer.elements[tileQueuesIndex + i].first = -1; tileQueueBuffer.elements[tileQueuesIndex + i].first = -1;
tileQueueBuffer.elements[tileQueuesIndex + i].last = -1; tileQueueBuffer.elements[tileQueuesIndex + i].last = -1;

View File

@ -7,28 +7,37 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer pathBufferSSBO layout(binding = 0) restrict readonly buffer pathBufferSSBO
{ {
oc_gl_path elements[]; oc_gl_path elements[];
} pathBuffer; }
pathBuffer;
layout(binding = 1) restrict readonly buffer segmentBufferSSBO layout(binding = 1) restrict readonly buffer segmentBufferSSBO
{ {
oc_gl_segment elements[]; oc_gl_segment elements[];
} segmentBuffer; }
segmentBuffer;
layout(binding = 2) restrict readonly buffer tileOpBufferSSBO layout(binding = 2) restrict readonly buffer tileOpBufferSSBO
{ {
oc_gl_tile_op elements[]; oc_gl_tile_op elements[];
} tileOpBuffer; }
tileOpBuffer;
layout(binding = 3) restrict readonly buffer screenTilesBufferSSBO layout(binding = 3) restrict readonly buffer screenTilesBufferSSBO
{ {
oc_gl_screen_tile elements[]; oc_gl_screen_tile elements[];
} screenTilesBuffer; }
screenTilesBuffer;
layout(binding = 4) restrict readonly buffer screenTilesCountBufferSSBO layout(binding = 4) restrict readonly buffer screenTilesCountBufferSSBO
{ {
int elements[]; int elements[];
} screenTilesCountBuffer; }
screenTilesCountBuffer;
layout(location = 0) uniform float scale; layout(location = 0) uniform float scale;
layout(location = 1) uniform int msaaSampleCount; layout(location = 1) uniform int msaaSampleCount;
@ -60,7 +69,7 @@ void main()
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) if((pixelCoord.x % 16) == 0 || (pixelCoord.y % 16) == 0)
{ {
imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1)); imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1));
@ -68,14 +77,14 @@ void main()
} }
*/ */
vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = { vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = {
centerCoord + vec2(1, 3)/16, centerCoord + vec2(1, 3) / 16,
centerCoord + vec2(-1, -3)/16, centerCoord + vec2(-1, -3) / 16,
centerCoord + vec2(5, -1)/16, centerCoord + vec2(5, -1) / 16,
centerCoord + vec2(-3, 5)/16, centerCoord + vec2(-3, 5) / 16,
centerCoord + vec2(-5, -5)/16, centerCoord + vec2(-5, -5) / 16,
centerCoord + vec2(-7, 1)/16, centerCoord + vec2(-7, 1) / 16,
centerCoord + vec2(3, -7)/16, centerCoord + vec2(3, -7) / 16,
centerCoord + vec2(7, 7)/16 centerCoord + vec2(7, 7) / 16
}; };
int sampleCount = msaaSampleCount; int sampleCount = msaaSampleCount;
@ -91,12 +100,13 @@ void main()
centerCoord + vec2(-0.25, 0.25), centerCoord + vec2(-0.25, 0.25),
centerCoord + vec2(+0.25, +0.25), centerCoord + vec2(+0.25, +0.25),
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); vec4 color = vec4(0);
int winding[OC_GL_MAX_SAMPLE_COUNT]; int winding[OC_GL_MAX_SAMPLE_COUNT];
for(int i=0; i<sampleCount; i++) for(int i = 0; i < sampleCount; i++)
{ {
winding[i] = 0; winding[i] = 0;
} }
@ -110,7 +120,7 @@ void main()
if(op.kind == OC_GL_OP_START) if(op.kind == OC_GL_OP_START)
{ {
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++) for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{ {
winding[sampleIndex] = op.windingOffsetOrCrossRight; winding[sampleIndex] = op.windingOffsetOrCrossRight;
} }
@ -120,26 +130,26 @@ void main()
int segIndex = op.index; int segIndex = op.index;
oc_gl_segment seg = segmentBuffer.elements[segIndex]; oc_gl_segment seg = segmentBuffer.elements[segIndex];
for(int sampleIndex=0; sampleIndex<sampleCount; sampleIndex++) for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{ {
vec2 sampleCoord = sampleCoords[sampleIndex]; vec2 sampleCoord = sampleCoords[sampleIndex];
if( (sampleCoord.y > seg.box.y) if((sampleCoord.y > seg.box.y)
&&(sampleCoord.y <= seg.box.w) && (sampleCoord.y <= seg.box.w)
&&(side_of_segment(sampleCoord, seg) < 0)) && (side_of_segment(sampleCoord, seg) < 0))
{ {
winding[sampleIndex] += seg.windingIncrement; winding[sampleIndex] += seg.windingIncrement;
} }
if(op.windingOffsetOrCrossRight != 0) if(op.windingOffsetOrCrossRight != 0)
{ {
if( (seg.config == OC_GL_BR || seg.config == OC_GL_TL) if((seg.config == OC_GL_BR || seg.config == OC_GL_TL)
&&(sampleCoord.y > seg.box.w)) && (sampleCoord.y > seg.box.w))
{ {
winding[sampleIndex] += seg.windingIncrement; winding[sampleIndex] += seg.windingIncrement;
} }
else if( (seg.config == OC_GL_BL || seg.config == OC_GL_TR) else if((seg.config == OC_GL_BL || seg.config == OC_GL_TR)
&&(sampleCoord.y > seg.box.y)) && (sampleCoord.y > seg.box.y))
{ {
winding[sampleIndex] -= seg.windingIncrement; winding[sampleIndex] -= seg.windingIncrement;
} }
@ -153,12 +163,12 @@ void main()
vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color; vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color;
nextColor.rgb *= nextColor.a; nextColor.rgb *= nextColor.a;
int textureID = pathBuffer.elements[pathBufferStart+pathIndex].textureID; int textureID = pathBuffer.elements[pathBufferStart + pathIndex].textureID;
if(textureID >= 0) if(textureID >= 0)
{ {
vec4 texColor = vec4(0); vec4 texColor = vec4(0);
for(int sampleIndex = 0; sampleIndex<srcSampleCount; sampleIndex++) for(int sampleIndex = 0; sampleIndex < srcSampleCount; sampleIndex++)
{ {
vec2 sampleCoord = imgSampleCoords[sampleIndex]; vec2 sampleCoord = imgSampleCoords[sampleIndex];
vec3 ph = vec3(sampleCoord.xy, 1); vec3 ph = vec3(sampleCoord.xy, 1);
@ -204,26 +214,26 @@ void main()
if(op.kind == OC_GL_OP_FILL) if(op.kind == OC_GL_OP_FILL)
{ {
color = color*(1-nextColor.a) + nextColor; color = color * (1 - nextColor.a) + nextColor;
} }
else else
{ {
vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale; vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale;
float coverage = 0; float coverage = 0;
for(int sampleIndex = 0; sampleIndex<sampleCount; sampleIndex++) for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{ {
vec2 sampleCoord = sampleCoords[sampleIndex]; vec2 sampleCoord = sampleCoords[sampleIndex];
if( sampleCoord.x >= clip.x if(sampleCoord.x >= clip.x
&& sampleCoord.x < clip.z && sampleCoord.x < clip.z
&& sampleCoord.y >= clip.y && sampleCoord.y >= clip.y
&& sampleCoord.y < clip.w) && sampleCoord.y < clip.w)
{ {
bool filled = op.kind == OC_GL_OP_CLIP_FILL bool filled = op.kind == OC_GL_OP_CLIP_FILL
||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL || (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL
&& ((winding[sampleIndex] & 1) != 0)) && ((winding[sampleIndex] & 1) != 0))
||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE || (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE
&& (winding[sampleIndex] != 0)); && (winding[sampleIndex] != 0));
if(filled) if(filled)
{ {
@ -233,7 +243,7 @@ void main()
winding[sampleIndex] = op.windingOffsetOrCrossRight; winding[sampleIndex] = op.windingOffsetOrCrossRight;
} }
coverage /= sampleCount; coverage /= sampleCount;
color = coverage*(color*(1-nextColor.a) + nextColor) + (1.-coverage)*color; color = coverage * (color * (1 - nextColor.a) + nextColor) + (1. - coverage) * color;
} }
} }
opIndex = op.next; opIndex = op.next;

View File

@ -7,37 +7,51 @@ layout(std430) buffer;
layout(binding = 0) restrict readonly buffer elementBufferSSBO layout(binding = 0) restrict readonly buffer elementBufferSSBO
{ {
oc_gl_path_elt elements[]; oc_gl_path_elt elements[];
} elementBuffer; }
elementBuffer;
layout(binding = 1) coherent restrict buffer segmentCountBufferSSBO layout(binding = 1) coherent restrict buffer segmentCountBufferSSBO
{ {
int elements[]; int elements[];
} segmentCountBuffer; }
segmentCountBuffer;
layout(binding = 2) restrict buffer segmentBufferSSBO layout(binding = 2) restrict buffer segmentBufferSSBO
{ {
oc_gl_segment elements[]; oc_gl_segment elements[];
} segmentBuffer; }
segmentBuffer;
layout(binding = 3) restrict buffer pathQueueBufferSSBO layout(binding = 3) restrict buffer pathQueueBufferSSBO
{ {
oc_gl_path_queue elements[]; oc_gl_path_queue elements[];
} pathQueueBuffer; }
pathQueueBuffer;
layout(binding = 4) coherent restrict buffer tileQueueBufferSSBO layout(binding = 4) coherent restrict buffer tileQueueBufferSSBO
{ {
oc_gl_tile_queue elements[]; oc_gl_tile_queue elements[];
} tileQueueBuffer; }
tileQueueBuffer;
layout(binding = 5) coherent restrict buffer tileOpCountBufferSSBO layout(binding = 5) coherent restrict buffer tileOpCountBufferSSBO
{ {
int elements[]; int elements[];
} tileOpCountBuffer; }
tileOpCountBuffer;
layout(binding = 6) restrict buffer tileOpBufferSSBO layout(binding = 6) restrict buffer tileOpBufferSSBO
{ {
oc_gl_tile_op elements[]; oc_gl_tile_op elements[];
} tileOpBuffer; }
tileOpBuffer;
layout(location = 0) uniform float scale; layout(location = 0) uniform float scale;
layout(location = 1) uniform uint tileSize; layout(location = 1) uniform uint tileSize;
@ -50,38 +64,39 @@ void bin_to_tiles(int segIndex)
const oc_gl_path_queue pathQueue = pathQueueBuffer.elements[seg.pathIndex]; const oc_gl_path_queue pathQueue = pathQueueBuffer.elements[seg.pathIndex];
ivec4 pathArea = pathQueue.area; ivec4 pathArea = pathQueue.area;
ivec4 coveredTiles = ivec4(seg.box)/int(tileSize); ivec4 coveredTiles = ivec4(seg.box) / int(tileSize);
int xMin = max(0, coveredTiles.x - pathArea.x); int xMin = max(0, coveredTiles.x - pathArea.x);
int yMin = max(0, coveredTiles.y - pathArea.y); int yMin = max(0, coveredTiles.y - pathArea.y);
int xMax = min(coveredTiles.z - pathArea.x, pathArea.z-1); int xMax = min(coveredTiles.z - pathArea.x, pathArea.z - 1);
int yMax = min(coveredTiles.w - pathArea.y, pathArea.w-1); int yMax = min(coveredTiles.w - pathArea.y, pathArea.w - 1);
for(int y = yMin; y <= yMax; y++) for(int y = yMin; y <= yMax; y++)
{ {
for(int x = xMin ; x <= xMax; x++) for(int x = xMin; x <= xMax; x++)
{ {
vec4 tileBox = vec4(float(x + pathArea.x), vec4 tileBox = vec4(float(x + pathArea.x),
float(y + pathArea.y), float(y + pathArea.y),
float(x + pathArea.x + 1), float(x + pathArea.x + 1),
float(y + pathArea.y + 1)) * float(tileSize); float(y + pathArea.y + 1))
* float(tileSize);
vec2 bl = {tileBox.x, tileBox.y}; vec2 bl = { tileBox.x, tileBox.y };
vec2 br = {tileBox.z, tileBox.y}; vec2 br = { tileBox.z, tileBox.y };
vec2 tr = {tileBox.z, tileBox.w}; vec2 tr = { tileBox.z, tileBox.w };
vec2 tl = {tileBox.x, tileBox.w}; vec2 tl = { tileBox.x, tileBox.w };
int sbl = side_of_segment(bl, seg); int sbl = side_of_segment(bl, seg);
int sbr = side_of_segment(br, seg); int sbr = side_of_segment(br, seg);
int str = side_of_segment(tr, seg); int str = side_of_segment(tr, seg);
int stl = side_of_segment(tl, seg); int stl = side_of_segment(tl, seg);
bool crossL = (stl*sbl < 0); bool crossL = (stl * sbl < 0);
bool crossR = (str*sbr < 0); bool crossR = (str * sbr < 0);
bool crossT = (stl*str < 0); bool crossT = (stl * str < 0);
bool crossB = (sbl*sbr < 0); bool crossB = (sbl * sbr < 0);
vec2 s0, s1; vec2 s0, s1;
if(seg.config == OC_GL_TL||seg.config == OC_GL_BR) if(seg.config == OC_GL_TL || seg.config == OC_GL_BR)
{ {
s0 = seg.box.xy; s0 = seg.box.xy;
s1 = seg.box.zw; s1 = seg.box.zw;
@ -112,7 +127,7 @@ void bin_to_tiles(int segIndex)
tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 0; tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 0;
tileOpBuffer.elements[tileOpIndex].next = -1; tileOpBuffer.elements[tileOpIndex].next = -1;
int tileQueueIndex = pathQueue.tileQueues + y*pathArea.z + x; int tileQueueIndex = pathQueue.tileQueues + y * pathArea.z + x;
tileOpBuffer.elements[tileOpIndex].next = atomicExchange(tileQueueBuffer.elements[tileQueueIndex].first, tileOpBuffer.elements[tileOpIndex].next = atomicExchange(tileQueueBuffer.elements[tileQueueIndex].first,
tileOpIndex); tileOpIndex);
@ -163,8 +178,8 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
case OC_GL_CUBIC: case OC_GL_CUBIC:
{ {
s = p[0]; s = p[0];
float sqrNorm0 = dot(p[1]-p[0], p[1]-p[0]); float sqrNorm0 = dot(p[1] - p[0], p[1] - p[0]);
float sqrNorm1 = dot(p[3]-p[2], p[3]-p[2]); float sqrNorm1 = dot(p[3] - p[2], p[3] - p[2]);
if(sqrNorm0 < sqrNorm1) if(sqrNorm0 < sqrNorm1)
{ {
c = p[2]; c = p[2];
@ -174,7 +189,8 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
c = p[1]; c = p[1];
} }
e = p[3]; e = p[3];
} break; }
break;
} }
bool goingUp = e.y >= s.y; bool goingUp = e.y >= s.y;
@ -192,7 +208,7 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
float dx = c.x - box.x; float dx = c.x - box.x;
float dy = c.y - box.y; float dy = c.y - box.y;
float alpha = (box.w - box.y)/(box.z - box.x); float alpha = (box.w - box.y) / (box.z - box.x);
float ofs = box.w - box.y; float ofs = box.w - box.y;
if(goingUp == goingRight) if(goingUp == goingRight)
@ -201,7 +217,7 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
{ {
segmentBuffer.elements[segIndex].config = OC_GL_BR; segmentBuffer.elements[segIndex].config = OC_GL_BR;
} }
else if(dy > alpha*dx) else if(dy > alpha * dx)
{ {
segmentBuffer.elements[segIndex].config = OC_GL_TL; segmentBuffer.elements[segIndex].config = OC_GL_TL;
} }
@ -216,7 +232,7 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
{ {
segmentBuffer.elements[segIndex].config = OC_GL_TR; segmentBuffer.elements[segIndex].config = OC_GL_TR;
} }
else if(dy < ofs - alpha*dx) else if(dy < ofs - alpha * dx)
{ {
segmentBuffer.elements[segIndex].config = OC_GL_BL; segmentBuffer.elements[segIndex].config = OC_GL_BL;
} }
@ -226,11 +242,11 @@ int push_segment(in vec2 p[4], int kind, int pathIndex)
} }
} }
} }
return(segIndex); return (segIndex);
} }
#define square(x) ((x)*(x)) #define square(x) ((x) * (x))
#define cube(x) ((x)*(x)*(x)) #define cube(x) ((x) * (x) * (x))
void line_setup(vec2 p[4], int pathIndex) void line_setup(vec2 p[4], int pathIndex)
{ {
@ -244,10 +260,10 @@ void line_setup(vec2 p[4], int pathIndex)
vec2 quadratic_blossom(vec2 p[4], float u, float v) vec2 quadratic_blossom(vec2 p[4], float u, float v)
{ {
vec2 b10 = u*p[1] + (1-u)*p[0]; vec2 b10 = u * p[1] + (1 - u) * p[0];
vec2 b11 = u*p[2] + (1-u)*p[1]; vec2 b11 = u * p[2] + (1 - u) * p[1];
vec2 b20 = v*b11 + (1-v)*b10; vec2 b20 = v * b11 + (1 - v) * b10;
return(b20); return (b20);
} }
void quadratic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4]) void quadratic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4])
@ -270,7 +286,7 @@ int quadratic_monotonize(vec2 p[4], out float splits[4])
splits[0] = 0; splits[0] = 0;
count++; count++;
vec2 r = (p[0] - p[1])/(p[2] - 2*p[1] + p[0]); vec2 r = (p[0] - p[1]) / (p[2] - 2 * p[1] + p[0]);
if(r.x > r.y) if(r.x > r.y)
{ {
float tmp = r.x; float tmp = r.x;
@ -289,17 +305,17 @@ int quadratic_monotonize(vec2 p[4], out float splits[4])
} }
splits[count] = 1; splits[count] = 1;
count++; count++;
return(count); return (count);
} }
mat3 barycentric_matrix(vec2 v0, vec2 v1, vec2 v2) mat3 barycentric_matrix(vec2 v0, vec2 v1, vec2 v2)
{ {
float det = v0.x*(v1.y-v2.y) + v1.x*(v2.y-v0.y) + v2.x*(v0.y - v1.y); float det = v0.x * (v1.y - v2.y) + v1.x * (v2.y - v0.y) + v2.x * (v0.y - v1.y);
mat3 B = {{v1.y - v2.y, v2.y-v0.y, v0.y-v1.y}, mat3 B = { { v1.y - v2.y, v2.y - v0.y, v0.y - v1.y },
{v2.x - v1.x, v0.x-v2.x, v1.x-v0.x}, { v2.x - v1.x, v0.x - v2.x, v1.x - v0.x },
{v1.x*v2.y-v2.x*v1.y, v2.x*v0.y-v0.x*v2.y, v0.x*v1.y-v1.x*v0.y}}; { v1.x * v2.y - v2.x * v1.y, v2.x * v0.y - v0.x * v2.y, v0.x * v1.y - v1.x * v0.y } };
B *= (1/det); B *= (1 / det);
return(B); return (B);
} }
void quadratic_emit(vec2 p[4], int pathIndex) void quadratic_emit(vec2 p[4], int pathIndex)
@ -309,23 +325,23 @@ void quadratic_emit(vec2 p[4], int pathIndex)
if(segIndex < segmentBuffer.elements.length()) if(segIndex < segmentBuffer.elements.length())
{ {
//NOTE: compute implicit equation matrix //NOTE: compute implicit equation matrix
float det = p[0].x*(p[1].y-p[2].y) + p[1].x*(p[2].y-p[0].y) + p[2].x*(p[0].y - p[1].y); float det = p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y) + p[2].x * (p[0].y - p[1].y);
float a = p[0].y - p[1].y + 0.5*(p[2].y - p[0].y); float a = p[0].y - p[1].y + 0.5 * (p[2].y - p[0].y);
float b = p[1].x - p[0].x + 0.5*(p[0].x - p[2].x); float b = p[1].x - p[0].x + 0.5 * (p[0].x - p[2].x);
float c = p[0].x*p[1].y - p[1].x*p[0].y + 0.5*(p[2].x*p[0].y - p[0].x*p[2].y); float c = p[0].x * p[1].y - p[1].x * p[0].y + 0.5 * (p[2].x * p[0].y - p[0].x * p[2].y);
float d = p[0].y - p[1].y; float d = p[0].y - p[1].y;
float e = p[1].x - p[0].x; float e = p[1].x - p[0].x;
float f = p[0].x*p[1].y - p[1].x*p[0].y; float f = p[0].x * p[1].y - p[1].x * p[0].y;
float flip = ( segmentBuffer.elements[segIndex].config == OC_GL_TL float flip = (segmentBuffer.elements[segIndex].config == OC_GL_TL
|| segmentBuffer.elements[segIndex].config == OC_GL_BL)? -1 : 1; || segmentBuffer.elements[segIndex].config == OC_GL_BL)
? -1
: 1;
float g = flip*(p[2].x*(p[0].y - p[1].y) + p[0].x*(p[1].y - p[2].y) + p[1].x*(p[2].y - p[0].y)); float g = flip * (p[2].x * (p[0].y - p[1].y) + p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y));
segmentBuffer.elements[segIndex].implicitMatrix = (1/det)*mat3(a, d, 0., segmentBuffer.elements[segIndex].implicitMatrix = (1 / det) * mat3(a, d, 0., b, e, 0., c, f, g);
b, e, 0.,
c, f, g);
segmentBuffer.elements[segIndex].hullVertex = p[1]; segmentBuffer.elements[segIndex].hullVertex = p[1];
bin_to_tiles(segIndex); bin_to_tiles(segIndex);
@ -338,10 +354,10 @@ void quadratic_setup(vec2 p[4], int pathIndex)
int splitCount = quadratic_monotonize(p, splits); int splitCount = quadratic_monotonize(p, splits);
//NOTE: produce bézier curve for each consecutive pair of roots //NOTE: produce bézier curve for each consecutive pair of roots
for(int sliceIndex=0; sliceIndex<splitCount-1; sliceIndex++) for(int sliceIndex = 0; sliceIndex < splitCount - 1; sliceIndex++)
{ {
vec2 sp[4]; vec2 sp[4];
quadratic_slice(p, splits[sliceIndex], splits[sliceIndex+1], sp); quadratic_slice(p, splits[sliceIndex], splits[sliceIndex + 1], sp);
quadratic_emit(sp, pathIndex); quadratic_emit(sp, pathIndex);
} }
} }
@ -355,7 +371,7 @@ int quadratic_roots_with_det(float a, float b, float c, float det, out float r[2
if(b != 0) if(b != 0)
{ {
count = 1; count = 1;
r[0] = -c/b; r[0] = -c / b;
} }
} }
else else
@ -369,55 +385,55 @@ int quadratic_roots_with_det(float a, float b, float c, float det, out float r[2
if(b > 0) if(b > 0)
{ {
float q = b + sqrt(det); float q = b + sqrt(det);
r[0] = -c/q; r[0] = -c / q;
r[1] = -q/a; r[1] = -q / a;
} }
else if(b < 0) else if(b < 0)
{ {
float q = -b + sqrt(det); float q = -b + sqrt(det);
r[0] = q/a; r[0] = q / a;
r[1] = c/q; r[1] = c / q;
} }
else else
{ {
float q = sqrt(-a*c); float q = sqrt(-a * c);
if(abs(a) >= abs(c)) if(abs(a) >= abs(c))
{ {
r[0] = q/a; r[0] = q / a;
r[1] = -q/a; r[1] = -q / a;
} }
else else
{ {
r[0] = -c/q; r[0] = -c / q;
r[1] = c/q; r[1] = c / q;
} }
} }
} }
} }
if(count>1 && r[0] > r[1]) if(count > 1 && r[0] > r[1])
{ {
float tmp = r[0]; float tmp = r[0];
r[0] = r[1]; r[0] = r[1];
r[1] = tmp; r[1] = tmp;
} }
return(count); return (count);
} }
int quadratic_roots(float a, float b, float c, out float r[2]) int quadratic_roots(float a, float b, float c, out float r[2])
{ {
float det = square(b)/4. - a*c; float det = square(b) / 4. - a * c;
return(quadratic_roots_with_det(a, b, c, det, r)); return (quadratic_roots_with_det(a, b, c, det, r));
} }
vec2 cubic_blossom(vec2 p[4], float u, float v, float w) vec2 cubic_blossom(vec2 p[4], float u, float v, float w)
{ {
vec2 b10 = u*p[1] + (1-u)*p[0]; vec2 b10 = u * p[1] + (1 - u) * p[0];
vec2 b11 = u*p[2] + (1-u)*p[1]; vec2 b11 = u * p[2] + (1 - u) * p[1];
vec2 b12 = u*p[3] + (1-u)*p[2]; vec2 b12 = u * p[3] + (1 - u) * p[2];
vec2 b20 = v*b11 + (1-v)*b10; vec2 b20 = v * b11 + (1 - v) * b10;
vec2 b21 = v*b12 + (1-v)*b11; vec2 b21 = v * b12 + (1 - v) * b11;
vec2 b30 = w*b21 + (1-w)*b20; vec2 b30 = w * b21 + (1 - w) * b20;
return(b30); return (b30);
} }
void cubic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4]) void cubic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4])
@ -480,16 +496,16 @@ cubic_info cubic_classify(vec2 c[4])
// this may very well be an error on my part that's cancelled by flipping the signs of the d_i though! // this may very well be an error on my part that's cancelled by flipping the signs of the d_i though!
*/ */
float d1 = -(c[3].y*c[2].x - c[3].x*c[2].y); float d1 = -(c[3].y * c[2].x - c[3].x * c[2].y);
float d2 = -(c[3].x*c[1].y - c[3].y*c[1].x); float d2 = -(c[3].x * c[1].y - c[3].y * c[1].x);
float d3 = -(c[2].y*c[1].x - c[2].x*c[1].y); float d3 = -(c[2].y * c[1].x - c[2].x * c[1].y);
result.d1 = d1; result.d1 = d1;
result.d2 = d2; result.d2 = d2;
result.d3 = d3; result.d3 = d3;
//NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1) //NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1)
float discrFactor2 = 3.0*square(d2) - 4.0*d3*d1; float discrFactor2 = 3.0 * square(d2) - 4.0 * d3 * d1;
//NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve //NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve
if(abs(d1) <= 1e-6 && abs(d2) <= 1e-6 && abs(d3) > 1e-6) if(abs(d1) <= 1e-6 && abs(d2) <= 1e-6 && abs(d3) > 1e-6)
@ -498,25 +514,25 @@ cubic_info cubic_classify(vec2 c[4])
//NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0 //NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0
result.kind = CUBIC_DEGENERATE_QUADRATIC; result.kind = CUBIC_DEGENERATE_QUADRATIC;
} }
else if( (discrFactor2 > 0 && abs(d1) > 1e-6) else if((discrFactor2 > 0 && abs(d1) > 1e-6)
||(discrFactor2 == 0 && abs(d1) > 1e-6)) || (discrFactor2 == 0 && abs(d1) > 1e-6))
{ {
//NOTE(martin): serpentine curve or cusp with inflection at infinity //NOTE(martin): serpentine curve or cusp with inflection at infinity
// (these two cases are handled the same way). // (these two cases are handled the same way).
//NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation //NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation
float tmtl[2]; float tmtl[2];
quadratic_roots_with_det(1, -2*d2, (4./3.*d1*d3), (1./3.)*discrFactor2, tmtl); quadratic_roots_with_det(1, -2 * d2, (4. / 3. * d1 * d3), (1. / 3.) * discrFactor2, tmtl);
float tm = tmtl[0]; float tm = tmtl[0];
float sm = 2*d1; float sm = 2 * d1;
float tl = tmtl[1]; float tl = tmtl[1];
float sl = 2*d1; float sl = 2 * d1;
float invNorm = 1/sqrt(square(tm) + square(sm)); float invNorm = 1 / sqrt(square(tm) + square(sm));
tm *= invNorm; tm *= invNorm;
sm *= invNorm; sm *= invNorm;
invNorm = 1/sqrt(square(tl) + square(sl)); invNorm = 1 / sqrt(square(tl) + square(sl));
tl *= invNorm; tl *= invNorm;
sl *= invNorm; sl *= invNorm;
@ -530,9 +546,9 @@ cubic_info cubic_classify(vec2 c[4])
*/ */
result.kind = (discrFactor2 > 0 && d1 != 0) ? CUBIC_SERPENTINE : CUBIC_CUSP; result.kind = (discrFactor2 > 0 && d1 != 0) ? CUBIC_SERPENTINE : CUBIC_CUSP;
F = mat4(tl*tm, -sm*tl-sl*tm, sl*sm, 0, F = mat4(tl * tm, -sm * tl - sl * tm, sl * sm, 0,
cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl), cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl),
cube(tm), -3*sm*square(tm), 3*square(sm)*tm, -cube(sm), cube(tm), -3 * sm * square(tm), 3 * square(sm) * tm, -cube(sm),
1, 0, 0, 0); 1, 0, 0, 0);
result.ts[0] = vec2(tm, sm); result.ts[0] = vec2(tm, sm);
@ -544,18 +560,18 @@ cubic_info cubic_classify(vec2 c[4])
result.kind = CUBIC_LOOP; result.kind = CUBIC_LOOP;
float tetd[2]; float tetd[2];
quadratic_roots_with_det(1, -2*d2, 4*(square(d2)-d1*d3), -discrFactor2, tetd); quadratic_roots_with_det(1, -2 * d2, 4 * (square(d2) - d1 * d3), -discrFactor2, tetd);
float td = tetd[1]; float td = tetd[1];
float sd = 2*d1; float sd = 2 * d1;
float te = tetd[0]; float te = tetd[0];
float se = 2*d1; float se = 2 * d1;
float invNorm = 1/sqrt(square(td) + square(sd)); float invNorm = 1 / sqrt(square(td) + square(sd));
td *= invNorm; td *= invNorm;
sd *= invNorm; sd *= invNorm;
invNorm = 1/sqrt(square(te) + square(se)); invNorm = 1 / sqrt(square(te) + square(se));
te *= invNorm; te *= invNorm;
se *= invNorm; se *= invNorm;
@ -567,9 +583,9 @@ cubic_info cubic_classify(vec2 c[4])
| sd*se te*sd^2 + 2*se*td*sd td*se^2 + 2*sd*te*se 0 | | sd*se te*sd^2 + 2*se*td*sd td*se^2 + 2*sd*te*se 0 |
| 0 -sd^2*se -sd*se^2 0 | | 0 -sd^2*se -sd*se^2 0 |
*/ */
F = mat4(td*te, -se*td-sd*te, sd*se, 0, F = mat4(td * te, -se * td - sd * te, sd * se, 0,
square(td)*te, -se*square(td)-2*sd*te*td, te*square(sd)+2*se*td*sd, -square(sd)*se, square(td) * te, -se * square(td) - 2 * sd * te * td, te * square(sd) + 2 * se * td * sd, -square(sd) * se,
td*square(te), -sd*square(te)-2*se*td*te, td*square(se)+2*sd*te*se, -sd*square(se), td * square(te), -sd * square(te) - 2 * se * td * te, td * square(se) + 2 * sd * te * se, -sd * square(se),
1, 0, 0, 0); 1, 0, 0, 0);
result.ts[0] = vec2(td, sd); result.ts[0] = vec2(td, sd);
@ -579,9 +595,9 @@ cubic_info cubic_classify(vec2 c[4])
{ {
//NOTE(martin): cusp with cusp at infinity //NOTE(martin): cusp with cusp at infinity
float tl = d3; float tl = d3;
float sl = 3*d2; float sl = 3 * d2;
float invNorm = 1/sqrt(square(tl)+square(sl)); float invNorm = 1 / sqrt(square(tl) + square(sl));
tl *= invNorm; tl *= invNorm;
sl *= invNorm; sl *= invNorm;
@ -596,7 +612,7 @@ cubic_info cubic_classify(vec2 c[4])
result.kind = CUBIC_CUSP_INFINITY; result.kind = CUBIC_CUSP_INFINITY;
F = mat4(tl, -sl, 0, 0, F = mat4(tl, -sl, 0, 0,
cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl), cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl),
1, 0, 0, 0, 1, 0, 0, 0,
1, 0, 0, 0); 1, 0, 0, 0);
@ -619,13 +635,13 @@ cubic_info cubic_classify(vec2 c[4])
| 1 1 1 1 | | 1 1 1 1 |
*/ */
mat4 invM3 = mat4(1, 1, 1, 1, mat4 invM3 = mat4(1, 1, 1, 1,
0, 1./3., 2./3., 1, 0, 1. / 3., 2. / 3., 1,
0, 0, 1./3., 1, 0, 0, 1. / 3., 1,
0, 0, 0, 1); 0, 0, 0, 1);
result.K = transpose(invM3*F); result.K = transpose(invM3 * F);
return(result); return (result);
} }
vec2 select_hull_vertex(vec2 p0, vec2 p1, vec2 p2, vec2 p3) vec2 select_hull_vertex(vec2 p0, vec2 p1, vec2 p2, vec2 p3)
@ -638,9 +654,9 @@ vec2 select_hull_vertex(vec2 p0, vec2 p1, vec2 p2, vec2 p3)
*/ */
vec2 pm; vec2 pm;
float det = (p1.x - p0.x)*(p3.y - p2.y) - (p1.y - p0.y)*(p3.x - p2.x); float det = (p1.x - p0.x) * (p3.y - p2.y) - (p1.y - p0.y) * (p3.x - p2.x);
float sqrNorm0 = dot(p1-p0, p1-p0); float sqrNorm0 = dot(p1 - p0, p1 - p0);
float sqrNorm1 = dot(p2-p3, p2-p3); float sqrNorm1 = dot(p2 - p3, p2 - p3);
if(abs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1) if(abs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1)
{ {
@ -655,10 +671,10 @@ vec2 select_hull_vertex(vec2 p0, vec2 p1, vec2 p2, vec2 p3)
} }
else else
{ {
float u = ((p0.x - p2.x)*(p2.y - p3.y) - (p0.y - p2.y)*(p2.x - p3.x))/det; float u = ((p0.x - p2.x) * (p2.y - p3.y) - (p0.y - p2.y) * (p2.x - p3.x)) / det;
pm = p0 + u*(p1-p0); pm = p0 + u * (p1 - p0);
} }
return(pm); return (pm);
} }
void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int pathIndex) void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int pathIndex)
@ -673,10 +689,10 @@ void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int
mat3 K; mat3 K;
//TODO: haul that up in caller //TODO: haul that up in caller
float sqrNorm0 = dot(p[1]-p[0], p[1]-p[0]); float sqrNorm0 = dot(p[1] - p[0], p[1] - p[0]);
float sqrNorm1 = dot(p[2]-p[3], p[2]-p[3]); float sqrNorm1 = dot(p[2] - p[3], p[2] - p[3]);
if(dot(p[0]-p[3], p[0]-p[3]) > 1e-5) if(dot(p[0] - p[3], p[0] - p[3]) > 1e-5)
{ {
if(sqrNorm0 >= sqrNorm1) if(sqrNorm0 >= sqrNorm1)
{ {
@ -702,16 +718,16 @@ void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int
mat3 B = barycentric_matrix(v0, v1, v2); mat3 B = barycentric_matrix(v0, v1, v2);
segmentBuffer.elements[segIndex].implicitMatrix = K*B; segmentBuffer.elements[segIndex].implicitMatrix = K * B;
segmentBuffer.elements[segIndex].hullVertex = select_hull_vertex(sp[0], sp[1], sp[2], sp[3]); segmentBuffer.elements[segIndex].hullVertex = select_hull_vertex(sp[0], sp[1], sp[2], sp[3]);
//NOTE: compute sign flip //NOTE: compute sign flip
segmentBuffer.elements[segIndex].sign = 1; segmentBuffer.elements[segIndex].sign = 1;
if( curve.kind == CUBIC_SERPENTINE if(curve.kind == CUBIC_SERPENTINE
|| curve.kind == CUBIC_CUSP) || curve.kind == CUBIC_CUSP)
{ {
segmentBuffer.elements[segIndex].sign = (curve.d1 < 0)? -1 : 1; segmentBuffer.elements[segIndex].sign = (curve.d1 < 0) ? -1 : 1;
} }
else if(curve.kind == CUBIC_LOOP) else if(curve.kind == CUBIC_LOOP)
{ {
@ -719,10 +735,10 @@ void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int
float d2 = curve.d2; float d2 = curve.d2;
float d3 = curve.d3; float d3 = curve.d3;
float H0 = d3*d1-square(d2) + d1*d2*s0 - square(d1)*square(s0); float H0 = d3 * d1 - square(d2) + d1 * d2 * s0 - square(d1) * square(s0);
float H1 = d3*d1-square(d2) + d1*d2*s1 - square(d1)*square(s1); float H1 = d3 * d1 - square(d2) + d1 * d2 * s1 - square(d1) * square(s1);
float H = (abs(H0) > abs(H1)) ? H0 : H1; float H = (abs(H0) > abs(H1)) ? H0 : H1;
segmentBuffer.elements[segIndex].sign = (H*d1 > 0) ? -1 : 1; segmentBuffer.elements[segIndex].sign = (H * d1 > 0) ? -1 : 1;
} }
if(sp[3].y > sp[0].y) if(sp[3].y > sp[0].y)
@ -746,47 +762,48 @@ void cubic_setup(vec2 p[4], int pathIndex)
*/ */
vec2 c[4] = { vec2 c[4] = {
p[0], p[0],
3.0*(p[1] - p[0]), 3.0 * (p[1] - p[0]),
3.0*(p[0] + p[2] - 2*p[1]), 3.0 * (p[0] + p[2] - 2 * p[1]),
3.0*(p[1] - p[2]) + p[3] - p[0]}; 3.0 * (p[1] - p[2]) + p[3] - p[0]
};
//NOTE: get classification, implicit matrix, double points and inflection points //NOTE: get classification, implicit matrix, double points and inflection points
cubic_info curve = cubic_classify(c); cubic_info curve = cubic_classify(c);
if(curve.kind == CUBIC_DEGENERATE_LINE) if(curve.kind == CUBIC_DEGENERATE_LINE)
{ {
vec2 l[4] = {p[0], p[3], vec2(0), vec2(0)}; vec2 l[4] = { p[0], p[3], vec2(0), vec2(0) };
line_setup(l, pathIndex); line_setup(l, pathIndex);
return; return;
} }
else if(curve.kind == CUBIC_DEGENERATE_QUADRATIC) else if(curve.kind == CUBIC_DEGENERATE_QUADRATIC)
{ {
vec2 quadPoint = vec2(1.5*p[1].x - 0.5*p[0].x, 1.5*p[1].y - 0.5*p[0].y); vec2 quadPoint = vec2(1.5 * p[1].x - 0.5 * p[0].x, 1.5 * p[1].y - 0.5 * p[0].y);
vec2 q[4] = {p[0], quadPoint, p[3], vec2(0)}; vec2 q[4] = { p[0], quadPoint, p[3], vec2(0) };
quadratic_setup(q, pathIndex); quadratic_setup(q, pathIndex);
return; return;
} }
//NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1 //NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1
float rootsX[2]; float rootsX[2];
int rootCountX = quadratic_roots(3*c[3].x, 2*c[2].x, c[1].x, rootsX); int rootCountX = quadratic_roots(3 * c[3].x, 2 * c[2].x, c[1].x, rootsX);
float rootsY[2]; float rootsY[2];
int rootCountY = quadratic_roots(3*c[3].y, 2*c[2].y, c[1].y, rootsY); int rootCountY = quadratic_roots(3 * c[3].y, 2 * c[2].y, c[1].y, rootsY);
float roots[6]; float roots[6];
for(int i=0; i<rootCountX; i++) for(int i = 0; i < rootCountX; i++)
{ {
roots[i] = rootsX[i]; roots[i] = rootsX[i];
} }
for(int i=0; i<rootCountY; i++) for(int i = 0; i < rootCountY; i++)
{ {
roots[i+rootCountX] = rootsY[i]; roots[i + rootCountX] = rootsY[i];
} }
//NOTE: add double points and inflection points to roots if finite //NOTE: add double points and inflection points to roots if finite
int rootCount = rootCountX + rootCountY; int rootCount = rootCountX + rootCountY;
for(int i=0; i<2; i++) for(int i = 0; i < 2; i++)
{ {
if(curve.ts[i].y != 0) if(curve.ts[i].y != 0)
{ {
@ -796,16 +813,16 @@ void cubic_setup(vec2 p[4], int pathIndex)
} }
//NOTE: sort roots //NOTE: sort roots
for(int i=1; i<rootCount; i++) for(int i = 1; i < rootCount; i++)
{ {
float tmp = roots[i]; float tmp = roots[i];
int j = i-1; int j = i - 1;
while(j>=0 && roots[j]>tmp) while(j >= 0 && roots[j] > tmp)
{ {
roots[j+1] = roots[j]; roots[j + 1] = roots[j];
j--; j--;
} }
roots[j+1] = tmp; roots[j + 1] = tmp;
} }
//NOTE: compute split points //NOTE: compute split points
@ -813,7 +830,7 @@ void cubic_setup(vec2 p[4], int pathIndex)
int splitCount = 0; int splitCount = 0;
splits[0] = 0; splits[0] = 0;
splitCount++; splitCount++;
for(int i=0; i<rootCount; i++) for(int i = 0; i < rootCount; i++)
{ {
if(roots[i] > 0 && roots[i] < 1) if(roots[i] > 0 && roots[i] < 1)
{ {
@ -825,10 +842,10 @@ void cubic_setup(vec2 p[4], int pathIndex)
splitCount++; splitCount++;
//NOTE: for each monotonic segment, compute hull matrix and sign, and emit segment //NOTE: for each monotonic segment, compute hull matrix and sign, and emit segment
for(int sliceIndex=0; sliceIndex<splitCount-1; sliceIndex++) for(int sliceIndex = 0; sliceIndex < splitCount - 1; sliceIndex++)
{ {
float s0 = splits[sliceIndex]; float s0 = splits[sliceIndex];
float s1 = splits[sliceIndex+1]; float s1 = splits[sliceIndex + 1];
vec2 sp[4]; vec2 sp[4];
cubic_slice(p, s0, s1, sp); cubic_slice(p, s0, s1, sp);
cubic_emit(curve, p, s0, s1, sp, pathIndex); cubic_emit(curve, p, s0, s1, sp, pathIndex);
@ -845,21 +862,24 @@ void main()
{ {
case OC_GL_LINE: case OC_GL_LINE:
{ {
vec2 p[4] = {elt.p[0]*scale, elt.p[1]*scale, vec2(0), vec2(0)}; vec2 p[4] = { elt.p[0] * scale, elt.p[1] * scale, vec2(0), vec2(0) };
line_setup(p, elt.pathIndex); line_setup(p, elt.pathIndex);
} break; }
break;
case OC_GL_QUADRATIC: case OC_GL_QUADRATIC:
{ {
vec2 p[4] = {elt.p[0]*scale, elt.p[1]*scale, elt.p[2]*scale, vec2(0)}; vec2 p[4] = { elt.p[0] * scale, elt.p[1] * scale, elt.p[2] * scale, vec2(0) };
quadratic_setup(p, elt.pathIndex); quadratic_setup(p, elt.pathIndex);
} break; }
break;
case OC_GL_CUBIC: case OC_GL_CUBIC:
{ {
vec2 p[4] = {elt.p[0]*scale, elt.p[1]*scale, elt.p[2]*scale, elt.p[3]*scale}; vec2 p[4] = { elt.p[0] * scale, elt.p[1] * scale, elt.p[2] * scale, elt.p[3] * scale };
cubic_setup(p, elt.pathIndex); cubic_setup(p, elt.pathIndex);
} break; }
break;
default: default:
break; break;

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: graphics.h * @file: graphics.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,21 +9,23 @@
#ifndef __GRAPHICS_H_ #ifndef __GRAPHICS_H_
#define __GRAPHICS_H_ #define __GRAPHICS_H_
#include"util/typedefs.h" #include "app/app.h"
#include"platform/platform.h" #include "platform/platform.h"
#include"app/app.h" #include "util/typedefs.h"
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): backends selection //NOTE(martin): backends selection
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
typedef enum { typedef enum
{
OC_NONE, OC_NONE,
OC_METAL, OC_METAL,
OC_GL, OC_GL,
OC_GLES, OC_GLES,
OC_CANVAS, OC_CANVAS,
OC_HOST } oc_surface_api; OC_HOST
} oc_surface_api;
//NOTE: these macros are used to select which backend to include when building milepost //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 // they can be overridden by passing them to the compiler command line
@ -76,11 +78,11 @@ typedef enum {
//NOTE: these macros are used to select backend-specific APIs to include when using milepost //NOTE: these macros are used to select backend-specific APIs to include when using milepost
#ifdef OC_EXPOSE_SURFACE_METAL #ifdef OC_EXPOSE_SURFACE_METAL
#include"mtl_surface.h" #include "mtl_surface.h"
#endif #endif
#ifdef OC_EXPOSE_SURFACE_WGL #ifdef OC_EXPOSE_SURFACE_WGL
#include"wgl_surface.h" #include "wgl_surface.h"
#endif #endif
//TODO: expose nsgl surface when supported, expose egl surface, etc... //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 //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 oc_surface oc_surface_nil(void);
ORCA_API bool oc_surface_is_nil(oc_surface surface); ORCA_API bool oc_surface_is_nil(oc_surface surface);
@ -121,9 +126,20 @@ ORCA_API void oc_surface_host_connect(oc_surface surface, oc_surface_id remoteId
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//NOTE(martin): graphics canvas structs //NOTE(martin): graphics canvas structs
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
typedef struct oc_canvas { u64 h; } oc_canvas; typedef struct oc_canvas
typedef struct oc_font { u64 h; } oc_font; {
typedef struct oc_image { u64 h; } oc_image; u64 h;
} oc_canvas;
typedef struct oc_font
{
u64 h;
} oc_font;
typedef struct oc_image
{
u64 h;
} oc_image;
typedef struct oc_color typedef struct oc_color
{ {
@ -136,16 +152,23 @@ typedef struct oc_color
f32 b; f32 b;
f32 a; f32 a;
}; };
f32 c[4]; f32 c[4];
}; };
} oc_color; } oc_color;
typedef enum {OC_JOINT_MITER = 0, typedef enum
{
OC_JOINT_MITER = 0,
OC_JOINT_BEVEL, OC_JOINT_BEVEL,
OC_JOINT_NONE } oc_joint_type; OC_JOINT_NONE
} oc_joint_type;
typedef enum {OC_CAP_NONE = 0, typedef enum
OC_CAP_SQUARE } oc_cap_type; {
OC_CAP_NONE = 0,
OC_CAP_SQUARE
} oc_cap_type;
typedef struct oc_font_extents typedef struct oc_font_extents
{ {

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: graphics_common.h * @file: graphics_common.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -8,15 +8,18 @@
#ifndef __GRAPHICS_COMMON_H_ #ifndef __GRAPHICS_COMMON_H_
#define __GRAPHICS_COMMON_H_ #define __GRAPHICS_COMMON_H_
#include"graphics.h" #include "graphics.h"
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// canvas structs // canvas structs
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef enum { OC_PATH_MOVE, typedef enum
{
OC_PATH_MOVE,
OC_PATH_LINE, OC_PATH_LINE,
OC_PATH_QUADRATIC, OC_PATH_QUADRATIC,
OC_PATH_CUBIC } oc_path_elt_type; OC_PATH_CUBIC
} oc_path_elt_type;
typedef struct oc_path_elt typedef struct oc_path_elt
{ {
@ -53,10 +56,12 @@ typedef struct oc_attributes
} oc_attributes; } oc_attributes;
typedef enum { OC_CMD_FILL, typedef enum
{
OC_CMD_FILL,
OC_CMD_STROKE, OC_CMD_STROKE,
OC_CMD_JUMP OC_CMD_JUMP
} oc_primitive_cmd; } oc_primitive_cmd;
typedef struct oc_primitive typedef struct oc_primitive
{ {

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: graphics_surface.c * @file: graphics_surface.c
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,13 +6,13 @@
* *
*****************************************************************/ *****************************************************************/
#include"graphics_surface.h" #include "graphics_surface.h"
//--------------------------------------------------------------- //---------------------------------------------------------------
// per-thread selected surface // per-thread selected surface
//--------------------------------------------------------------- //---------------------------------------------------------------
oc_thread_local oc_surface oc_selectedSurface = {0}; oc_thread_local oc_surface oc_selectedSurface = { 0 };
//--------------------------------------------------------------- //---------------------------------------------------------------
// typed handles functions // 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 oc_surface_handle_alloc(oc_surface_data* surface)
{ {
oc_surface handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) }; oc_surface handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) };
return(handle); return (handle);
} }
oc_surface_data* oc_surface_data_from_handle(oc_surface 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); oc_surface_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_SURFACE, handle.h);
return(data); return (data);
} }
oc_image oc_image_handle_alloc(oc_image_data* image) oc_image oc_image_handle_alloc(oc_image_data* image)
{ {
oc_image handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) }; oc_image handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) };
return(handle); return (handle);
} }
oc_image_data* oc_image_data_from_handle(oc_image 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); oc_image_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_IMAGE, handle.h);
return(data); return (data);
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
@ -48,24 +48,24 @@ oc_image_data* oc_image_data_from_handle(oc_image handle)
#if OC_COMPILE_GL #if OC_COMPILE_GL
#if OC_PLATFORM_WINDOWS #if OC_PLATFORM_WINDOWS
#include"wgl_surface.h" #include "wgl_surface.h"
#define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window #define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window
#endif #endif
#endif #endif
#if OC_COMPILE_GLES #if OC_COMPILE_GLES
#include"egl_surface.h" #include "egl_surface.h"
#endif #endif
#if OC_COMPILE_METAL #if OC_COMPILE_METAL
#include"mtl_surface.h" #include "mtl_surface.h"
#endif #endif
#if OC_COMPILE_CANVAS #if OC_COMPILE_CANVAS
#if OC_PLATFORM_MACOS #if OC_PLATFORM_MACOS
oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window); oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window);
#elif OC_PLATFORM_WINDOWS #elif OC_PLATFORM_WINDOWS
oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window); oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window);
#endif #endif
#endif #endif
@ -74,32 +74,33 @@ bool oc_is_surface_backend_available(oc_surface_api api)
bool result = false; bool result = false;
switch(api) switch(api)
{ {
#if OC_COMPILE_METAL #if OC_COMPILE_METAL
case OC_METAL: case OC_METAL:
#endif #endif
#if OC_COMPILE_GL #if OC_COMPILE_GL
case OC_GL: case OC_GL:
#endif #endif
#if OC_COMPILE_GLES #if OC_COMPILE_GLES
case OC_GLES: case OC_GLES:
#endif #endif
#if OC_COMPILE_CANVAS #if OC_COMPILE_CANVAS
case OC_CANVAS: case OC_CANVAS:
#endif #endif
result = true; result = true;
break; break;
default: default:
break; break;
} }
return(result); return (result);
} }
oc_surface oc_surface_nil() { return((oc_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); }
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) oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
{ {
@ -112,25 +113,25 @@ oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
switch(api) switch(api)
{ {
#if OC_COMPILE_GL #if OC_COMPILE_GL
case OC_GL: case OC_GL:
surface = oc_gl_surface_create_for_window(window); surface = oc_gl_surface_create_for_window(window);
break; break;
#endif #endif
#if OC_COMPILE_GLES #if OC_COMPILE_GLES
case OC_GLES: case OC_GLES:
surface = oc_egl_surface_create_for_window(window); surface = oc_egl_surface_create_for_window(window);
break; break;
#endif #endif
#if OC_COMPILE_METAL #if OC_COMPILE_METAL
case OC_METAL: case OC_METAL:
surface = oc_mtl_surface_create_for_window(window); surface = oc_mtl_surface_create_for_window(window);
break; break;
#endif #endif
#if OC_COMPILE_CANVAS #if OC_COMPILE_CANVAS
case OC_CANVAS: case OC_CANVAS:
#if OC_PLATFORM_MACOS #if OC_PLATFORM_MACOS
@ -139,7 +140,7 @@ oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
surface = oc_gl_canvas_surface_create_for_window(window); surface = oc_gl_canvas_surface_create_for_window(window);
#endif #endif
break; break;
#endif #endif
default: default:
break; break;
@ -149,7 +150,7 @@ oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
surfaceHandle = oc_surface_handle_alloc(surface); surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle); oc_surface_select(surfaceHandle);
} }
return(surfaceHandle); return (surfaceHandle);
} }
oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api) oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api)
@ -163,11 +164,11 @@ oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api)
switch(api) switch(api)
{ {
#if OC_COMPILE_GLES #if OC_COMPILE_GLES
case OC_GLES: case OC_GLES:
surface = oc_egl_surface_create_remote(width, height); surface = oc_egl_surface_create_remote(width, height);
break; break;
#endif #endif
default: default:
break; break;
@ -177,7 +178,7 @@ oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api)
surfaceHandle = oc_surface_handle_alloc(surface); surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle); oc_surface_select(surfaceHandle);
} }
return(surfaceHandle); return (surfaceHandle);
} }
oc_surface oc_surface_create_host(oc_window window) oc_surface oc_surface_create_host(oc_window window)
@ -188,17 +189,17 @@ oc_surface oc_surface_create_host(oc_window window)
} }
oc_surface handle = oc_surface_nil(); oc_surface handle = oc_surface_nil();
oc_surface_data* surface = 0; oc_surface_data* surface = 0;
#if OC_PLATFORM_MACOS #if OC_PLATFORM_MACOS
surface = oc_osx_surface_create_host(window); surface = oc_osx_surface_create_host(window);
#elif OC_PLATFORM_WINDOWS #elif OC_PLATFORM_WINDOWS
surface = oc_win32_surface_create_host(window); surface = oc_win32_surface_create_host(window);
#endif #endif
if(surface) if(surface)
{ {
handle = oc_surface_handle_alloc(surface); handle = oc_surface_handle_alloc(surface);
} }
return(handle); return (handle);
} }
void oc_surface_destroy(oc_surface handle) void oc_surface_destroy(oc_surface handle)
@ -273,25 +274,25 @@ void oc_surface_swap_interval(oc_surface surface, int swap)
oc_vec2 oc_surface_get_size(oc_surface surface) oc_vec2 oc_surface_get_size(oc_surface surface)
{ {
OC_DEBUG_ASSERT(oc_graphicsData.init); OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 size = {0}; oc_vec2 size = { 0 };
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->getSize) if(surfaceData && surfaceData->getSize)
{ {
size = surfaceData->getSize(surfaceData); size = surfaceData->getSize(surfaceData);
} }
return(size); return (size);
} }
oc_vec2 oc_surface_contents_scaling(oc_surface surface) oc_vec2 oc_surface_contents_scaling(oc_surface surface)
{ {
OC_DEBUG_ASSERT(oc_graphicsData.init); OC_DEBUG_ASSERT(oc_graphicsData.init);
oc_vec2 scaling = {1, 1}; oc_vec2 scaling = { 1, 1 };
oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); oc_surface_data* surfaceData = oc_surface_data_from_handle(surface);
if(surfaceData && surfaceData->contentsScaling) if(surfaceData && surfaceData->contentsScaling)
{ {
scaling = surfaceData->contentsScaling(surfaceData); scaling = surfaceData->contentsScaling(surfaceData);
} }
return(scaling); return (scaling);
} }
void oc_surface_set_hidden(oc_surface surface, bool hidden) void oc_surface_set_hidden(oc_surface surface, bool hidden)
@ -313,7 +314,7 @@ bool oc_surface_get_hidden(oc_surface surface)
{ {
res = surfaceData->getHidden(surfaceData); res = surfaceData->getHidden(surfaceData);
} }
return(res); return (res);
} }
void* oc_surface_native_layer(oc_surface surface) void* oc_surface_native_layer(oc_surface surface)
@ -324,7 +325,7 @@ void* oc_surface_native_layer(oc_surface surface)
{ {
res = surfaceData->nativeLayer(surfaceData); res = surfaceData->nativeLayer(surfaceData);
} }
return(res); return (res);
} }
oc_surface_id oc_surface_remote_id(oc_surface handle) oc_surface_id oc_surface_remote_id(oc_surface handle)
@ -335,7 +336,7 @@ oc_surface_id oc_surface_remote_id(oc_surface handle)
{ {
remoteId = surface->remoteID(surface); remoteId = surface->remoteID(surface);
} }
return(remoteId); return (remoteId);
} }
void oc_surface_host_connect(oc_surface handle, oc_surface_id remoteID) void oc_surface_host_connect(oc_surface handle, oc_surface_id remoteID)
@ -377,13 +378,13 @@ void oc_surface_render_commands(oc_surface surface,
oc_vec2 oc_image_size(oc_image image) oc_vec2 oc_image_size(oc_image image)
{ {
oc_vec2 res = {0}; oc_vec2 res = { 0 };
oc_image_data* imageData = oc_image_data_from_handle(image); oc_image_data* imageData = oc_image_data_from_handle(image);
if(imageData) if(imageData)
{ {
res = imageData->size; res = imageData->size;
} }
return(res); return (res);
} }
oc_image oc_image_create(oc_surface surface, u32 width, u32 height) oc_image oc_image_create(oc_surface surface, u32 width, u32 height)
@ -399,14 +400,14 @@ oc_image oc_image_create(oc_surface surface, u32 width, u32 height)
{ {
OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS); OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS);
oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){width, height}); oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){ width, height });
if(imageData) if(imageData)
{ {
imageData->surface = surface; imageData->surface = surface;
image = oc_image_handle_alloc(imageData); image = oc_image_handle_alloc(imageData);
} }
} }
return(image); return (image);
} }
void oc_image_destroy(oc_image image) void oc_image_destroy(oc_image image)

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: graphics_surface.h * @file: graphics_surface.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -8,34 +8,35 @@
#ifndef __GRAPHICS_SURFACE_H_ #ifndef __GRAPHICS_SURFACE_H_
#define __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 #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
//--------------------------------------------------------------- //---------------------------------------------------------------
// surface interface // surface interface
//--------------------------------------------------------------- //---------------------------------------------------------------
typedef struct oc_surface_data oc_surface_data; typedef struct oc_surface_data oc_surface_data;
typedef struct oc_canvas_backend oc_canvas_backend; typedef struct oc_canvas_backend oc_canvas_backend;
typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface); typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface);
typedef void (*oc_surface_select_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_deselect_proc)(oc_surface_data* surface);
typedef void (*oc_surface_present_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 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_get_size_proc)(oc_surface_data* surface);
typedef oc_vec2 (*oc_surface_contents_scaling_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 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_set_hidden_proc)(oc_surface_data* surface, bool hidden);
typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface); 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 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_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId);
typedef struct oc_surface_data typedef struct oc_surface_data
{ {
oc_surface_api api; oc_surface_api api;
oc_layer layer; oc_layer layer;
@ -54,47 +55,47 @@ typedef struct oc_surface_data
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 oc_surface_handle_alloc(oc_surface_data* surface);
oc_surface_data* oc_surface_data_from_handle(oc_surface handle); 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_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_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_init_host(oc_surface_data* surface, oc_window_data* window);
void oc_surface_cleanup(oc_surface_data* surface); void oc_surface_cleanup(oc_surface_data* surface);
void* oc_surface_native_layer(oc_surface surface); void* oc_surface_native_layer(oc_surface surface);
//--------------------------------------------------------------- //---------------------------------------------------------------
// canvas backend interface // canvas backend interface
//--------------------------------------------------------------- //---------------------------------------------------------------
typedef struct oc_image_data typedef struct oc_image_data
{ {
oc_list_elt listElt; oc_list_elt listElt;
u32 generation; u32 generation;
oc_surface surface; oc_surface surface;
oc_vec2 size; 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 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_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image);
typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend, typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend,
oc_image_data* image, oc_image_data* image,
oc_rect region, oc_rect region,
u8* pixels); u8* pixels);
typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend, typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend,
oc_color clearColor, oc_color clearColor,
u32 primitiveCount, u32 primitiveCount,
oc_primitive* primitives, oc_primitive* primitives,
u32 eltCount, u32 eltCount,
oc_path_elt* pathElements); oc_path_elt* pathElements);
typedef struct oc_canvas_backend typedef struct oc_canvas_backend
{ {
oc_canvas_backend_destroy_proc destroy; oc_canvas_backend_destroy_proc destroy;
oc_canvas_backend_image_create_proc imageCreate; oc_canvas_backend_image_create_proc imageCreate;
@ -103,7 +104,7 @@ typedef struct oc_canvas_backend
oc_canvas_backend_render_proc render; oc_canvas_backend_render_proc render;
} oc_canvas_backend; } oc_canvas_backend;
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: mtl_renderer.h * @file: mtl_renderer.h
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,9 +9,10 @@
#ifndef __MTL_RENDERER_H_ #ifndef __MTL_RENDERER_H_
#define __MTL_RENDERER_H_ #define __MTL_RENDERER_H_
#include<simd/simd.h> #include <simd/simd.h>
typedef enum { typedef enum
{
OC_MTL_FILL, OC_MTL_FILL,
OC_MTL_STROKE, OC_MTL_STROKE,
} oc_mtl_cmd; } oc_mtl_cmd;
@ -26,7 +27,8 @@ typedef struct oc_mtl_path
int texture; int texture;
} oc_mtl_path; } oc_mtl_path;
typedef enum { typedef enum
{
OC_MTL_LINE = 1, OC_MTL_LINE = 1,
OC_MTL_QUADRATIC, OC_MTL_QUADRATIC,
OC_MTL_CUBIC, OC_MTL_CUBIC,
@ -39,7 +41,8 @@ typedef struct oc_mtl_path_elt
vector_float2 p[4]; vector_float2 p[4];
} oc_mtl_path_elt; } oc_mtl_path_elt;
typedef enum { typedef enum
{
OC_MTL_BL, // curve on bottom left OC_MTL_BL, // curve on bottom left
OC_MTL_BR, // curve on bottom right OC_MTL_BR, // curve on bottom right
OC_MTL_TL, // curve on top left OC_MTL_TL, // curve on top left
@ -67,20 +70,24 @@ typedef struct oc_mtl_path_queue
} oc_mtl_path_queue; } oc_mtl_path_queue;
#ifdef __METAL_VERSION__ #ifdef __METAL_VERSION__
using namespace metal; using namespace metal;
#endif #endif
typedef enum { OC_MTL_OP_FILL, typedef enum
{
OC_MTL_OP_FILL,
OC_MTL_OP_CLIP_FILL, OC_MTL_OP_CLIP_FILL,
OC_MTL_OP_START, OC_MTL_OP_START,
OC_MTL_OP_END, OC_MTL_OP_END,
OC_MTL_OP_SEGMENT } oc_mtl_tile_op_kind; OC_MTL_OP_SEGMENT
} oc_mtl_tile_op_kind;
typedef struct oc_mtl_tile_op typedef struct oc_mtl_tile_op
{ {
oc_mtl_tile_op_kind kind; oc_mtl_tile_op_kind kind;
int index; int index;
int next; int next;
union union
{ {
bool crossRight; bool crossRight;
@ -104,7 +111,8 @@ typedef struct oc_mtl_screen_tile
} oc_mtl_screen_tile; } oc_mtl_screen_tile;
enum { enum
{
OC_MTL_MAX_IMAGES_PER_BATCH = 30 OC_MTL_MAX_IMAGES_PER_BATCH = 30
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: mtl_surface.m * @file: mtl_surface.m
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,14 +6,14 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#import<Metal/Metal.h> #import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
#import<QuartzCore/CAMetalLayer.h> #include <simd/simd.h>
#include<simd/simd.h>
#include"graphics_surface.h" #include "app/osx_app.h"
#include"util/macros.h" #include "graphics_surface.h"
#include"app/osx_app.h" #include "util/macros.h"
typedef struct oc_mtl_surface typedef struct oc_mtl_surface
{ {
@ -61,7 +61,9 @@ void oc_mtl_surface_acquire_command_buffer(oc_mtl_surface* surface)
} }
void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface) void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface)
{@autoreleasepool{ {
@autoreleasepool
{
/*WARN(martin): /*WARN(martin):
//TODO: we should stop trying to render if we detect that the app is in the background //TODO: we should stop trying to render if we detect that the app is in the background
or occluded or occluded
@ -79,7 +81,8 @@ void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface)
[surface->drawable retain]; [surface->drawable retain];
} }
} }
}} }
}
void oc_mtl_surface_prepare(oc_surface_data* interface) void oc_mtl_surface_prepare(oc_surface_data* interface)
{ {
@ -96,7 +99,7 @@ void oc_mtl_surface_present(oc_surface_data* interface)
{ {
if(surface->drawable != nil) if(surface->drawable != nil)
{ {
[surface->commandBuffer presentDrawable: surface->drawable]; [surface->commandBuffer presentDrawable:surface->drawable];
[surface->drawable release]; [surface->drawable release];
surface->drawable = nil; surface->drawable = nil;
} }
@ -112,7 +115,7 @@ void oc_mtl_surface_swap_interval(oc_surface_data* interface, int swap)
oc_mtl_surface* surface = (oc_mtl_surface*)interface; oc_mtl_surface* surface = (oc_mtl_surface*)interface;
@autoreleasepool @autoreleasepool
{ {
[surface->mtlLayer setDisplaySyncEnabled: (swap ? YES : NO)]; [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 //TODO fix that according to real scaling, depending on the monitor settings
static const f32 OC_MTL_SURFACE_CONTENTS_SCALING = 2; static const f32 OC_MTL_SURFACE_CONTENTS_SCALING = 2;
@ -201,17 +203,16 @@ oc_surface_data* oc_mtl_surface_create_for_window(oc_window window)
[surface->mtlLayer retain]; [surface->mtlLayer retain];
surface->mtlLayer.device = surface->device; surface->mtlLayer.device = surface->device;
[surface->mtlLayer setOpaque:NO]; [surface->mtlLayer setOpaque:NO];
surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
[surface->interface.layer.caLayer addSublayer: (CALayer*)surface->mtlLayer]; [surface->interface.layer.caLayer addSublayer:(CALayer*)surface->mtlLayer];
//----------------------------------------------------------- //-----------------------------------------------------------
//NOTE(martin): set the size and scaling //NOTE(martin): set the size and scaling
//----------------------------------------------------------- //-----------------------------------------------------------
NSRect frame = [[windowData->osx.nsWindow contentView] frame]; NSRect frame = [[windowData->osx.nsWindow contentView] frame];
CGSize size = frame.size; CGSize size = frame.size;
surface->mtlLayer.frame = (CGRect){{0, 0}, size}; surface->mtlLayer.frame = (CGRect){ { 0, 0 }, size };
size.width *= OC_MTL_SURFACE_CONTENTS_SCALING; size.width *= OC_MTL_SURFACE_CONTENTS_SCALING;
size.height *= OC_MTL_SURFACE_CONTENTS_SCALING; size.height *= OC_MTL_SURFACE_CONTENTS_SCALING;
surface->mtlLayer.drawableSize = size; surface->mtlLayer.drawableSize = size;
@ -220,8 +221,8 @@ oc_surface_data* oc_mtl_surface_create_for_window(oc_window window)
surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
//NOTE(martin): handling resizing //NOTE(martin): handling resizing
// surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; // surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
// surface->mtlLayer.needsDisplayOnBoundsChange = YES; // surface->mtlLayer.needsDisplayOnBoundsChange = YES;
//----------------------------------------------------------- //-----------------------------------------------------------
//NOTE(martin): create a command queue //NOTE(martin): create a command queue
@ -234,7 +235,7 @@ oc_surface_data* oc_mtl_surface_create_for_window(oc_window window)
surface->commandBuffer = nil; surface->commandBuffer = nil;
} }
} }
return((oc_surface_data*)surface); return ((oc_surface_data*)surface);
} }
void* oc_mtl_surface_layer(oc_surface surface) void* oc_mtl_surface_layer(oc_surface surface)
@ -243,11 +244,11 @@ void* oc_mtl_surface_layer(oc_surface surface)
if(surfaceData && surfaceData->api == OC_METAL) if(surfaceData && surfaceData->api == OC_METAL)
{ {
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
return(mtlSurface->mtlLayer); return (mtlSurface->mtlLayer);
} }
else else
{ {
return(nil); return (nil);
} }
} }
@ -258,11 +259,11 @@ void* oc_mtl_surface_drawable(oc_surface surface)
{ {
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_drawable(mtlSurface); oc_mtl_surface_acquire_drawable(mtlSurface);
return(mtlSurface->drawable); return (mtlSurface->drawable);
} }
else else
{ {
return(nil); return (nil);
} }
} }
@ -273,10 +274,10 @@ void* oc_mtl_surface_command_buffer(oc_surface surface)
{ {
oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData;
oc_mtl_surface_acquire_command_buffer(mtlSurface); oc_mtl_surface_acquire_command_buffer(mtlSurface);
return(mtlSurface->commandBuffer); return (mtlSurface->commandBuffer);
} }
else else
{ {
return(nil); return (nil);
} }
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: wgl_surface.c * @file: wgl_surface.c
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -6,23 +6,23 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include"app/win32_app.h" #include "app/win32_app.h"
#include"graphics_surface.h" #include "gl_loader.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 \ #define OC_WGL_PROC_LIST \
OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \ OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \
OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \ OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \
OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \ OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \
OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT) \ OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT)
//NOTE: wgl function pointers declarations //NOTE: wgl function pointers declarations
#define OC_WGL_PROC(type, name) OC_CAT3(PFN, type, PROC) name = 0; #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 #undef OC_WGL_PROC
//NOTE: wgl loader //NOTE: wgl loader
@ -36,18 +36,18 @@ typedef struct oc_wgl_dummy_context
} oc_wgl_dummy_context; } 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() static void oc_wgl_init()
{ {
if(!oc_wglDummyContext.init) if(!oc_wglDummyContext.init)
{ {
//NOTE: create a dummy window //NOTE: create a dummy window
WNDCLASS windowClass = {.style = CS_OWNDC, WNDCLASS windowClass = { .style = CS_OWNDC,
.lpfnWndProc = DefWindowProc, .lpfnWndProc = DefWindowProc,
.hInstance = GetModuleHandleW(NULL), .hInstance = GetModuleHandleW(NULL),
.lpszClassName = "oc_wgl_helper_window_class", .lpszClassName = "oc_wgl_helper_window_class",
.hCursor = LoadCursor(0, IDC_ARROW)}; .hCursor = LoadCursor(0, IDC_ARROW) };
if(!RegisterClass(&windowClass)) if(!RegisterClass(&windowClass))
{ {
@ -68,8 +68,7 @@ static void oc_wgl_init()
} }
oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd); oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd);
PIXELFORMATDESCRIPTOR pixelFormatDesc = PIXELFORMATDESCRIPTOR pixelFormatDesc = {
{
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
1, 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
@ -94,10 +93,10 @@ static void oc_wgl_init()
oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC); oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC);
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
//NOTE(martin): now load WGL extension functions //NOTE(martin): now load WGL extension functions
#define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress( #name ); #define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress(#name);
OC_WGL_PROC_LIST OC_WGL_PROC_LIST
#undef OC_WGL_PROC #undef OC_WGL_PROC
oc_wglDummyContext.init = true; oc_wglDummyContext.init = true;
} }
@ -105,12 +104,11 @@ static void oc_wgl_init()
{ {
wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext);
} }
quit:; quit:;
} }
#undef OC_WGL_PROC_LIST #undef OC_WGL_PROC_LIST
typedef struct oc_wgl_surface typedef struct oc_wgl_surface
{ {
oc_surface_data interface; oc_surface_data interface;
@ -168,7 +166,7 @@ void oc_wgl_surface_swap_interval(oc_surface_data* interface, int swap)
void* oc_wgl_get_proc(const char* name) void* oc_wgl_get_proc(const char* name)
{ {
void* p = wglGetProcAddress(name); void* p = wglGetProcAddress(name);
if( p == 0 if(p == 0
|| p == (void*)0x01 || p == (void*)0x01
|| p == (void*)0x02 || p == (void*)0x02
|| p == (void*)0x03 || p == (void*)0x03
@ -178,7 +176,7 @@ void* oc_wgl_get_proc(const char* name)
HMODULE module = LoadLibrary("opengl32.dll"); HMODULE module = LoadLibrary("opengl32.dll");
p = (void*)GetProcAddress(module, name); p = (void*)GetProcAddress(module, name);
} }
return(p); return (p);
} }
oc_surface_data* oc_wgl_surface_create_for_window(oc_window window) oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
@ -207,8 +205,7 @@ oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
surface->hDC = GetDC(surface->interface.layer.hWnd); surface->hDC = GetDC(surface->interface.layer.hWnd);
//NOTE(martin): create the pixel format and gl context //NOTE(martin): create the pixel format and gl context
PIXELFORMATDESCRIPTOR pixelFormatDesc = PIXELFORMATDESCRIPTOR pixelFormatDesc = {
{
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
1, 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
@ -240,7 +237,8 @@ oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
WGL_ALPHA_BITS_ARB, 8, WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24, WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8, WGL_STENCIL_BITS_ARB, 8,
0}; 0
};
u32 numFormats = 0; u32 numFormats = 0;
int pixelFormat = 0; int pixelFormat = 0;
@ -257,7 +255,8 @@ oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 4,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0}; 0
};
surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs); surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs);
@ -274,5 +273,5 @@ oc_surface_data* oc_wgl_surface_create_for_window(oc_window window)
oc_gl_load_gl44(&surface->api, oc_wgl_get_proc); oc_gl_load_gl44(&surface->api, oc_wgl_get_proc);
} }
} }
return((oc_surface_data*)surface); return ((oc_surface_data*)surface);
} }

View File

@ -1,4 +1,4 @@
/************************************************************//** /************************************************************/ /**
* *
* @file: wgl_surface.c * @file: wgl_surface.c
* @author: Martin Fouilleul * @author: Martin Fouilleul
@ -9,7 +9,7 @@
#ifndef __WGL_SURFACE_H_ #ifndef __WGL_SURFACE_H_
#define __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); oc_surface_data* oc_wgl_surface_create_for_window(oc_window window);

View File

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

View File

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

View File

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

View File

@ -2,12 +2,13 @@
#define _MATH_H #define _MATH_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
// NOTE(orca): not doing anything fancy for float_t and double_t // NOTE(orca): not doing anything fancy for float_t and double_t
typedef float float_t; typedef float float_t;
typedef double double_t; typedef double double_t;
#define NAN __builtin_nanf("") #define NAN __builtin_nanf("")
#define INFINITY __builtin_inff() #define INFINITY __builtin_inff()
@ -18,60 +19,68 @@ typedef double double_t;
#define FP_SUBNORMAL 3 #define FP_SUBNORMAL 3
#define FP_NORMAL 4 #define FP_NORMAL 4
int __fpclassify(double); int __fpclassify(double);
int __fpclassifyf(float); int __fpclassifyf(float);
int __fpclassifyl(long double); int __fpclassifyl(long double);
static __inline unsigned __FLOAT_BITS(float __f)
{
union
{
float __f;
unsigned __i;
} __u;
static __inline unsigned __FLOAT_BITS(float __f)
{
union {float __f; unsigned __i;} __u;
__u.__f = __f; __u.__f = __f;
return __u.__i; return __u.__i;
} }
static __inline unsigned long long __DOUBLE_BITS(double __f)
{ static __inline unsigned long long __DOUBLE_BITS(double __f)
union {double __f; unsigned long long __i;} __u; {
union
{
double __f;
unsigned long long __i;
} __u;
__u.__f = __f; __u.__f = __f;
return __u.__i; return __u.__i;
} }
#define fpclassify(x) ( \ #define fpclassify(x) ( \
sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \ sizeof(x) == sizeof(float) ? __fpclassifyf(x) : sizeof(x) == sizeof(double) ? __fpclassify(x) \
sizeof(x) == sizeof(double) ? __fpclassify(x) : \ : __fpclassifyl(x))
__fpclassifyl(x) )
#define isinf(x) ( \ #define isinf(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \ sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \ : __fpclassifyl(x) == FP_INFINITE)
__fpclassifyl(x) == FP_INFINITE)
#define isnan(x) ( \ #define isnan(x) ( \
sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \ sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \ : __fpclassifyl(x) == FP_NAN)
__fpclassifyl(x) == FP_NAN)
double acos(double); double acos(double);
double ceil(double); double ceil(double);
double cos(double); double cos(double);
float cosf(float); float cosf(float);
double fabs(double); double fabs(double);
double floor(double); double floor(double);
double fmod(double, double); double fmod(double, double);
double pow(double, double); double pow(double, double);
double scalbn(double, int); double scalbn(double, int);
double sin(double); double sin(double);
float sinf(float); float sinf(float);
double sqrt(double); double sqrt(double);
float sqrtf(float); float sqrtf(float);
#define M_E 2.7182818284590452354 /* e */ #define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log_2 e */ #define M_LOG2E 1.4426950408889634074 /* log_2 e */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,63 +3,84 @@
double fmod(double x, double y) double fmod(double x, double y)
{ {
union {double f; uint64_t i;} ux = {x}, uy = {y}; union
int ex = ux.i>>52 & 0x7ff; {
int ey = uy.i>>52 & 0x7ff; double f;
int sx = ux.i>>63; uint64_t i;
} ux = { x }, uy = { y };
int ex = ux.i >> 52 & 0x7ff;
int ey = uy.i >> 52 & 0x7ff;
int sx = ux.i >> 63;
uint64_t i; uint64_t i;
/* in the followings uxi should be ux.i, but then gcc wrongly adds */ /* in the followings uxi should be ux.i, but then gcc wrongly adds */
/* float load/store to inner loops ruining performance and code size */ /* float load/store to inner loops ruining performance and code size */
uint64_t uxi = ux.i; uint64_t uxi = ux.i;
if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) if(uy.i << 1 == 0 || isnan(y) || ex == 0x7ff)
return (x*y)/(x*y); return (x * y) / (x * y);
if (uxi<<1 <= uy.i<<1) { if(uxi << 1 <= uy.i << 1)
if (uxi<<1 == uy.i<<1) {
return 0*x; if(uxi << 1 == uy.i << 1)
return 0 * x;
return x; return x;
} }
/* normalize x and y */ /* normalize x and y */
if (!ex) { if(!ex)
for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1); {
for(i = uxi << 12; i >> 63 == 0; ex--, i <<= 1)
;
uxi <<= -ex + 1; uxi <<= -ex + 1;
} else { }
else
{
uxi &= -1ULL >> 12; uxi &= -1ULL >> 12;
uxi |= 1ULL << 52; uxi |= 1ULL << 52;
} }
if (!ey) { if(!ey)
for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); {
for(i = uy.i << 12; i >> 63 == 0; ey--, i <<= 1)
;
uy.i <<= -ey + 1; uy.i <<= -ey + 1;
} else { }
else
{
uy.i &= -1ULL >> 12; uy.i &= -1ULL >> 12;
uy.i |= 1ULL << 52; uy.i |= 1ULL << 52;
} }
/* x mod y */ /* x mod y */
for (; ex > ey; ex--) { for(; ex > ey; ex--)
{
i = uxi - uy.i; i = uxi - uy.i;
if (i >> 63 == 0) { if(i >> 63 == 0)
if (i == 0) {
return 0*x; if(i == 0)
return 0 * x;
uxi = i; uxi = i;
} }
uxi <<= 1; uxi <<= 1;
} }
i = uxi - uy.i; i = uxi - uy.i;
if (i >> 63 == 0) { if(i >> 63 == 0)
if (i == 0) {
return 0*x; if(i == 0)
return 0 * x;
uxi = i; uxi = i;
} }
for (; uxi>>52 == 0; uxi <<= 1, ex--); for(; uxi >> 52 == 0; uxi <<= 1, ex--)
;
/* scale result */ /* scale result */
if (ex > 0) { if(ex > 0)
{
uxi -= 1ULL << 52; uxi -= 1ULL << 52;
uxi |= (uint64_t)ex << 52; uxi |= (uint64_t)ex << 52;
} else { }
else
{
uxi >>= -ex + 1; uxi >>= -ex + 1;
} }
uxi |= (uint64_t)sx << 63; uxi |= (uint64_t)sx << 63;

View File

@ -1,23 +1,23 @@
#include <stdint.h>
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
#include <stdint.h>
#define WANT_ROUNDING 1 #define WANT_ROUNDING 1
#if WANT_SNAN #if WANT_SNAN
#error SNaN is unsupported #error SNaN is unsupported
#else #else
#define issignalingf_inline(x) 0 #define issignalingf_inline(x) 0
#define issignaling_inline(x) 0 #define issignaling_inline(x) 0
#endif #endif
/* Helps static branch prediction so hot path can be better optimized. */ /* Helps static branch prediction so hot path can be better optimized. */
#ifdef __GNUC__ #ifdef __GNUC__
#define predict_true(x) __builtin_expect(!!(x), 1) #define predict_true(x) __builtin_expect(!!(x), 1)
#define predict_false(x) __builtin_expect(x, 0) #define predict_false(x) __builtin_expect(x, 0)
#else #else
#define predict_true(x) (x) #define predict_true(x) (x)
#define predict_false(x) (x) #define predict_false(x) (x)
#endif #endif
static inline float eval_as_float(float x) static inline float eval_as_float(float x)
@ -39,7 +39,8 @@ static inline double eval_as_double(double x)
used to evaluate an expression for its fenv side-effects only. */ used to evaluate an expression for its fenv side-effects only. */
#ifndef fp_force_evalf #ifndef fp_force_evalf
#define fp_force_evalf fp_force_evalf #define fp_force_evalf fp_force_evalf
static inline void fp_force_evalf(float x) static inline void fp_force_evalf(float x)
{ {
volatile float y; volatile float y;
@ -48,7 +49,8 @@ static inline void fp_force_evalf(float x)
#endif #endif
#ifndef fp_force_eval #ifndef fp_force_eval
#define fp_force_eval fp_force_eval #define fp_force_eval fp_force_eval
static inline void fp_force_eval(double x) static inline void fp_force_eval(double x)
{ {
volatile double y; volatile double y;
@ -57,7 +59,8 @@ static inline void fp_force_eval(double x)
#endif #endif
#ifndef fp_force_evall #ifndef fp_force_evall
#define fp_force_evall fp_force_evall #define fp_force_evall fp_force_evall
static inline void fp_force_evall(long double x) static inline void fp_force_evall(long double x)
{ {
volatile long double y; volatile long double y;
@ -65,66 +68,79 @@ static inline void fp_force_evall(long double x)
} }
#endif #endif
#define FORCE_EVAL(x) do { \ #define FORCE_EVAL(x) \
if (sizeof(x) == sizeof(float)) { \ do \
{ \
if(sizeof(x) == sizeof(float)) \
{ \
fp_force_evalf(x); \ fp_force_evalf(x); \
} else if (sizeof(x) == sizeof(double)) { \ } \
else if(sizeof(x) == sizeof(double)) \
{ \
fp_force_eval(x); \ fp_force_eval(x); \
} else { \ } \
else \
{ \
fp_force_evall(x); \ fp_force_evall(x); \
} \ } \
} while(0) } while(0)
#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i #define asuint(f) ((union {float _f; uint32_t _i; }){ f })._i
#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f #define asfloat(i) ((union {uint32_t _i; float _f; }){ i })._f
#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i #define asuint64(f) ((union {double _f; uint64_t _i; }){ f })._i
#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f #define asdouble(i) ((union {uint64_t _i; double _f; }){ i })._f
#define EXTRACT_WORDS(hi,lo,d) \ #define EXTRACT_WORDS(hi, lo, d) \
do { \ do \
{ \
uint64_t __u = asuint64(d); \ uint64_t __u = asuint64(d); \
(hi) = __u >> 32; \ (hi) = __u >> 32; \
(lo) = (uint32_t)__u; \ (lo) = (uint32_t)__u; \
} while (0) } while(0)
#define GET_HIGH_WORD(hi,d) \ #define GET_HIGH_WORD(hi, d) \
do { \ do \
{ \
(hi) = asuint64(d) >> 32; \ (hi) = asuint64(d) >> 32; \
} while (0) } while(0)
#define GET_LOW_WORD(lo,d) \ #define GET_LOW_WORD(lo, d) \
do { \ do \
{ \
(lo) = (uint32_t)asuint64(d); \ (lo) = (uint32_t)asuint64(d); \
} while (0) } while(0)
#define INSERT_WORDS(d,hi,lo) \ #define INSERT_WORDS(d, hi, lo) \
do { \ do \
(d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \ { \
} while (0) (d) = asdouble(((uint64_t)(hi) << 32) | (uint32_t)(lo)); \
} while(0)
#define SET_HIGH_WORD(d,hi) \ #define SET_HIGH_WORD(d, hi) \
INSERT_WORDS(d, hi, (uint32_t)asuint64(d)) INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
#define SET_LOW_WORD(d,lo) \ #define SET_LOW_WORD(d, lo) \
INSERT_WORDS(d, asuint64(d)>>32, lo) INSERT_WORDS(d, asuint64(d) >> 32, lo)
#define GET_FLOAT_WORD(w,d) \ #define GET_FLOAT_WORD(w, d) \
do { \ do \
{ \
(w) = asuint(d); \ (w) = asuint(d); \
} while (0) } while(0)
#define SET_FLOAT_WORD(d,w) \ #define SET_FLOAT_WORD(d, w) \
do { \ do \
{ \
(d) = asfloat(w); \ (d) = asfloat(w); \
} while (0) } while(0)
int __rem_pio2_large(double*,double*,int,int,int); int __rem_pio2_large(double*, double*, int, int, int);
int __rem_pio2(double,double*); int __rem_pio2(double, double*);
double __sin(double,double,int); double __sin(double, double, int);
double __cos(double,double); double __cos(double, double);
int __rem_pio2f(float,double*); int __rem_pio2f(float, double*);
float __sindf(double); float __sindf(double);
float __cosdf(double); float __cosdf(double);

View File

@ -5,11 +5,11 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include "exp_data.h"
#include "libm.h"
#include "pow_data.h"
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include "libm.h"
#include "exp_data.h"
#include "pow_data.h"
/* /*
Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53) Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53)
@ -33,7 +33,7 @@ static inline uint32_t top12(double x)
/* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about /* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about
additional 15 bits precision. IX is the bit representation of x, but additional 15 bits precision. IX is the bit representation of x, but
normalized in the subnormal range using the sign bit for the exponent. */ normalized in the subnormal range using the sign bit for the exponent. */
static inline double_t log_inline(uint64_t ix, double_t *tail) static inline double_t log_inline(uint64_t ix, double_t* tail)
{ {
/* double_t for better performance on targets with FLT_EVAL_METHOD==2. */ /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p; double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p;
@ -92,8 +92,7 @@ static inline double_t log_inline(uint64_t ix, double_t *tail)
lo4 = t2 - hi + arhi2; lo4 = t2 - hi + arhi2;
#endif #endif
/* p = log1p(r) - r - A[0]*r*r. */ /* p = log1p(r) - r - A[0]*r*r. */
p = (ar3 * (A[1] + r * A[2] + p = (ar3 * (A[1] + r * A[2] + ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));
ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));
lo = lo1 + lo2 + lo3 + lo4 + p; lo = lo1 + lo2 + lo3 + lo4 + p;
y = hi + lo; y = hi + lo;
*tail = hi - y + lo; *tail = hi - y + lo;
@ -125,7 +124,8 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
{ {
double_t scale, y; double_t scale, y;
if ((ki & 0x80000000) == 0) { if((ki & 0x80000000) == 0)
{
/* k > 0, the exponent of scale might have overflowed by <= 460. */ /* k > 0, the exponent of scale might have overflowed by <= 460. */
sbits -= 1009ull << 52; sbits -= 1009ull << 52;
scale = asdouble(sbits); scale = asdouble(sbits);
@ -137,20 +137,21 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
/* Note: sbits is signed scale. */ /* Note: sbits is signed scale. */
scale = asdouble(sbits); scale = asdouble(sbits);
y = scale + scale * tmp; y = scale + scale * tmp;
if (fabs(y) < 1.0) { if(fabs(y) < 1.0)
{
/* Round y to the right precision before scaling it into the subnormal /* Round y to the right precision before scaling it into the subnormal
range to avoid double rounding that can cause 0.5+E/2 ulp error where range to avoid double rounding that can cause 0.5+E/2 ulp error where
E is the worst-case ulp error outside the subnormal range. So this E is the worst-case ulp error outside the subnormal range. So this
is only useful if the goal is better than 1 ulp worst-case error. */ is only useful if the goal is better than 1 ulp worst-case error. */
double_t hi, lo, one = 1.0; double_t hi, lo, one = 1.0;
if (y < 0.0) if(y < 0.0)
one = -1.0; one = -1.0;
lo = scale - y + scale * tmp; lo = scale - y + scale * tmp;
hi = one + y; hi = one + y;
lo = one - hi + y + lo; lo = one - hi + y + lo;
y = eval_as_double(hi + lo) - one; y = eval_as_double(hi + lo) - one;
/* Fix the sign of 0. */ /* Fix the sign of 0. */
if (y == 0.0) if(y == 0.0)
y = asdouble(sbits & 0x8000000000000000); y = asdouble(sbits & 0x8000000000000000);
/* The underflow exception needs to be signaled explicitly. */ /* The underflow exception needs to be signaled explicitly. */
// NOTE(orca): removing special fp functions // NOTE(orca): removing special fp functions
@ -172,17 +173,19 @@ static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
double_t kd, z, r, r2, scale, tail, tmp; double_t kd, z, r, r2, scale, tail, tmp;
abstop = top12(x) & 0x7ff; abstop = top12(x) & 0x7ff;
if (predict_false(abstop - top12(0x1p-54) >= if(predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54)))
top12(512.0) - top12(0x1p-54))) { {
if (abstop - top12(0x1p-54) >= 0x80000000) { if(abstop - top12(0x1p-54) >= 0x80000000)
{
/* Avoid spurious underflow for tiny x. */ /* Avoid spurious underflow for tiny x. */
/* Note: 0 is common input. */ /* Note: 0 is common input. */
double_t one = WANT_ROUNDING ? 1.0 + x : 1.0; double_t one = WANT_ROUNDING ? 1.0 + x : 1.0;
return sign_bias ? -one : one; return sign_bias ? -one : one;
} }
if (abstop >= top12(1024.0)) { if(abstop >= top12(1024.0))
{
/* Note: inf and nan are already handled. */ /* Note: inf and nan are already handled. */
if (asuint64(x) >> 63) if(asuint64(x) >> 63)
return __math_uflow(sign_bias); return __math_uflow(sign_bias);
else else
return __math_oflow(sign_bias); return __math_oflow(sign_bias);
@ -223,7 +226,7 @@ static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
/* Without fma the worst case error is 0.25/N ulp larger. */ /* Without fma the worst case error is 0.25/N ulp larger. */
/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */
tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5); tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
if (predict_false(abstop == 0)) if(predict_false(abstop == 0))
return specialcase(tmp, sbits, ki); return specialcase(tmp, sbits, ki);
scale = asdouble(sbits); scale = asdouble(sbits);
/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
@ -236,13 +239,13 @@ static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
static inline int checkint(uint64_t iy) static inline int checkint(uint64_t iy)
{ {
int e = iy >> 52 & 0x7ff; int e = iy >> 52 & 0x7ff;
if (e < 0x3ff) if(e < 0x3ff)
return 0; return 0;
if (e > 0x3ff + 52) if(e > 0x3ff + 52)
return 2; return 2;
if (iy & ((1ULL << (0x3ff + 52 - e)) - 1)) if(iy & ((1ULL << (0x3ff + 52 - e)) - 1))
return 0; return 0;
if (iy & (1ULL << (0x3ff + 52 - e))) if(iy & (1ULL << (0x3ff + 52 - e)))
return 1; return 1;
return 2; return 2;
} }
@ -263,29 +266,30 @@ double pow(double x, double y)
iy = asuint64(y); iy = asuint64(y);
topx = top12(x); topx = top12(x);
topy = top12(y); topy = top12(y);
if (predict_false(topx - 0x001 >= 0x7ff - 0x001 || if(predict_false(topx - 0x001 >= 0x7ff - 0x001 || (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be))
(topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) { {
/* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0 /* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0
and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */ and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */
/* Special cases: (x < 0x1p-126 or inf or nan) or /* Special cases: (x < 0x1p-126 or inf or nan) or
(|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */ (|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */
if (predict_false(zeroinfnan(iy))) { if(predict_false(zeroinfnan(iy)))
if (2 * iy == 0) {
if(2 * iy == 0)
return issignaling_inline(x) ? x + y : 1.0; return issignaling_inline(x) ? x + y : 1.0;
if (ix == asuint64(1.0)) if(ix == asuint64(1.0))
return issignaling_inline(y) ? x + y : 1.0; return issignaling_inline(y) ? x + y : 1.0;
if (2 * ix > 2 * asuint64(INFINITY) || if(2 * ix > 2 * asuint64(INFINITY) || 2 * iy > 2 * asuint64(INFINITY))
2 * iy > 2 * asuint64(INFINITY))
return x + y; return x + y;
if (2 * ix == 2 * asuint64(1.0)) if(2 * ix == 2 * asuint64(1.0))
return 1.0; return 1.0;
if ((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63)) if((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63))
return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */ return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */
return y * y; return y * y;
} }
if (predict_false(zeroinfnan(ix))) { if(predict_false(zeroinfnan(ix)))
{
double_t x2 = x * x; double_t x2 = x * x;
if (ix >> 63 && checkint(iy) == 1) if(ix >> 63 && checkint(iy) == 1)
x2 = -x2; x2 = -x2;
/* Without the barrier some versions of clang hoist the 1/x2 and /* Without the barrier some versions of clang hoist the 1/x2 and
thus division by zero exception can be signaled spuriously. */ thus division by zero exception can be signaled spuriously. */
@ -294,33 +298,34 @@ double pow(double x, double y)
return iy >> 63 ? (1 / x2) : x2; return iy >> 63 ? (1 / x2) : x2;
} }
/* Here x and y are non-zero finite. */ /* Here x and y are non-zero finite. */
if (ix >> 63) { if(ix >> 63)
{
/* Finite x < 0. */ /* Finite x < 0. */
int yint = checkint(iy); int yint = checkint(iy);
if (yint == 0) if(yint == 0)
return __math_invalid(x); return __math_invalid(x);
if (yint == 1) if(yint == 1)
sign_bias = SIGN_BIAS; sign_bias = SIGN_BIAS;
ix &= 0x7fffffffffffffff; ix &= 0x7fffffffffffffff;
topx &= 0x7ff; topx &= 0x7ff;
} }
if ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) { if((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)
{
/* Note: sign_bias == 0 here because y is not odd. */ /* Note: sign_bias == 0 here because y is not odd. */
if (ix == asuint64(1.0)) if(ix == asuint64(1.0))
return 1.0; return 1.0;
if ((topy & 0x7ff) < 0x3be) { if((topy & 0x7ff) < 0x3be)
{
/* |y| < 2^-65, x^y ~= 1 + y*log(x). */ /* |y| < 2^-65, x^y ~= 1 + y*log(x). */
if (WANT_ROUNDING) if(WANT_ROUNDING)
return ix > asuint64(1.0) ? 1.0 + y : return ix > asuint64(1.0) ? 1.0 + y : 1.0 - y;
1.0 - y;
else else
return 1.0; return 1.0;
} }
return (ix > asuint64(1.0)) == (topy < 0x800) ? return (ix > asuint64(1.0)) == (topy < 0x800) ? __math_oflow(0) : __math_uflow(0);
__math_oflow(0) :
__math_uflow(0);
} }
if (topx == 0) { if(topx == 0)
{
/* Normalize subnormal x so exponent becomes negative. */ /* Normalize subnormal x so exponent becomes negative. */
ix = asuint64(x * 0x1p52); ix = asuint64(x * 0x1p52);
ix &= 0x7fffffffffffffff; ix &= 0x7fffffffffffffff;

View File

@ -9,12 +9,16 @@
#define POW_LOG_TABLE_BITS 7 #define POW_LOG_TABLE_BITS 7
#define POW_LOG_POLY_ORDER 8 #define POW_LOG_POLY_ORDER 8
extern const struct pow_log_data {
extern const struct pow_log_data
{
double ln2hi; double ln2hi;
double ln2lo; double ln2lo;
double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */ double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
/* Note: the pad field is unused, but allows slightly faster indexing. */ /* Note: the pad field is unused, but allows slightly faster indexing. */
struct { struct
{
double invc, pad, logc, logctail; double invc, pad, logc, logctail;
} tab[1 << POW_LOG_TABLE_BITS]; } tab[1 << POW_LOG_TABLE_BITS];
} __pow_log_data; } __pow_log_data;

View File

@ -3,31 +3,41 @@
double scalbn(double x, int n) double scalbn(double x, int n)
{ {
union {double f; uint64_t i;} u; union
{
double f;
uint64_t i;
} u;
double_t y = x; double_t y = x;
if (n > 1023) { if(n > 1023)
{
y *= 0x1p1023; y *= 0x1p1023;
n -= 1023; n -= 1023;
if (n > 1023) { if(n > 1023)
{
y *= 0x1p1023; y *= 0x1p1023;
n -= 1023; n -= 1023;
if (n > 1023) if(n > 1023)
n = 1023; n = 1023;
} }
} else if (n < -1022) { }
else if(n < -1022)
{
/* make sure final n < -53 to avoid double /* make sure final n < -53 to avoid double
rounding in the subnormal range */ rounding in the subnormal range */
y *= 0x1p-1022 * 0x1p53; y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53; n += 1022 - 53;
if (n < -1022) { if(n < -1022)
{
y *= 0x1p-1022 * 0x1p53; y *= 0x1p-1022 * 0x1p53;
n += 1022 - 53; n += 1022 - 53;
if (n < -1022) if(n < -1022)
n = -1022; n = -1022;
} }
} }
u.i = (uint64_t)(0x3ff+n)<<52; u.i = (uint64_t)(0x3ff + n) << 52;
x = y * u.f; x = y * u.f;
return x; return x;
} }

View File

@ -53,25 +53,31 @@ double sin(double x)
ix &= 0x7fffffff; ix &= 0x7fffffff;
/* |x| ~< pi/4 */ /* |x| ~< pi/4 */
if (ix <= 0x3fe921fb) { if(ix <= 0x3fe921fb)
if (ix < 0x3e500000) { /* |x| < 2**-26 */ {
if(ix < 0x3e500000)
{ /* |x| < 2**-26 */
/* raise inexact if x != 0 and underflow if subnormal*/ /* raise inexact if x != 0 and underflow if subnormal*/
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); FORCE_EVAL(ix < 0x00100000 ? x / 0x1p120f : x + 0x1p120f);
return x; return x;
} }
return __sin(x, 0.0, 0); return __sin(x, 0.0, 0);
} }
/* sin(Inf or NaN) is NaN */ /* sin(Inf or NaN) is NaN */
if (ix >= 0x7ff00000) if(ix >= 0x7ff00000)
return x - x; return x - x;
/* argument reduction needed */ /* argument reduction needed */
n = __rem_pio2(x, y); n = __rem_pio2(x, y);
switch (n&3) { switch(n & 3)
case 0: return __sin(y[0], y[1], 1); {
case 1: return __cos(y[0], y[1]); case 0:
case 2: return -__sin(y[0], y[1], 1); return __sin(y[0], y[1], 1);
case 1:
return __cos(y[0], y[1]);
case 2:
return -__sin(y[0], y[1], 1);
default: default:
return -__cos(y[0], y[1]); return -__cos(y[0], y[1]);
} }

View File

@ -18,10 +18,10 @@
/* Small multiples of pi/2 rounded to double precision. */ /* Small multiples of pi/2 rounded to double precision. */
static const double static const double
s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ s1pio2 = 1 * M_PI_2, /* 0x3FF921FB, 0x54442D18 */
s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ s2pio2 = 2 * M_PI_2, /* 0x400921FB, 0x54442D18 */
s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ s3pio2 = 3 * M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ s4pio2 = 4 * M_PI_2; /* 0x401921FB, 0x54442D18 */
float sinf(float x) float sinf(float x)
{ {
@ -33,26 +33,32 @@ float sinf(float x)
sign = ix >> 31; sign = ix >> 31;
ix &= 0x7fffffff; ix &= 0x7fffffff;
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ if(ix <= 0x3f490fda)
if (ix < 0x39800000) { /* |x| < 2**-12 */ { /* |x| ~<= pi/4 */
if(ix < 0x39800000)
{ /* |x| < 2**-12 */
/* raise inexact if x!=0 and underflow if subnormal */ /* raise inexact if x!=0 and underflow if subnormal */
FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); FORCE_EVAL(ix < 0x00800000 ? x / 0x1p120f : x + 0x1p120f);
return x; return x;
} }
return __sindf(x); return __sindf(x);
} }
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ if(ix <= 0x407b53d1)
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */ { /* |x| ~<= 5*pi/4 */
if (sign) if(ix <= 0x4016cbe3)
{ /* |x| ~<= 3pi/4 */
if(sign)
return -__cosdf(x + s1pio2); return -__cosdf(x + s1pio2);
else else
return __cosdf(x - s1pio2); return __cosdf(x - s1pio2);
} }
return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2)); return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
} }
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ if(ix <= 0x40e231d5)
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */ { /* |x| ~<= 9*pi/4 */
if (sign) if(ix <= 0x40afeddf)
{ /* |x| ~<= 7*pi/4 */
if(sign)
return __cosdf(x + s3pio2); return __cosdf(x + s3pio2);
else else
return -__cosdf(x - s3pio2); return -__cosdf(x - s3pio2);
@ -61,15 +67,19 @@ float sinf(float x)
} }
/* sin(Inf or NaN) is NaN */ /* sin(Inf or NaN) is NaN */
if (ix >= 0x7f800000) if(ix >= 0x7f800000)
return x - x; return x - x;
/* general argument reduction needed */ /* general argument reduction needed */
n = __rem_pio2f(x, &y); n = __rem_pio2f(x, &y);
switch (n&3) { switch(n & 3)
case 0: return __sindf(y); {
case 1: return __cosdf(y); case 0:
case 2: return __sindf(-y); return __sindf(y);
case 1:
return __cosdf(y);
case 2:
return __sindf(-y);
default: default:
return -__cosdf(y); return -__cosdf(y);
} }

View File

@ -1,24 +1,24 @@
#include <stdint.h>
#include <math.h>
#include "libm.h" #include "libm.h"
#include "sqrt_data.h" #include "sqrt_data.h"
#include <math.h>
#include <stdint.h>
#define FENV_SUPPORT 1 #define FENV_SUPPORT 1
/* returns a*b*2^-32 - e, with error 0 <= e < 1. */ /* returns a*b*2^-32 - e, with error 0 <= e < 1. */
static inline uint32_t mul32(uint32_t a, uint32_t b) static inline uint32_t mul32(uint32_t a, uint32_t b)
{ {
return (uint64_t)a*b >> 32; return (uint64_t)a * b >> 32;
} }
/* returns a*b*2^-64 - e, with error 0 <= e < 3. */ /* returns a*b*2^-64 - e, with error 0 <= e < 3. */
static inline uint64_t mul64(uint64_t a, uint64_t b) static inline uint64_t mul64(uint64_t a, uint64_t b)
{ {
uint64_t ahi = a>>32; uint64_t ahi = a >> 32;
uint64_t alo = a&0xffffffff; uint64_t alo = a & 0xffffffff;
uint64_t bhi = b>>32; uint64_t bhi = b >> 32;
uint64_t blo = b&0xffffffff; uint64_t blo = b & 0xffffffff;
return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32); return ahi * bhi + (ahi * blo >> 32) + (alo * bhi >> 32);
} }
double sqrt(double x) double sqrt(double x)
@ -28,13 +28,14 @@ double sqrt(double x)
/* special case handling. */ /* special case handling. */
ix = asuint64(x); ix = asuint64(x);
top = ix >> 52; top = ix >> 52;
if (predict_false(top - 0x001 >= 0x7ff - 0x001)) { if(predict_false(top - 0x001 >= 0x7ff - 0x001))
{
/* x < 0x1p-1022 or inf or nan. */ /* x < 0x1p-1022 or inf or nan. */
if (ix * 2 == 0) if(ix * 2 == 0)
return x; return x;
if (ix == 0x7ff0000000000000) if(ix == 0x7ff0000000000000)
return x; return x;
if (ix > 0x7ff0000000000000) if(ix > 0x7ff0000000000000)
return __math_invalid(x); return __math_invalid(x);
/* x is subnormal, normalize it. */ /* x is subnormal, normalize it. */
ix = asuint64(x * 0x1p52); ix = asuint64(x * 0x1p52);
@ -48,7 +49,8 @@ double sqrt(double x)
2^e is the exponent part of the result. */ 2^e is the exponent part of the result. */
int even = top & 1; int even = top & 1;
m = (ix << 11) | 0x8000000000000000; m = (ix << 11) | 0x8000000000000000;
if (even) m >>= 1; if(even)
m >>= 1;
top = (top + 0x3ff) >> 1; top = (top + 0x3ff) >> 1;
/* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) /* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4)
@ -111,7 +113,7 @@ double sqrt(double x)
i = (ix >> 46) % 128; i = (ix >> 46) % 128;
r = (uint32_t)__rsqrt_tab[i] << 16; r = (uint32_t)__rsqrt_tab[i] << 16;
/* |r sqrt(m) - 1| < 0x1.fdp-9 */ /* |r sqrt(m) - 1| < 0x1.fdp-9 */
s = mul32(m>>32, r); s = mul32(m >> 32, r);
/* |s/sqrt(m) - 1| < 0x1.fdp-9 */ /* |s/sqrt(m) - 1| < 0x1.fdp-9 */
d = mul32(s, r); d = mul32(s, r);
u = three - d; u = three - d;
@ -126,7 +128,7 @@ double sqrt(double x)
r = r << 32; r = r << 32;
s = mul64(m, r); s = mul64(m, r);
d = mul64(s, r); d = mul64(s, r);
u = (three<<32) - d; u = (three << 32) - d;
s = mul64(s, u); /* repr: 3.61 */ s = mul64(s, u); /* repr: 3.61 */
/* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */ /* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */
s = (s - 2) >> 9; /* repr: 12.52 */ s = (s - 2) >> 9; /* repr: 12.52 */
@ -138,19 +140,20 @@ double sqrt(double x)
we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */ we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */
uint64_t d0, d1, d2; uint64_t d0, d1, d2;
double y, t; double y, t;
d0 = (m << 42) - s*s; d0 = (m << 42) - s * s;
d1 = s - d0; d1 = s - d0;
d2 = d1 + s + 1; d2 = d1 + s + 1;
s += d1 >> 63; s += d1 >> 63;
s &= 0x000fffffffffffff; s &= 0x000fffffffffffff;
s |= top << 52; s |= top << 52;
y = asdouble(s); y = asdouble(s);
if (FENV_SUPPORT) { if(FENV_SUPPORT)
{
/* handle rounding modes and inexact exception: /* handle rounding modes and inexact exception:
only (s+1)^2 == 2^42 m case is exact otherwise only (s+1)^2 == 2^42 m case is exact otherwise
add a tiny value to cause the fenv effects. */ add a tiny value to cause the fenv effects. */
uint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000; uint64_t tiny = predict_false(d2 == 0) ? 0 : 0x0010000000000000;
tiny |= (d1^d2) & 0x8000000000000000; tiny |= (d1 ^ d2) & 0x8000000000000000;
t = asdouble(tiny); t = asdouble(tiny);
y = eval_as_double(y + t); y = eval_as_double(y + t);
} }

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