| @ -1,466 +0,0 @@ | |||
| /********************************************************************************************** | |||
| * | |||
| * raylib.pbr - Some useful functions to deal with pbr materials and lights | |||
| * | |||
| * CONFIGURATION: | |||
| * | |||
| * #define RPBR_IMPLEMENTATION | |||
| * Generates the implementation of the library into the included file. | |||
| * If not defined, the library is in header only mode and can be included in other headers | |||
| * or source files without problems. But only ONE file should hold the implementation. | |||
| * | |||
| * LICENSE: zlib/libpng | |||
| * | |||
| * Copyright (c) 2023-2024 Afan OLOVCIC (@_DevDad) 2017-2020 Victor Fisac(@victorfisac),Ramon Santamaria (@raysan5) | |||
| * | |||
| * This software is provided "as-is", without any express or implied warranty. In no event | |||
| * will the authors be held liable for any damages arising from the use of this software. | |||
| * | |||
| * Permission is granted to anyone to use this software for any purpose, including commercial | |||
| * applications, and to alter it and redistribute it freely, subject to the following restrictions: | |||
| * | |||
| * 1. The origin of this software must not be misrepresented; you must not claim that you | |||
| * wrote the original software. If you use this software in a product, an acknowledgment | |||
| * in the product documentation would be appreciated but is not required. | |||
| * | |||
| * 2. Altered source versions must be plainly marked as such, and must not be misrepresented | |||
| * as being the original software. | |||
| * | |||
| * 3. This notice may not be removed or altered from any source distribution. | |||
| * | |||
| **********************************************************************************************/ | |||
| #ifndef RPBR_H | |||
| #define RPBR_H | |||
| #include "raylib.h" | |||
| //---------------------------------------------------------------------------------- | |||
| // Defines and Macros | |||
| //---------------------------------------------------------------------------------- | |||
| #define MAX_LIGHTS 4 // Max dynamic lights supported by shader | |||
| #define SHADER_LOC_MAP_MRA SHADER_LOC_MAP_METALNESS //METALLIC, ROUGHNESS and AO | |||
| #define SHADER_LOC_MAP_EMISSIVE SHADER_LOC_MAP_HEIGHT //EMISSIVE | |||
| #define MATERIAL_MAP_MRA MATERIAL_MAP_METALNESS | |||
| #define MATERIAL_MAP_EMISSIVE MATERIAL_MAP_HEIGHT | |||
| #define NULL 0 | |||
| #define COLOR_TO_ARRAY(c) | |||
| typedef struct { | |||
| int enabled; | |||
| int type; | |||
| Vector3 position; | |||
| Vector3 target; | |||
| float color[4]; | |||
| float intensity; | |||
| int enabledLoc; | |||
| int typeLoc; | |||
| int positionLoc; | |||
| int targetLoc; | |||
| int colorLoc; | |||
| int intensityLoc; | |||
| } PBRLight; | |||
| typedef enum { | |||
| LIGHT_DIRECTIONAL = 0, | |||
| LIGHT_POINT, | |||
| LIGHT_SPOT | |||
| } PBRLightType; | |||
| typedef struct{ | |||
| Shader pbrShader; | |||
| Shader skyShader; | |||
| unsigned int cubemap; | |||
| unsigned int irradiance; | |||
| unsigned int prefilter; | |||
| unsigned int brdf; | |||
| int modelMatrixLoc; | |||
| int pbrViewLoc; | |||
| int skyViewLoc; | |||
| int skyResolutionLoc; | |||
| } PBREnvironment; | |||
| typedef enum{ | |||
| PBR_COLOR_ALBEDO = 0, | |||
| PBR_COLOR_EMISSIVE | |||
| }PBRColorType; | |||
| typedef enum{ | |||
| PBR_VEC2_TILING = 0, | |||
| PBR_VEC2_OFFSET | |||
| }PBRVec2Type; | |||
| typedef enum{ | |||
| PBR_PARAM_NORMAL =0, | |||
| PBR_PARAM_METALLIC, | |||
| PBR_PARAM_ROUGHNESS, | |||
| PBR_PARAM_EMISSIVE, | |||
| PBR_PARAM_AO | |||
| }PBRFloatType; | |||
| typedef enum{ | |||
| PBR_TEXTURE_ALBEDO = 0, | |||
| PBR_TEXTURE_NORMAL, | |||
| PBR_TEXTURE_MRA, | |||
| PBR_TEXTURE_EMISSIVE | |||
| }PBRTexType; | |||
| // Textures are moved to material from params to pack better and use less textures on the end | |||
| // texture MRAE 4Channel R: Metallic G: Roughness B: A: Ambient Occlusion | |||
| // texEmissive use just one channel, so we have 3 channels still to use if we need | |||
| typedef struct { | |||
| Shader pbrShader; | |||
| float albedo[4]; | |||
| float normal; | |||
| float metallic; | |||
| float roughness; | |||
| float ao; | |||
| float emissive[4]; | |||
| float ambient[3]; | |||
| float emissivePower; | |||
| Texture2D texAlbedo; | |||
| Texture2D texNormal; | |||
| Texture2D texMRA;//r: Metallic g: Roughness b: AO a:Empty | |||
| Texture2D texEmissive; //Emissive Texture | |||
| // Using float4 to store tilling at 1st and 2nd position and offset at 3rd and 4th | |||
| float texTiling[2]; | |||
| float texOffset[2]; | |||
| int useTexAlbedo; | |||
| int useTexNormal; | |||
| int useTexMRA; | |||
| int useTexEmissive; | |||
| int albedoLoc; | |||
| int normalLoc; | |||
| int metallicLoc; | |||
| int roughnessLoc; | |||
| int aoLoc; | |||
| int emissiveColorLoc; | |||
| int emissivePowerLoc; | |||
| int texTilingLoc; | |||
| int texOffsetLoc; | |||
| int useTexAlbedoLoc; | |||
| int useTexNormalLoc; | |||
| int useTexMRAELoc; | |||
| int useTexEmissiveLoc; | |||
| } PBRMaterial; | |||
| typedef struct{ | |||
| Model model; | |||
| PBRMaterial pbrMat; | |||
| }PBRModel; | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| //---------------------------------------------------------------------------------- | |||
| // Module Functions Declaration | |||
| //---------------------------------------------------------------------------------- | |||
| // Create a light and get shader locations | |||
| PBRLight PBRLightCreate(int type, Vector3 position, Vector3 target, Color color,float intensity, Shader shader); | |||
| // Send light properties to shader | |||
| void PBRLightUpdate(Shader shader, PBRLight light); | |||
| //For now until we do real skylight | |||
| void PBRSetAmbient(Shader shader, Color color, float intensity); | |||
| PBRModel PBRModelLoad(const char *fileName); | |||
| PBRModel PBRModelLoadFromMesh(Mesh mesh); | |||
| void PBRLoadTextures(PBRMaterial *pbrMat,PBRTexType pbrTexType,const char *fileName); | |||
| void UnloadPBRMaterial(PBRMaterial pbrMat); | |||
| void PBRSetColor(PBRMaterial *pbrMat,PBRColorType pbrColorType,Color color); | |||
| void PBRSetVec2(PBRMaterial *pbrMat,PBRVec2Type type,Vector2 value); | |||
| void PBRSetFloat(PBRMaterial *pbrMat, PBRFloatType pbrParamType, float value); | |||
| void PBRMaterialSetup( PBRMaterial *pbrMat,Shader pbrShader, PBREnvironment* environment); | |||
| void PBRSetMaterial(PBRModel* model,PBRMaterial* pbrMat,int matIndex); | |||
| void PBRDrawModel(PBRModel pbrModel, Vector3 position, float scale); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif //RPBR_H | |||
| /*********************************************************************************** | |||
| * | |||
| * RPBR IMPLEMENTATION | |||
| * | |||
| ************************************************************************************/ | |||
| #if defined(RPBR_IMPLEMENTATION) | |||
| //---------------------------------------------------------------------------------- | |||
| // Global Variables Definition | |||
| //---------------------------------------------------------------------------------- | |||
| static int lightsCount = 0; // Current amount of created lights | |||
| // Create a light and get shader locations | |||
| PBRLight PBRLightCreate(int type, Vector3 position, Vector3 target, Color color,float intensity, Shader shader) | |||
| { | |||
| PBRLight light = { 0 }; | |||
| if (lightsCount < MAX_LIGHTS) | |||
| { | |||
| light.enabled = 1; | |||
| light.type = type; | |||
| light.position = position; | |||
| light.target = target; | |||
| light.color[0] = (float)color.r/(float)255; | |||
| light.color[1] = (float)color.g/(float)255; | |||
| light.color[2] = (float)color.b/(float)255; | |||
| light.color[3] = (float)color.a/(float)255; | |||
| light.intensity = intensity; | |||
| // NOTE: Lighting shader naming must be the provided ones | |||
| light.enabledLoc = GetShaderLocation(shader, TextFormat("lights[%i].enabled", lightsCount)); | |||
| light.typeLoc = GetShaderLocation(shader, TextFormat("lights[%i].type", lightsCount)); | |||
| light.positionLoc = GetShaderLocation(shader, TextFormat("lights[%i].position", lightsCount)); | |||
| light.targetLoc = GetShaderLocation(shader, TextFormat("lights[%i].target", lightsCount)); | |||
| light.colorLoc = GetShaderLocation(shader, TextFormat("lights[%i].color", lightsCount)); | |||
| light.intensityLoc = GetShaderLocation(shader, TextFormat("lights[%i].intensity", lightsCount)); | |||
| PBRLightUpdate(shader, light); | |||
| lightsCount++; | |||
| } | |||
| return light; | |||
| } | |||
| // Send light properties to shader | |||
| // NOTE: Light shader locations should be available | |||
| void PBRLightUpdate(Shader shader, PBRLight light) | |||
| { | |||
| SetShaderValue(shader, light.enabledLoc, &light.enabled, SHADER_UNIFORM_INT); | |||
| SetShaderValue(shader, light.typeLoc, &light.type, SHADER_UNIFORM_INT); | |||
| // Send to shader light position values | |||
| float position[3] = { light.position.x, light.position.y, light.position.z }; | |||
| SetShaderValue(shader, light.positionLoc, position, SHADER_UNIFORM_VEC3); | |||
| // Send to shader light target position values | |||
| float target[3] = { light.target.x, light.target.y, light.target.z }; | |||
| SetShaderValue(shader, light.targetLoc, target, SHADER_UNIFORM_VEC3); | |||
| SetShaderValue(shader, light.colorLoc, light.color, SHADER_UNIFORM_VEC4); | |||
| SetShaderValue(shader, light.intensityLoc, &light.intensity, SHADER_UNIFORM_FLOAT); | |||
| } | |||
| void PBRSetAmbient(Shader shader, Color color, float intensity){ | |||
| float col[3] = {color.r/255,color.g/255,color.b/255}; | |||
| SetShaderValue(shader, GetShaderLocation(shader, "ambientColor"), col, SHADER_UNIFORM_VEC3); | |||
| SetShaderValue(shader, GetShaderLocation(shader, "ambient"), &intensity, SHADER_UNIFORM_FLOAT); | |||
| } | |||
| void PBRMaterialSetup(PBRMaterial *pbrMat, Shader pbrShader, PBREnvironment* environment){ | |||
| pbrMat->pbrShader = pbrShader; | |||
| pbrMat->texAlbedo = (Texture2D){0}; | |||
| pbrMat->texNormal = (Texture2D){0}; | |||
| pbrMat->texMRA = (Texture2D){0}; | |||
| pbrMat->texEmissive = (Texture2D){0}; | |||
| //PBRParam | |||
| pbrMat->albedo[0] = 1.0; | |||
| pbrMat->albedo[1] = 1.0; | |||
| pbrMat->albedo[2] = 1.0; | |||
| pbrMat->albedo[3] = 1.0; | |||
| pbrMat->metallic = 0; | |||
| pbrMat->roughness = 0; | |||
| pbrMat->ao = 1.0; | |||
| pbrMat->normal = 1; | |||
| pbrMat->emissive[0] = 0; | |||
| pbrMat->emissive[1] = 0; | |||
| pbrMat->emissive[2] = 0; | |||
| pbrMat->emissive[3] = 0; | |||
| pbrMat->texTiling[0] = 1.0; | |||
| pbrMat->texTiling[1] = 1.0; | |||
| pbrMat->texOffset[0] = 0.0; | |||
| pbrMat->texOffset[1] = 0.0; | |||
| pbrMat->emissivePower = 1.0; | |||
| // Set up PBR shader material locations | |||
| pbrMat->albedoLoc = GetShaderLocation(pbrMat->pbrShader, "albedoColor"); | |||
| pbrMat->normalLoc = GetShaderLocation(pbrMat->pbrShader, "normalValue"); | |||
| pbrMat->metallicLoc = GetShaderLocation(pbrMat->pbrShader, "metallicValue"); | |||
| pbrMat->roughnessLoc = GetShaderLocation(pbrMat->pbrShader, "roughnessValue"); | |||
| pbrMat->aoLoc = GetShaderLocation(pbrMat->pbrShader, "aoValue"); | |||
| pbrMat->emissiveColorLoc = GetShaderLocation(pbrMat->pbrShader, "emissiveColor"); | |||
| pbrMat->emissivePowerLoc = GetShaderLocation(pbrMat->pbrShader, "emissivePower"); | |||
| pbrMat->texTilingLoc = GetShaderLocation(pbrMat->pbrShader, "tiling"); | |||
| pbrMat->texOffsetLoc = GetShaderLocation(pbrMat->pbrShader, "offset"); | |||
| pbrMat->useTexAlbedoLoc = GetShaderLocation(pbrMat->pbrShader, "useTexAlbedo"); | |||
| pbrMat->useTexNormalLoc = GetShaderLocation(pbrMat->pbrShader, "useTexNormal"); | |||
| pbrMat->useTexMRAELoc = GetShaderLocation(pbrMat->pbrShader, "useTexMRA"); | |||
| pbrMat->useTexEmissiveLoc = GetShaderLocation(pbrMat->pbrShader, "useTexEmissive"); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->emissivePowerLoc, &pbrMat->emissivePower, SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,pbrMat->texTiling,SHADER_UNIFORM_VEC2); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,pbrMat->texOffset,SHADER_UNIFORM_VEC2); | |||
| } | |||
| void PBRLoadTextures(PBRMaterial *pbrMat,PBRTexType pbrTexType,const char *fileName){ | |||
| if(pbrMat == NULL) return; | |||
| switch(pbrTexType){ | |||
| case PBR_TEXTURE_ALBEDO: | |||
| pbrMat->texAlbedo = LoadTexture(fileName); | |||
| pbrMat->useTexAlbedo = 1; | |||
| break; | |||
| case PBR_TEXTURE_MRA: | |||
| pbrMat->texMRA = LoadTexture(fileName); | |||
| pbrMat->useTexMRA = 1; | |||
| break; | |||
| case PBR_TEXTURE_NORMAL: | |||
| pbrMat->texNormal = LoadTexture(fileName); | |||
| pbrMat->useTexNormal = 1; | |||
| break; | |||
| case PBR_TEXTURE_EMISSIVE: | |||
| pbrMat->texEmissive = LoadTexture(fileName); | |||
| pbrMat->useTexEmissive = 1; | |||
| break; | |||
| } | |||
| } | |||
| void UnloadPBRMaterial(PBRMaterial pbrMat){ | |||
| if(pbrMat.useTexAlbedo == 1) UnloadTexture(pbrMat.texAlbedo); | |||
| if(pbrMat.useTexNormal == 1) UnloadTexture(pbrMat.texNormal); | |||
| if(pbrMat.useTexMRA == 1) UnloadTexture(pbrMat.texMRA); | |||
| if(pbrMat.useTexEmissive == 1) UnloadTexture(pbrMat.texEmissive); | |||
| } | |||
| void PBRSetColor(PBRMaterial *pbrMat,PBRColorType pbrColorType,Color color){ | |||
| if(pbrMat == NULL) return; | |||
| switch(pbrColorType){ | |||
| case PBR_COLOR_ALBEDO: | |||
| pbrMat->albedo[0] = (float) color.r / 255; | |||
| pbrMat->albedo[1] = (float) color.g / 255; | |||
| pbrMat->albedo[2] = (float) color.b / 255; | |||
| pbrMat->albedo[3] = (float) color.a / 255; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4); | |||
| break; | |||
| case PBR_COLOR_EMISSIVE: | |||
| pbrMat->emissive[0] = (float) color.r / 255; | |||
| pbrMat->emissive[1] = (float) color.g / 255; | |||
| pbrMat->emissive[2] = (float) color.b / 255; | |||
| pbrMat->emissive[3] = (float) color.a / 255; | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4); | |||
| break; | |||
| } | |||
| } | |||
| void PBRSetFloat(PBRMaterial *pbrMat, PBRFloatType pbrParamType, float value){ | |||
| if(pbrMat == NULL) return; | |||
| switch(pbrParamType){ | |||
| case PBR_PARAM_METALLIC: | |||
| pbrMat->metallic = value; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT); | |||
| break; | |||
| case PBR_PARAM_ROUGHNESS: | |||
| pbrMat->roughness = value; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT); | |||
| break; | |||
| case PBR_PARAM_NORMAL: | |||
| pbrMat->normal = value; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT); | |||
| break; | |||
| case PBR_PARAM_AO: | |||
| pbrMat->ao = value; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT); | |||
| break; | |||
| case PBR_PARAM_EMISSIVE: | |||
| pbrMat->emissivePower = value; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->emissivePowerLoc,&pbrMat->emissivePower,SHADER_UNIFORM_FLOAT); | |||
| break; | |||
| } | |||
| } | |||
| void PBRSetVec2(PBRMaterial *pbrMat,PBRVec2Type type,Vector2 value){ | |||
| switch(type){ | |||
| case PBR_VEC2_TILING: | |||
| pbrMat->texTiling[0] = value.x; | |||
| pbrMat->texTiling[1] = value.y; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,&pbrMat->texTiling,SHADER_UNIFORM_VEC2); | |||
| break; | |||
| case PBR_VEC2_OFFSET: | |||
| pbrMat->texOffset[0] = value.x; | |||
| pbrMat->texOffset[1] = value.y; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,&pbrMat->texOffset,SHADER_UNIFORM_VEC2); | |||
| break; | |||
| } | |||
| } | |||
| void PBRSetMaterial(PBRModel* model,PBRMaterial* pbrMat,int matIndex){ | |||
| model->pbrMat = *pbrMat; | |||
| model->model.materials[matIndex].shader = model->pbrMat.pbrShader; | |||
| pbrMat->pbrShader.locs[SHADER_LOC_MAP_MRA] = GetShaderLocation(pbrMat->pbrShader, "mraMap"); | |||
| pbrMat->pbrShader.locs[SHADER_LOC_MAP_EMISSIVE] = GetShaderLocation(pbrMat->pbrShader, "emissiveMap"); | |||
| pbrMat->pbrShader.locs[SHADER_LOC_MAP_NORMAL] = GetShaderLocation(pbrMat->pbrShader, "normalMap"); | |||
| if(pbrMat->useTexAlbedo) { | |||
| model->model.materials[matIndex].maps[MATERIAL_MAP_ALBEDO].texture = pbrMat->texAlbedo; | |||
| } | |||
| if(pbrMat->useTexMRA) { | |||
| model->model.materials[matIndex].maps[MATERIAL_MAP_MRA].texture = pbrMat->texMRA; | |||
| } | |||
| if(pbrMat->useTexNormal) { | |||
| model->model.materials[matIndex].maps[MATERIAL_MAP_NORMAL].texture = pbrMat->texNormal; | |||
| } | |||
| if(pbrMat->useTexEmissive) { | |||
| model->model.materials[matIndex].maps[MATERIAL_MAP_EMISSIVE].texture = pbrMat->texEmissive; | |||
| } | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->useTexAlbedoLoc,&pbrMat->useTexAlbedo,SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->useTexNormalLoc,&pbrMat->useTexNormal,SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->useTexMRAELoc, &pbrMat->useTexMRA, SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->useTexEmissiveLoc, &pbrMat->useTexEmissive, SHADER_UNIFORM_INT); | |||
| } | |||
| void PBRDrawModel(PBRModel pbrModel, Vector3 position, float scale){ | |||
| PBRMaterial *pbrMat = &pbrModel.pbrMat; | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,pbrMat->texTiling,SHADER_UNIFORM_VEC2); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,pbrMat->texOffset,SHADER_UNIFORM_VEC2); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->useTexAlbedoLoc,&pbrMat->useTexAlbedo,SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader,pbrMat->useTexNormalLoc,&pbrMat->useTexNormal,SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->useTexMRAELoc, &pbrMat->useTexMRA, SHADER_UNIFORM_INT); | |||
| SetShaderValue(pbrMat->pbrShader, pbrMat->useTexEmissiveLoc, &pbrMat->useTexEmissive, SHADER_UNIFORM_INT); | |||
| DrawModel(pbrModel.model,position,scale,WHITE); | |||
| } | |||
| PBRModel PBRModelLoad(const char *fileName){ | |||
| PBRModel pbrModel = (PBRModel){0}; | |||
| pbrModel.model = LoadModel(fileName); | |||
| return pbrModel; | |||
| } | |||
| PBRModel PBRModelLoadFromMesh(Mesh mesh){ | |||
| PBRModel pbrModel = (PBRModel){0}; | |||
| pbrModel.model = LoadModelFromMesh(mesh); | |||
| return pbrModel; | |||
| } | |||
| #endif // RPBR_IMPLEMENTATION | |||