Merge pull request #111 from hartenfels/autoconf-flags

Fix Automake Flags and Matrix Struct Initializers
This commit is contained in:
Recep Aslantas
2019-11-26 22:45:41 +03:00
committed by GitHub
11 changed files with 180 additions and 49 deletions

View File

@@ -8,7 +8,7 @@
ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = -Wall \
-std=gnu99 \
-std=gnu11 \
-O3 \
-Wstrict-aliasing=2 \
-fstrict-aliasing \
@@ -21,7 +21,8 @@ libcglm_la_LDFLAGS = -no-undefined -version-info 0:1:0
checkLDFLAGS = -L./.libs \
-lm \
-lcglm
checkCFLAGS = -I./include
checkCFLAGS = $(AM_CFLAGS) \
-I./include
check_PROGRAMS = test/tests
TESTS = $(check_PROGRAMS)
@@ -150,7 +151,8 @@ test_tests_SOURCES=\
test/src/test_vec3.c \
test/src/test_mat3.c \
test/src/test_affine.c \
test/src/test_bezier.c
test/src/test_bezier.c \
test/src/test_struct.c
pkgconfig_DATA=cglm.pc

View File

@@ -131,6 +131,21 @@ glm_mul(T, R, modelMat);
glm_inv_tr(modelMat);
```
### Struct API
The struct API works as follows, note the `s` suffix on types, the `glms_` prefix on functions and the `GLMS_` prefix on constants:
```C
#include <cglm/struct.h>
mat4s mat = GLMS_MAT4_IDENTITY_INIT;
mat4s inv = glms_mat4_inv(mat);
```
Struct functions generally take their parameters as *values* and *return* their results, rather than taking pointers and writing to out parameters. That means your parameters can usually be `const`, if you're into that.
The types used are actually unions that allow access to the same data multiple ways. One of those ways involves anonymous structures, available since C11. MSVC also supports it for earlier C versions out of the box and GCC/Clang do if you enable `-fms-extensions`. To explicitly enable these anonymous structures, `#define CGLM_USE_ANONYMOUS_STRUCT` to `1`, to disable them, to `0`. For backward compatibility, you can also `#define CGLM_NO_ANONYMOUS_STRUCT` (value is irrelevant) to disable them. If you don't specify explicitly, cglm will do a best guess based on your compiler and the C version you're using.
## Build
### Unix (Autotools)

View File

@@ -10,6 +10,9 @@ AC_PREREQ([2.69])
AC_INIT([cglm], [0.6.1], [info@recp.me])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects serial-tests])
# Don't use the default cflags (-O2 -g), we set ours manually in Makefile.am.
: ${CFLAGS=""}
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/])
AC_CONFIG_HEADERS([config.h])

View File

@@ -38,12 +38,8 @@
#include "../mat3.h"
#include "vec3.h"
#define GLMS_MAT3_IDENTITY_INIT {1.0f, 0.0f, 0.0f, \
0.0f, 1.0f, 0.0f, \
0.0f, 0.0f, 1.0f}
#define GLMS_MAT3_ZERO_INIT {0.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 0.0f}
#define GLMS_MAT3_IDENTITY_INIT {GLM_MAT3_IDENTITY_INIT}
#define GLMS_MAT3_ZERO_INIT {GLM_MAT3_ZERO_INIT}
/* for C only */
#define GLMS_MAT3_IDENTITY ((mat3s)GLMS_MAT3_IDENTITY_INIT)

View File

@@ -53,15 +53,8 @@
#include "vec4.h"
#include "vec3.h"
#define GLMS_MAT4_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 0.0f, \
0.0f, 1.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 1.0f, 0.0f, \
0.0f, 0.0f, 0.0f, 1.0f}
#define GLMS_MAT4_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 0.0f, 0.0f, \
0.0f, 0.0f, 0.0f, 0.0f}
#define GLMS_MAT4_IDENTITY_INIT {GLM_MAT4_IDENTITY_INIT}
#define GLMS_MAT4_ZERO_INIT {GLM_MAT4_ZERO_INIT}
/* for C only */
#define GLMS_MAT4_IDENTITY ((mat4s)GLMS_MAT4_IDENTITY_INIT)

View File

@@ -62,7 +62,7 @@
* ----------------------------------------------------------------------------
*/
#define GLMS_QUAT_IDENTITY_INIT GLM_QUAT_IDENTITY_INIT
#define GLMS_QUAT_IDENTITY_INIT {GLM_QUAT_IDENTITY_INIT}
#define GLMS_QUAT_IDENTITY ((versors)GLMS_QUAT_IDENTITY_INIT)
/*!

View File

@@ -86,15 +86,15 @@
#include "../vec3.h"
#include "vec3-ext.h"
#define GLMS_VEC3_ONE_INIT {1.0f, 1.0f, 1.0f}
#define GLMS_VEC3_ZERO_INIT {0.0f, 0.0f, 0.0f}
#define GLMS_VEC3_ONE_INIT {GLM_VEC3_ONE_INIT}
#define GLMS_VEC3_ZERO_INIT {GLM_VEC3_ZERO_INIT}
#define GLMS_VEC3_ONE ((vec3s)GLMS_VEC3_ONE_INIT)
#define GLMS_VEC3_ZERO ((vec3s)GLMS_VEC3_ZERO_INIT)
#define GLMS_YUP ((vec3s){0.0f, 1.0f, 0.0f})
#define GLMS_ZUP ((vec3s){0.0f, 0.0f, 1.0f})
#define GLMS_XUP ((vec3s){1.0f, 0.0f, 0.0f})
#define GLMS_YUP ((vec3s){{0.0f, 1.0f, 0.0f}})
#define GLMS_ZUP ((vec3s){{0.0f, 0.0f, 1.0f}})
#define GLMS_XUP ((vec3s){{1.0f, 0.0f, 0.0f}})
/*!
* @brief init vec3 using vec4

View File

@@ -7,12 +7,12 @@
/*
Macros:
GLM_VEC4_ONE_INIT
GLM_VEC4_BLACK_INIT
GLM_VEC4_ZERO_INIT
GLM_VEC4_ONE
GLM_VEC4_BLACK
GLM_VEC4_ZERO
GLMS_VEC4_ONE_INIT
GLMS_VEC4_BLACK_INIT
GLMS_VEC4_ZERO_INIT
GLMS_VEC4_ONE
GLMS_VEC4_BLACK
GLMS_VEC4_ZERO
Functions:
CGLM_INLINE vec4s glms_vec4(vec3s v3, float last);
@@ -72,9 +72,9 @@
#include "../vec4.h"
#include "vec4-ext.h"
#define GLMS_VEC4_ONE_INIT {1.0f, 1.0f, 1.0f, 1.0f}
#define GLMS_VEC4_BLACK_INIT {0.0f, 0.0f, 0.0f, 1.0f}
#define GLMS_VEC4_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f}
#define GLMS_VEC4_ONE_INIT {GLM_VEC4_ONE_INIT}
#define GLMS_VEC4_BLACK_INIT {GLM_VEC4_BLACK_INIT}
#define GLMS_VEC4_ZERO_INIT {GLM_VEC4_ZERO_INIT}
#define GLMS_VEC4_ONE ((vec4s)GLM_VEC4_ONE_INIT)
#define GLMS_VEC4_BLACK ((vec4s)GLM_VEC4_BLACK_INIT)

View File

@@ -10,40 +10,67 @@
#include "types.h"
/*
* Anonymous structs are available since C11, but we'd like to be compatible
* with C99 and C89 too. So let's figure out if we should be using them or not.
* It's simply a convenience feature, you can e.g. build the library with
* anonymous structs and your application without them and they'll still be
* compatible, cglm doesn't use the anonymous structs internally.
*/
#ifndef CGLM_USE_ANONYMOUS_STRUCT
/* If the user doesn't explicitly specify if they want anonymous structs or
* not, then we'll try to intuit an appropriate choice. */
# if defined(CGLM_NO_ANONYMOUS_STRUCT)
/* The user has defined CGLM_NO_ANONYMOUS_STRUCT. This used to be the
* only #define governing the use of anonymous structs, so for backward
* compatibility, we still honor that choice and disable them. */
# define CGLM_USE_ANONYMOUS_STRUCT 0
# elif __STDC_VERSION__ >= 20112L || defined(_MSVC_VER)
/* We're compiling for C11 or this is the MSVC compiler. In either
* case, anonymous structs are available, so use them. */
# define CGLM_USE_ANONYMOUS_STRUCT 1
# else
/* Otherwise, we're presumably building for C99 or C89 and can't rely
* on anonymous structs being available. Turn them off. */
# define CGLM_USE_ANONYMOUS_STRUCT 0
# endif
#endif
typedef union vec2s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
vec2 raw;
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float x;
float y;
};
#endif
vec2 raw;
} vec2s;
typedef union vec3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
vec3 raw;
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float x;
float y;
float z;
};
#endif
vec3 raw;
} vec3s;
typedef union ivec3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
ivec3 raw;
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
int x;
int y;
int z;
};
#endif
ivec3 raw;
} ivec3s;
typedef union CGLM_ALIGN_IF(16) vec4s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
vec4 raw;
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float x;
float y;
@@ -51,11 +78,11 @@ typedef union CGLM_ALIGN_IF(16) vec4s {
float w;
};
#endif
vec4 raw;
} vec4s;
typedef union CGLM_ALIGN_IF(16) versors {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
vec4 raw;
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float x;
float y;
@@ -68,23 +95,24 @@ typedef union CGLM_ALIGN_IF(16) versors {
float real;
};
#endif
vec4 raw;
} versors;
typedef union mat3s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
mat3 raw;
vec3s col[3];
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float m00, m01, m02;
float m10, m11, m12;
float m20, m21, m22;
};
#endif
vec3s col[3];
mat3 raw;
} mat3s;
typedef union CGLM_ALIGN_MAT mat4s {
#ifndef CGLM_NO_ANONYMOUS_STRUCT
mat4 raw;
vec4s col[4];
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float m00, m01, m02, m03;
float m10, m11, m12, m13;
@@ -92,8 +120,6 @@ typedef union CGLM_ALIGN_MAT mat4s {
float m30, m31, m32, m33;
};
#endif
vec4s col[4];
mat4 raw;
} mat4s;
#endif /* cglm_types_struct_h */

71
test/src/test_struct.c Normal file
View File

@@ -0,0 +1,71 @@
#include "test_common.h"
TEST_IMPL(mat3s_identity_init) {
mat3s mat3_identity = GLMS_MAT3_IDENTITY_INIT;
mat3 mat3_identity_a = GLM_MAT3_IDENTITY_INIT;
test_assert_mat3_eq(mat3_identity.raw, mat3_identity_a);
TEST_SUCCESS
}
TEST_IMPL(mat3s_zero_init) {
mat3s mat3_zero = GLMS_MAT3_ZERO_INIT;
mat3 mat3_zero_a = GLM_MAT3_ZERO_INIT;
test_assert_mat3_eq(mat3_zero.raw, mat3_zero_a);
TEST_SUCCESS
}
TEST_IMPL(mat4s_identity_init) {
mat4s mat4_identity = GLMS_MAT4_IDENTITY_INIT;
mat4 mat4_identity_a = GLM_MAT4_IDENTITY_INIT;
test_assert_mat4_eq(mat4_identity.raw, mat4_identity_a);
TEST_SUCCESS
}
TEST_IMPL(mat4s_zero_init) {
mat4s mat4_zero = GLMS_MAT4_ZERO_INIT;
mat4 mat4_zero_a = GLM_MAT4_ZERO_INIT;
test_assert_mat4_eq(mat4_zero.raw, mat4_zero_a);
TEST_SUCCESS
}
TEST_IMPL(quats_zero_init) {
versors quat_zero = GLMS_QUAT_IDENTITY_INIT;
versor quat_zero_a = GLM_QUAT_IDENTITY_INIT;
test_assert_quat_eq(quat_zero.raw, quat_zero_a);
TEST_SUCCESS
}
TEST_IMPL(vec3s_one_init) {
vec3s vec3_one = GLMS_VEC3_ONE_INIT;
vec3 vec3_one_a = GLM_VEC3_ONE_INIT;
test_assert_vec3_eq(vec3_one.raw, vec3_one_a);
TEST_SUCCESS
}
TEST_IMPL(vec3s_zero_init) {
vec3s vec3_zero = GLMS_VEC3_ZERO_INIT;
vec3 vec3_zero_a = GLM_VEC3_ZERO_INIT;
test_assert_vec3_eq(vec3_zero.raw, vec3_zero_a);
TEST_SUCCESS
}
TEST_IMPL(vec4s_black_init) {
vec4s vec4_black = GLMS_VEC4_BLACK_INIT;
vec4 vec4_black_a = GLM_VEC4_BLACK_INIT;
test_assert_vec4_eq(vec4_black.raw, vec4_black_a);
TEST_SUCCESS
}
TEST_IMPL(vec4s_one_init) {
vec4s vec4_one = GLMS_VEC4_ONE_INIT;
vec4 vec4_one_a = GLM_VEC4_ONE_INIT;
test_assert_vec4_eq(vec4_one.raw, vec4_one_a);
TEST_SUCCESS
}
TEST_IMPL(vec4s_zero_init) {
vec4s vec4_zero = GLMS_VEC4_ZERO_INIT;
vec4 vec4_zero_a = GLM_VEC4_ZERO_INIT;
test_assert_vec4_eq(vec4_zero.raw, vec4_zero_a);
TEST_SUCCESS
}

View File

@@ -504,6 +504,19 @@ TEST_DECLARE(glmc_vec4_fract)
TEST_DECLARE(glmc_vec4_hadd)
TEST_DECLARE(glmc_vec4_sqrt)
/* structs */
TEST_DECLARE(mat3s_identity_init)
TEST_DECLARE(mat3s_zero_init)
TEST_DECLARE(mat4s_identity_init)
TEST_DECLARE(mat4s_zero_init)
TEST_DECLARE(quats_zero_init)
TEST_DECLARE(vec3s_one_init)
TEST_DECLARE(vec3s_zero_init)
TEST_DECLARE(vec4s_black_init)
TEST_DECLARE(vec4s_one_init)
TEST_DECLARE(vec4s_zero_init)
/*****************************************************************************/
TEST_LIST {
@@ -996,6 +1009,18 @@ TEST_LIST {
TEST_ENTRY(glmc_vec4_fract)
TEST_ENTRY(glmc_vec4_hadd)
TEST_ENTRY(glmc_vec4_sqrt)
/* structs */
TEST_ENTRY(mat3s_identity_init)
TEST_ENTRY(mat3s_zero_init)
TEST_ENTRY(mat4s_identity_init)
TEST_ENTRY(mat4s_zero_init)
TEST_ENTRY(quats_zero_init)
TEST_ENTRY(vec3s_one_init)
TEST_ENTRY(vec3s_zero_init)
TEST_ENTRY(vec4s_black_init)
TEST_ENTRY(vec4s_one_init)
TEST_ENTRY(vec4s_zero_init)
};
#endif /* tests_h */