adding simd sse and sse2 versions of drawmodelex and drawmesh and also the math functions that thees two function uses this should improve the performance slitly

This commit is contained in:
Abdelilah-Majid 2022-01-04 15:16:36 +01:00
parent 2116a98745
commit 361f586dfe
5 changed files with 786 additions and 3 deletions

View File

@ -199,9 +199,9 @@ endif
# Define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# On RPI OpenGL ES 2.0 must be used
@ -279,6 +279,11 @@ endif
# -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing)
CFLAGS = -Wall -D_DEFAULT_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing $(CUSTOM_CFLAGS)
simd_flags = -Dsse_sse2 -msse -msse2 #flags for simd sse and sse2
#simd_flags =
CFLAGS += $(simd_flags)
ifneq ($(RAYLIB_CONFIG_FLAGS), NONE)
CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS)
endif

View File

@ -79,6 +79,7 @@
#define RAYLIB_H
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#include <simd.h>
#define RAYLIB_VERSION "4.1-dev"
@ -1410,6 +1411,7 @@ RLAPI BoundingBox GetModelBoundingBox(Model model);
// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelEx_simd(Model model[], Vector3_simd position, Vector3_simd rotationAxis, __simd_f rotationAngle, Vector3_simd scale, Color_float_simd tint);// Draw a model with extended parameters using sse and sse2 simd instruction set
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
@ -1422,6 +1424,7 @@ RLAPI void UploadMesh(Mesh *mesh, bool dynamic);
RLAPI void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
RLAPI void DrawMesh_simd(Mesh mesh, Material material, Matrix transform);// Draw a 3d mesh with material and transform in simd
RLAPI void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits

View File

@ -47,6 +47,9 @@
#ifndef RAYMATH_H
#define RAYMATH_H
#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE)
#error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory"
#endif
@ -154,7 +157,19 @@ typedef struct float16 {
float v[16];
} float16;
//color structs
#if !defined(RL_COLOR_TYPE)
typedef struct Color {
unsigned char r, g, b, a;
}Color;
#define RL_COLOR_TYPE
#endif
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), fminf(), fmaxf(), fabs()
#include <simd.h>
//----------------------------------------------------------------------------------
// Module Functions Definition - Utils math
@ -1847,4 +1862,307 @@ RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat)
return result;
}
//simd math functions
RMAPI Color_float_simd Color_to_Color_float_simd(Color color[]){
Color_float_simd result = {0};
for(unsigned int i=0; i < __simd_32_size; i++){
((float*)&result.r)[i] = color[i].r;
((float*)&result.g)[i] = color[i].g;
((float*)&result.b)[i] = color[i].b;
((float*)&result.a)[i] = color[i].a;
}
return result;
}
RMAPI Color *Color_float_simd_to_Color(Color_float_simd color_simd){
Color *result = malloc(sizeof(Color) * __simd_32_size);
for(unsigned int i=0; i < __simd_32_size; i++){
result[i].r = ((float*)&color_simd.r)[i];
result[i].g = ((float*)&color_simd.g)[i];
result[i].b = ((float*)&color_simd.b)[i];
result[i].a = ((float*)&color_simd.a)[i];
}
return result;
}
RMAPI Matrix_simd Matrix_to_Matrix_simd(Matrix matrix[]){
Matrix_simd result = {0};
for(unsigned int i=0; i < __simd_32_size; i++){
((float*)&result.m0)[i] = matrix[i].m0;
((float*)&result.m1)[i] = matrix[i].m1;
((float*)&result.m2)[i] = matrix[i].m2;
((float*)&result.m3)[i] = matrix[i].m3;
((float*)&result.m4)[i] = matrix[i].m4;
((float*)&result.m5)[i] = matrix[i].m5;
((float*)&result.m6)[i] = matrix[i].m6;
((float*)&result.m7)[i] = matrix[i].m7;
((float*)&result.m8)[i] = matrix[i].m8;
((float*)&result.m9)[i] = matrix[i].m9;
((float*)&result.m10)[i] = matrix[i].m10;
((float*)&result.m11)[i] = matrix[i].m11;
((float*)&result.m12)[i] = matrix[i].m12;
((float*)&result.m13)[i] = matrix[i].m13;
((float*)&result.m14)[i] = matrix[i].m14;
((float*)&result.m15)[i] = matrix[i].m15;
}
return result;
}
RMAPI Matrix *Matrix_simd_to_Matrix(Matrix_simd matrix_simd){
Matrix *result = malloc(sizeof(Matrix) * __simd_32_size);
for(unsigned int i=0; i < __simd_32_size; i++){
result[i].m0 = ((float*)&matrix_simd.m0)[i];
result[i].m1 = ((float*)&matrix_simd.m1)[i];
result[i].m2 = ((float*)&matrix_simd.m2)[i];
result[i].m3 = ((float*)&matrix_simd.m3)[i];
result[i].m4 = ((float*)&matrix_simd.m4)[i];
result[i].m5 = ((float*)&matrix_simd.m5)[i];
result[i].m6 = ((float*)&matrix_simd.m6)[i];
result[i].m7 = ((float*)&matrix_simd.m7)[i];
result[i].m8 = ((float*)&matrix_simd.m8)[i];
result[i].m9 = ((float*)&matrix_simd.m9)[i];
result[i].m10 = ((float*)&matrix_simd.m10)[i];
result[i].m11 = ((float*)&matrix_simd.m11)[i];
result[i].m12 = ((float*)&matrix_simd.m12)[i];
result[i].m13 = ((float*)&matrix_simd.m13)[i];
result[i].m14 = ((float*)&matrix_simd.m14)[i];
result[i].m15 = ((float*)&matrix_simd.m15)[i];
}
return result;
}
RMAPI Matrix_simd MatrixTranslate_simd(__simd_f x, __simd_f y, __simd_f z)
{
Matrix_simd result = { __simd_f_set_ps1(1.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), x,
__simd_f_set_ps1(0.0f), __simd_f_set_ps1(1.0f), __simd_f_set_ps1(0.0f), y,
__simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(1.0f), z,
__simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(1.0f) };
return result;
}
RMAPI Matrix_simd MatrixScale_simd(__simd_f x, __simd_f y, __simd_f z)
{
Matrix_simd result = { x, __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f),
__simd_f_set_ps1(0.0f), y, __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f),
__simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), z, __simd_f_set_ps1(0.0f),
__simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(0.0f), __simd_f_set_ps1(1.0f) };
/*
Matrix_simd result = {0};
for(unsigned int i=0; i < arr_size; i++){
((float*)&result.m0)[i] = x[i];
((float*)&result.m5)[i] = y[i];
((float*)&result.m10)[i] = z[i];
}
result.m1 = __simd_f_set_ps1(0.0f);
result.m2 = __simd_f_set_ps1(0.0f);
result.m3 = __simd_f_set_ps1(0.0f);
result.m4 = __simd_f_set_ps1(0.0f);
result.m6 = __simd_f_set_ps1(0.0f);
result.m7 = __simd_f_set_ps1(0.0f);
result.m8 = __simd_f_set_ps1(0.0f);
result.m9 = __simd_f_set_ps1(0.0f);
result.m11 = __simd_f_set_ps1(0.0f);
result.m12 = __simd_f_set_ps1(0.0f);
result.m13 = __simd_f_set_ps1(0.0f);
result.m14 = __simd_f_set_ps1(0.0f);
result.m15 = __simd_f_set_ps1(1.0f);
*/
return result;
}
RMAPI Matrix_simd MatrixRotate_simd(Vector3_simd axis, __simd_f angle)
{
Matrix_simd result = { 0 };
__simd_f x = axis.x, y = axis.y, z = axis.z;
__simd_f lengthSquared = __simd_f_add_ps(__simd_f_add_ps(__simd_f_mul_ps(x, x),
__simd_f_mul_ps(y, y)),
__simd_f_mul_ps(z, z));
__simd_f if_0 = __simd_f_and_ps(
__simd_f_and_ps(
__simd_f_cmpare_not_equal_ps(lengthSquared, __simd_f_set_ps1(1.0f)),
__simd_f_cmpare_not_equal_ps(lengthSquared, __simd_f_set_ps1(0.0f))),
__simd_f_set_ps1(1.0f));
lengthSquared = lengthSquared * if_0 + 1 * (__simd_f_not_and_ps(if_0, __simd_f_set_ps1(1.0f)));
__simd_f ilength = __simd_f_reciprocal_sqrt_ps(lengthSquared)*if_0+
0*(__simd_f_not_and_ps(if_0, __simd_f_set_ps1(1.0f)));
x = (__simd_f_mul_ps(x, ilength)*if_0)+x*(__simd_f_not_and_ps(if_0, __simd_f_set_ps1(1.0f)));
y = (__simd_f_mul_ps(y, ilength)*if_0)+y*(__simd_f_not_and_ps(if_0, __simd_f_set_ps1(1.0f)));
z = (__simd_f_mul_ps(z, ilength)*if_0)+z*(__simd_f_not_and_ps(if_0, __simd_f_set_ps1(1.0f)));
__simd_f sinres = { 0 };
__simd_f cosres = { 0 };
for (unsigned int i = 0; i < __simd_32_size; i++) {
((float*)&sinres)[i] = sinf(((float*)&angle)[i]);
((float*)&cosres)[i] = cosf(((float*)&angle)[i]);
}
__simd_f t = __simd_f_sub_ps(__simd_f_set_ps1(1.0f), cosres);
/*
result.m0 = x*x*t + cosres;
result.m1 = y*x*t + z*sinres;
result.m2 = z*x*t - y*sinres;
result.m3 = 0.0f;
result.m4 = x*y*t - z*sinres;
result.m5 = y*y*t + cosres;
result.m6 = z*y*t + x*sinres;
result.m7 = 0.0f;
result.m8 = x*z*t + y*sinres;
result.m9 = y*z*t - x*sinres;
result.m10 = z*z*t + cosres;
result.m11 = 0.0f;
result.m12 = 0.0f;
result.m13 = 0.0f;
result.m14 = 0.0f;
result.m15 = 1.0f;
*/
result.m0 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(x, x), t), cosres);
result.m1 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(y, x), t), __simd_f_mul_ps(z, sinres));
result.m2 = __simd_f_sub_ps(__simd_f_mul_ps(__simd_f_mul_ps(z, x), t), __simd_f_mul_ps(y, sinres));
result.m3 = __simd_f_set_ps1(0.0f);
result.m4 = __simd_f_sub_ps(__simd_f_mul_ps(__simd_f_mul_ps(x, y), t), __simd_f_mul_ps(z, sinres));
result.m5 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(y, y), t), cosres);
result.m6 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(z, y), t), __simd_f_mul_ps(x, sinres));
result.m7 = __simd_f_set_ps1(0.0f);
result.m8 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(x, z), t), __simd_f_mul_ps(y, sinres));
result.m9 = __simd_f_sub_ps(__simd_f_mul_ps(__simd_f_mul_ps(y, z), t), __simd_f_mul_ps(x, sinres));
result.m10 = __simd_f_add_ps(__simd_f_mul_ps(__simd_f_mul_ps(z, z), t), cosres);
result.m11 = __simd_f_set_ps1(0.0f);
result.m12 = __simd_f_set_ps1(0.0f);
result.m13 = __simd_f_set_ps1(0.0f);
result.m14 = __simd_f_set_ps1(0.0f);
result.m15 = __simd_f_set_ps1(1.0f);
return result;
}
RMAPI Matrix_simd MatrixMultiply_simd(Matrix_simd left, Matrix_simd right)
{
Matrix_simd result = { 0 };
result.m0 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m0, right.m0), __simd_f_mul_ps(left.m1, right.m4)),
__simd_f_add_ps(__simd_f_mul_ps(left.m2, right.m8), __simd_f_mul_ps(left.m3, right.m12)));
result.m1 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m0, right.m1), __simd_f_mul_ps(left.m1, right.m5)),
__simd_f_add_ps(__simd_f_mul_ps(left.m2, right.m9), __simd_f_mul_ps(left.m3, right.m13)));
result.m2 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m0, right.m2), __simd_f_mul_ps(left.m1, right.m6)),
__simd_f_add_ps(__simd_f_mul_ps(left.m2, right.m10), __simd_f_mul_ps(left.m3, right.m14)));
result.m3 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m0, right.m3), __simd_f_mul_ps(left.m1, right.m7)),
__simd_f_add_ps(__simd_f_mul_ps(left.m2, right.m11), __simd_f_mul_ps(left.m3, right.m15)));
result.m4 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m4, right.m0), __simd_f_mul_ps(left.m5, right.m4)),
__simd_f_add_ps(__simd_f_mul_ps(left.m6, right.m8), __simd_f_mul_ps(left.m7, right.m12)));
result.m5 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m4, right.m1), __simd_f_mul_ps(left.m5, right.m5)),
__simd_f_add_ps(__simd_f_mul_ps(left.m6, right.m9), __simd_f_mul_ps(left.m7, right.m13)));
result.m6 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m4, right.m2), __simd_f_mul_ps(left.m5, right.m6)),
__simd_f_add_ps(__simd_f_mul_ps(left.m6, right.m10), __simd_f_mul_ps(left.m7, right.m14)));
result.m7 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m4, right.m3), __simd_f_mul_ps(left.m5, right.m7)),
__simd_f_add_ps(__simd_f_mul_ps(left.m6, right.m11), __simd_f_mul_ps(left.m7, right.m15)));
result.m8 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m8, right.m0), __simd_f_mul_ps(left.m9, right.m4)),
__simd_f_add_ps(__simd_f_mul_ps(left.m10, right.m8), __simd_f_mul_ps(left.m11, right.m12)));
result.m9 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m8, right.m1), __simd_f_mul_ps(left.m9, right.m5)),
__simd_f_add_ps(__simd_f_mul_ps(left.m10, right.m9), __simd_f_mul_ps(left.m11, right.m13)));
result.m10 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m8, right.m2), __simd_f_mul_ps(left.m9, right.m6)),
__simd_f_add_ps(__simd_f_mul_ps(left.m10, right.m10), __simd_f_mul_ps(left.m11, right.m14)));
result.m11 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m8, right.m3), __simd_f_mul_ps(left.m9, right.m7)),
__simd_f_add_ps(__simd_f_mul_ps(left.m10, right.m11), __simd_f_mul_ps(left.m11, right.m15)));
result.m12 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m12, right.m0), __simd_f_mul_ps(left.m13, right.m4)),
__simd_f_add_ps(__simd_f_mul_ps(left.m14, right.m8), __simd_f_mul_ps(left.m15, right.m12)));
result.m13 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m12, right.m1), __simd_f_mul_ps(left.m13, right.m5)),
__simd_f_add_ps(__simd_f_mul_ps(left.m14, right.m9), __simd_f_mul_ps(left.m15, right.m13)));
result.m14 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m12, right.m2), __simd_f_mul_ps(left.m13, right.m6)),
__simd_f_add_ps(__simd_f_mul_ps(left.m14, right.m10), __simd_f_mul_ps(left.m15, right.m14)));
result.m15 = __simd_f_add_ps(
__simd_f_add_ps(__simd_f_mul_ps(left.m12, right.m3), __simd_f_mul_ps(left.m13, right.m7)),
__simd_f_add_ps(__simd_f_mul_ps(left.m14, right.m11), __simd_f_mul_ps(left.m15, right.m15)));
return result;
}
#endif // RAYMATH_H

View File

@ -57,6 +57,7 @@
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: memcmp(), strlen()
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), fabsf()
#include <simd.h>
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
#define TINYOBJ_MALLOC RL_MALLOC
@ -1372,7 +1373,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
// Draw mesh
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, 0);
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, mesh.indices);
else rlDrawVertexArray(0, mesh.vertexCount);
}
@ -1403,6 +1404,257 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
#endif
}
// Draw a 3d mesh with material and transform in simd
void DrawMesh_simd(Mesh mesh, Material material, Matrix transform)
{
#if defined(GRAPHICS_API_OPENGL_11)
#define GL_VERTEX_ARRAY 0x8074
#define GL_NORMAL_ARRAY 0x8075
#define GL_COLOR_ARRAY 0x8076
#define GL_TEXTURE_COORD_ARRAY 0x8078
rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id);
rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices);
rlEnableStatePointer(GL_TEXTURE_COORD_ARRAY, mesh.texcoords);
rlEnableStatePointer(GL_NORMAL_ARRAY, mesh.normals);
rlEnableStatePointer(GL_COLOR_ARRAY, mesh.colors);
rlPushMatrix();
rlMultMatrixf(MatrixToFloat(transform));
rlColor4ub(material.maps[MATERIAL_MAP_DIFFUSE].color.r,
material.maps[MATERIAL_MAP_DIFFUSE].color.g,
material.maps[MATERIAL_MAP_DIFFUSE].color.b,
material.maps[MATERIAL_MAP_DIFFUSE].color.a);
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, mesh.indices);
else rlDrawVertexArray(0, mesh.vertexCount);
rlPopMatrix();
rlDisableStatePointer(GL_VERTEX_ARRAY);
rlDisableStatePointer(GL_TEXTURE_COORD_ARRAY);
rlDisableStatePointer(GL_NORMAL_ARRAY);
rlDisableStatePointer(GL_COLOR_ARRAY);
rlDisableTexture();
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Bind shader program
rlEnableShader(material.shader.id);
// Send required data to shader (matrices, values)
//-----------------------------------------------------
// Upload to shader material.colDiffuse
if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
{
__simd_f values = {
material.maps[MATERIAL_MAP_DIFFUSE].color.r,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.g,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.b,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.a///255.0f
};
__simd_f divide_by = __simd_f_set_ps1(255.0f);
values = values / divide_by;
float values_float[4] = {
((float*)&values)[0],///255.0f,
((float*)&values)[1],///255.0f,
((float*)&values)[2],///255.0f,
((float*)&values)[3]///255.0f
};
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values_float, SHADER_UNIFORM_VEC4, 1);
}
// Upload to shader material.colSpecular (if location available)
if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
{
__simd_f values = {
material.maps[MATERIAL_MAP_DIFFUSE].color.r,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.g,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.b,///255.0f,
material.maps[MATERIAL_MAP_DIFFUSE].color.a///255.0f
};
__simd_f divide_by = __simd_f_set_ps1(255.0f);
values = values / divide_by;
float values_float[4] = {
((float*)&values)[0],///255.0f,
((float*)&values)[1],///255.0f,
((float*)&values)[2],///255.0f,
((float*)&values)[3]///255.0f
};
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values_float, SHADER_UNIFORM_VEC4, 1);
}
// Get a copy of current matrices to work with,
// just in case stereo render is required and we need to modify them
// NOTE: At this point the modelview matrix just contains the view matrix (camera)
// That's because BeginMode3D() sets it and there is no model-drawing function
// that modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matModel = MatrixIdentity();
Matrix matView = rlGetMatrixModelview();
Matrix matModelView = MatrixIdentity();
Matrix matProjection = rlGetMatrixProjection();
// Upload view and projection matrices (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
// Model transformation matrix is send to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transform);
// Accumulate several model transformations:
// transform: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
matModel = MatrixMultiply(transform, rlGetMatrixTransform());
// Get model-view matrix
matModelView = MatrixMultiply(matModel, matView);
// Upload model normal matrix (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
//-----------------------------------------------------
// Bind active texture maps (if available)
for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
if (material.maps[i].texture.id > 0)
{
// Select current shader texture slot
rlActiveTextureSlot(i);
// Enable texture for active slot
if ((i == MATERIAL_MAP_IRRADIANCE) ||
(i == MATERIAL_MAP_PREFILTER) ||
(i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
else rlEnableTexture(material.maps[i].texture.id);
rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
}
}
// Try binding vertex array objects (VAO)
// or use VBOs if not possible
if (!rlEnableVertexArray(mesh.vaoId))
{
// Bind mesh VBO data: vertex position (shader-location = 0)
rlEnableVertexBuffer(mesh.vboId[0]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
rlEnableVertexBuffer(mesh.vboId[1]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
{
// Bind mesh VBO data: vertex normals (shader-location = 2)
rlEnableVertexBuffer(mesh.vboId[2]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
}
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
{
if (mesh.vboId[3] != 0)
{
rlEnableVertexBuffer(mesh.vboId[3]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
}
else
{
// Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support
float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
rlSetVertexAttributeDefault(material.shader.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC2, 4);
rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
}
}
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
{
rlEnableVertexBuffer(mesh.vboId[4]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
}
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
{
rlEnableVertexBuffer(mesh.vboId[5]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
}
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
}
int eyeCount = 1;
if (rlIsStereoRenderEnabled()) eyeCount = 2;
for (int eye = 0; eye < eyeCount; eye++)
{
// Calculate model-view-projection matrix (MVP)
Matrix matModelViewProjection = MatrixIdentity();
if (eyeCount == 1) matModelViewProjection = MatrixMultiply(matModelView, matProjection);
else
{
// Setup current eye viewport (half screen width)
rlViewport(eye*rlGetFramebufferWidth()/2, 0, rlGetFramebufferWidth()/2, rlGetFramebufferHeight());
matModelViewProjection = MatrixMultiply(MatrixMultiply(matModelView, rlGetMatrixViewOffsetStereo(eye)), rlGetMatrixProjectionStereo(eye));
}
// Send combined model-view-projection matrix to shader
rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
// Draw mesh
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, mesh.indices);
else rlDrawVertexArray(0, mesh.vertexCount);
}
// Unbind all binded texture maps
for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
// Select current shader texture slot
rlActiveTextureSlot(i);
// Disable texture for active slot
if ((i == MATERIAL_MAP_IRRADIANCE) ||
(i == MATERIAL_MAP_PREFILTER) ||
(i == MATERIAL_MAP_CUBEMAP)) rlDisableTextureCubemap();
else rlDisableTexture();
}
// Disable all possible vertex array objects (or VBOs)
rlDisableVertexArray();
rlDisableVertexBuffer();
rlDisableVertexBufferElement();
// Disable shader program
rlDisableShader();
// Restore rlgl internal modelview and projection matrices
rlSetMatrixModelview(matView);
rlSetMatrixProjection(matProjection);
#endif
}
// Draw multiple mesh instances with material and different transforms
void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances)
{
@ -3295,6 +3547,117 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
}
}
// Draw a model with extended parameters using sse and sse2 simd instruction set
void DrawModelEx_simd(Model model[], Vector3_simd position, Vector3_simd rotationAxis, __simd_f rotationAngle, Vector3_simd scale, Color_float_simd tint)
{
// Calculate transformation matrix from function parameters
// Get transform matrix (rotation -> scale -> translation)
Matrix_simd matScale = MatrixScale_simd(scale.x, scale.y, scale.z);
Matrix_simd matRotation = MatrixRotate_simd(rotationAxis, __simd_f_mul_ps(rotationAngle, __simd_f_set_ps1(DEG2RAD)));
Matrix_simd matTranslation = MatrixTranslate_simd(position.x, position.y, position.z);
Matrix_simd matTransform = MatrixMultiply_simd(MatrixMultiply_simd(matScale, matRotation), matTranslation);
// Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
Matrix model_transform[__simd_32_size] = {0};
for(unsigned int i=0; i< __simd_32_size; i++){
model_transform[i] = model[i].transform;
}
Matrix_simd model_transform_simd = Matrix_to_Matrix_simd(model_transform);
model_transform_simd = MatrixMultiply_simd(model_transform_simd, matTransform);
Matrix *model_transform_ptr = Matrix_simd_to_Matrix(model_transform_simd);
for(unsigned int i=0; i<__simd_32_size; i++)
model[i].transform = model_transform_ptr[i];
Color color_arr[__simd_32_size] = {0};
Color_float_simd colorTint = {WHITE.r, WHITE.g, WHITE.b, WHITE.a};
for(unsigned int i=0; i < __simd_32_size; i++){
unsigned int j_max = floorf((float)model[i].meshCount/(float)__simd_32_size);
for (unsigned int j = 0; j < j_max; j++)
{
for(unsigned int a=0; a < __simd_32_size; a++){
color_arr[a] = model[i].materials[model[i].
meshMaterial[j*__simd_32_size+a]].maps[MATERIAL_MAP_DIFFUSE].color;
}
Color_float_simd color_simd = Color_to_Color_float_simd(color_arr);
colorTint.r = (((color_simd.r/255.0)*(tint.r/255.0))*255.0f);
colorTint.g = (((color_simd.g/255.0)*(tint.g/255.0))*255.0f);
colorTint.b = (((color_simd.b/255.0)*(tint.b/255.0))*255.0f);
colorTint.a = (((color_simd.a/255.0)*(tint.a/255.0))*255.0f);
Color * color_tint= Color_float_simd_to_Color(colorTint);
for(unsigned int a=0; a<__simd_32_size; a++){
model[i].materials[model[i].meshMaterial[j*__simd_32_size+a]].
maps[MATERIAL_MAP_DIFFUSE].color = color_tint[a];
DrawMesh_simd(model[i].meshes[j*__simd_32_size+a], model[i].
materials[model[i].meshMaterial[j*__simd_32_size+a]], model[i].transform);
model[i].materials[model[i].meshMaterial[j*__simd_32_size+a]].
maps[MATERIAL_MAP_DIFFUSE].color = color_arr[a];
}
}
unsigned int j = {0};
j = j_max * __simd_32_size;
unsigned int j_max_2 = {0};
j_max_2 = model[i].meshCount;
if(j_max_2 - j){
for(unsigned int a=0; a < (j_max_2 - j); a++){
color_arr[a] = model[i].materials[model[i].
meshMaterial[j+a]].maps[MATERIAL_MAP_DIFFUSE].color;
}
Color_float_simd color_simd = Color_to_Color_float_simd(color_arr);
colorTint.r = (((color_simd.r/255.0)*(tint.r/255.0))*255.0f);
colorTint.g = (((color_simd.g/255.0)*(tint.g/255.0))*255.0f);
colorTint.b = (((color_simd.b/255.0)*(tint.b/255.0))*255.0f);
colorTint.a = (((color_simd.a/255.0)*(tint.a/255.0))*255.0f);
Color * color_tint= Color_float_simd_to_Color(colorTint);
for(unsigned int a=0; a < (j_max_2-j); a++){
model[i].materials[model[i].meshMaterial[j+a]].
maps[MATERIAL_MAP_DIFFUSE].color = color_tint[a];
DrawMesh_simd(model[i].meshes[j+a], model[i].
materials[model[i].meshMaterial[j+a]], model[i].transform);
model[i].materials[model[i].meshMaterial[j+a]].
maps[MATERIAL_MAP_DIFFUSE].color = color_arr[a];
}
}
}
}
// Draw a model wires (with texture if set)
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
{

94
src/simd.h Normal file
View File

@ -0,0 +1,94 @@
#pragma once
#include <immintrin.h>
#include <math.h>
#ifdef sse_sse2
//Sizes
#define __simd_8_size 16
#define __simd_16_size 8
#define __simd_32_size 4
#define __simd_64_size 2
//Variables
#define __simd_f __m128
#define __simd_d __m128d
#define __simd_i __m128i
//Intrinsics
#define __simd_f_set_ps1(a) (_mm_set_ps1(a))
#define __simd_f_add_ps(a, b) (_mm_add_ps((a), (b)))
#define __simd_f_sub_ps(a, b) (_mm_sub_ps(a, b))
#define __simd_f_mul_ps(a, b) (_mm_mul_ps(a, b))
#define __simd_f_reciprocal_sqrt_ps(a) (_mm_rsqrt_ps(a))
#define __simd_f_cmpare_lower_or_equal_ps(a, b) (_mm_cmple_ps(a, b))
#define __simd_f_cmpare_grater_or_equal_ps(a, b) (_mm_cmpge_ps(a, b))
#define __simd_f_cmpare_not_equal_ps(a, b) (_mm_cmpneq_ps(a, b))
#define __simd_i__mm_cast_f_to_i_ps_si128(a) (_mm_castps_si128(a))
#define __simd_f_and_ps(a, b) (_mm_and_ps(a, b))
#define __simd_f_not_and_ps(a, b) (_mm_andnot_ps(a, b))
#else
#define __simd_8_size 1
#define __simd_16_size 1
#define __simd_32_size 1
#define __simd_64_size 1
#define __simd_f float
#define __simd_d double
#define __simd_i int
#define __simd_f_set_ps1(a) (a)
#define __simd_f_add_ps(a, b) (a+b)
#define __simd_f_sub_ps(a, b) (a-b)
#define __simd_f_mul_ps(a, b) (a*b)
#define __simd_f_reciprocal_sqrt_ps(a) (1/sqrtf(a))
#define __simd_f_cmpare_lower_or_equal_ps(a, b) (a<=b)
#define __simd_f_cmpare_grater_or_equal_ps(a, b) (a>=b)
#define __simd_f_cmpare_not_equal_ps(a, b) (a!=b)
#define __simd_i__mm_cast_f_to_i_ps_si128(a) ((int)a)
#define __simd_f_and_ps(a, b) (a&&b)
#define __simd_f_not_and_ps(a, b) (!a)
#endif
//simd structs
typedef struct Vector3_simd {
__simd_f x;
__simd_f y;
__simd_f z;
}Vector3_simd;
typedef struct Matrix_simd {
__simd_f m0, m4, m8, m12; // Matrix first row (4 components)
__simd_f m1, m5, m9, m13; // Matrix second row (4 components)
__simd_f m2, m6, m10, m14; // Matrix third row (4 components)
__simd_f m3, m7, m11, m15; // Matrix fourth row (4 components)
} Matrix_simd;
typedef struct Color_float_simd{
__simd_f r, g, b, a;
}Color_float_simd;
// simd structs