Working on PBR system
Moved PBR material loading to example, right decision?
This commit is contained in:
parent
e8b65422c4
commit
76c6f0b1e6
6 changed files with 390 additions and 293 deletions
|
@ -12,32 +12,16 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
#define MAX_LIGHTS 4 // Max lights supported by shader
|
#define RLIGHTS_IMPLEMENTATION
|
||||||
#define LIGHT_DISTANCE 3.5f // Light distance from world center
|
#include "rlights.h"
|
||||||
#define LIGHT_HEIGHT 1.0f // Light height position
|
|
||||||
|
|
||||||
typedef enum {
|
#define CUBEMAP_SIZE 512 // Cubemap texture size
|
||||||
LIGHT_DIRECTIONAL,
|
#define IRRADIANCE_SIZE 32 // Irradiance texture size
|
||||||
LIGHT_POINT
|
#define PREFILTERED_SIZE 256 // Prefiltered HDR environment texture size
|
||||||
} LightType;
|
#define BRDF_SIZE 512 // BRDF LUT texture size
|
||||||
|
|
||||||
typedef struct {
|
// PBR material loading
|
||||||
bool enabled;
|
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness);
|
||||||
LightType type;
|
|
||||||
Vector3 position;
|
|
||||||
Vector3 target;
|
|
||||||
Color color;
|
|
||||||
int enabledLoc;
|
|
||||||
int typeLoc;
|
|
||||||
int posLoc;
|
|
||||||
int targetLoc;
|
|
||||||
int colorLoc;
|
|
||||||
} Light;
|
|
||||||
|
|
||||||
int lightsCount = 0; // Current amount of created lights
|
|
||||||
|
|
||||||
Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader); // Defines a light and get locations from PBR shader
|
|
||||||
void UpdateLightValues(Shader shader, Light light); // Send to PBR shader light values
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -54,27 +38,7 @@ int main()
|
||||||
|
|
||||||
// Load model and PBR material
|
// Load model and PBR material
|
||||||
Model model = LoadModel("resources/pbr/trooper.obj");
|
Model model = LoadModel("resources/pbr/trooper.obj");
|
||||||
|
model.material = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
|
||||||
Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
|
|
||||||
model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
|
|
||||||
|
|
||||||
SetMaterialTexture(&model.material, MAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
|
|
||||||
SetMaterialTexture(&model.material, MAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
|
|
||||||
SetMaterialTexture(&model.material, MAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png"));
|
|
||||||
SetMaterialTexture(&model.material, MAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png"));
|
|
||||||
SetMaterialTexture(&model.material, MAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png"));
|
|
||||||
|
|
||||||
// Set textures filtering for better quality
|
|
||||||
SetTextureFilter(model.material.maps[MAP_ALBEDO].texture, FILTER_BILINEAR);
|
|
||||||
SetTextureFilter(model.material.maps[MAP_NORMAL].texture, FILTER_BILINEAR);
|
|
||||||
SetTextureFilter(model.material.maps[MAP_METALNESS].texture, FILTER_BILINEAR);
|
|
||||||
SetTextureFilter(model.material.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR);
|
|
||||||
SetTextureFilter(model.material.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR);
|
|
||||||
|
|
||||||
int renderModeLoc = GetShaderLocation(model.material.shader, "renderMode");
|
|
||||||
SetShaderValuei(model.material.shader, renderModeLoc, (int[1]){ 0 }, 1);
|
|
||||||
|
|
||||||
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
|
||||||
|
|
||||||
// Define lights attributes
|
// Define lights attributes
|
||||||
Light lights[MAX_LIGHTS] = { CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader),
|
Light lights[MAX_LIGHTS] = { CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader),
|
||||||
|
@ -82,6 +46,8 @@ int main()
|
||||||
CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader),
|
CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader),
|
||||||
CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader) };
|
CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader) };
|
||||||
|
|
||||||
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -127,59 +93,88 @@ int main()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defines a light and get locations from PBR shader
|
// Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps)
|
||||||
Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader)
|
// NOTE: PBR shader is loaded inside this function
|
||||||
|
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
|
||||||
{
|
{
|
||||||
Light light = { 0 };
|
Material mat = { 0 }; // NOTE: All maps textures are set to { 0 }
|
||||||
|
|
||||||
if (lightsCount < MAX_LIGHTS)
|
#define PATH_PBR_VS "resources/shaders/pbr.vs" // Path to physically based rendering vertex shader
|
||||||
{
|
#define PATH_PBR_FS "resources/shaders/pbr.fs" // Path to physically based rendering fragment shader
|
||||||
light.enabled = true;
|
|
||||||
light.type = type;
|
|
||||||
light.position = pos;
|
|
||||||
light.target = targ;
|
|
||||||
light.color = color;
|
|
||||||
|
|
||||||
char enabledName[32] = "lights[x].enabled\0";
|
mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS);
|
||||||
char typeName[32] = "lights[x].type\0";
|
|
||||||
char posName[32] = "lights[x].position\0";
|
|
||||||
char targetName[32] = "lights[x].target\0";
|
|
||||||
char colorName[32] = "lights[x].color\0";
|
|
||||||
enabledName[7] = '0' + lightsCount;
|
|
||||||
typeName[7] = '0' + lightsCount;
|
|
||||||
posName[7] = '0' + lightsCount;
|
|
||||||
targetName[7] = '0' + lightsCount;
|
|
||||||
colorName[7] = '0' + lightsCount;
|
|
||||||
|
|
||||||
light.enabledLoc = GetShaderLocation(shader, enabledName);
|
// Get required locations points for PBR material
|
||||||
light.typeLoc = GetShaderLocation(shader, typeName);
|
// NOTE: Those location names must be available and used in the shader code
|
||||||
light.posLoc = GetShaderLocation(shader, posName);
|
mat.shader.locs[LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
|
||||||
light.targetLoc = GetShaderLocation(shader, targetName);
|
mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
|
||||||
light.colorLoc = GetShaderLocation(shader, colorName);
|
mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
|
||||||
|
mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
|
||||||
|
mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
|
||||||
|
mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
|
||||||
|
mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
|
||||||
|
mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
|
||||||
|
mat.shader.locs[LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
|
||||||
|
mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
|
||||||
|
|
||||||
UpdateLightValues(shader, light);
|
// Set view matrix location
|
||||||
lightsCount++;
|
mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix");
|
||||||
}
|
mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view");
|
||||||
|
mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos");
|
||||||
|
|
||||||
return light;
|
// Set PBR standard maps
|
||||||
}
|
SetMaterialTexture(&mat, MAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
|
||||||
|
SetMaterialTexture(&mat, MAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
|
||||||
// Send to PBR shader light values
|
SetMaterialTexture(&mat, MAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png"));
|
||||||
void UpdateLightValues(Shader shader, Light light)
|
SetMaterialTexture(&mat, MAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png"));
|
||||||
{
|
SetMaterialTexture(&mat, MAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png"));
|
||||||
// Send to shader light enabled state and type
|
|
||||||
SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1);
|
// Set environment maps
|
||||||
SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1);
|
#define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader
|
||||||
|
#define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader
|
||||||
// Send to shader light position values
|
#define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
|
||||||
float position[3] = { light.position.x, light.position.y, light.position.z };
|
#define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader
|
||||||
SetShaderValue(shader, light.posLoc, position, 3);
|
#define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
|
||||||
|
#define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" // Path to reflection prefilter calculation fragment shader
|
||||||
// Send to shader light target position values
|
#define PATH_BRDF_VS "resources/shaders/brdf.vs" // Path to bidirectional reflectance distribution function vertex shader
|
||||||
float target[3] = { light.target.x, light.target.y, light.target.z };
|
#define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
|
||||||
SetShaderValue(shader, light.targetLoc, target, 3);
|
|
||||||
|
Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
|
||||||
// Send to shader light color values
|
Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
|
||||||
float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 };
|
Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
|
||||||
SetShaderValue(shader, light.colorLoc, diff, 4);
|
Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
||||||
|
|
||||||
|
Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
|
||||||
|
Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE);
|
||||||
|
SetMaterialTexture(&mat, MAP_IRRADIANCE, GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE));
|
||||||
|
SetMaterialTexture(&mat, MAP_PREFILTER, GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE));
|
||||||
|
SetMaterialTexture(&mat, MAP_BRDF, GenTextureBRDF(shdrBRDF, cubemap, BRDF_SIZE));
|
||||||
|
UnloadTexture(cubemap);
|
||||||
|
UnloadTexture(texHDR);
|
||||||
|
|
||||||
|
UnloadShader(shdrCubemap);
|
||||||
|
UnloadShader(shdrIrradiance);
|
||||||
|
UnloadShader(shdrPrefilter);
|
||||||
|
UnloadShader(shdrBRDF);
|
||||||
|
|
||||||
|
// Set textures filtering for better quality
|
||||||
|
SetTextureFilter(mat.maps[MAP_ALBEDO].texture, FILTER_BILINEAR);
|
||||||
|
SetTextureFilter(mat.maps[MAP_NORMAL].texture, FILTER_BILINEAR);
|
||||||
|
SetTextureFilter(mat.maps[MAP_METALNESS].texture, FILTER_BILINEAR);
|
||||||
|
SetTextureFilter(mat.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR);
|
||||||
|
SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR);
|
||||||
|
|
||||||
|
int renderModeLoc = GetShaderLocation(mat.shader, "renderMode");
|
||||||
|
SetShaderValuei(mat.shader, renderModeLoc, (int[1]){ 0 }, 1);
|
||||||
|
|
||||||
|
// Set up material properties color
|
||||||
|
mat.maps[MAP_ALBEDO].color = albedo;
|
||||||
|
mat.maps[MAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
|
||||||
|
mat.maps[MAP_METALNESS].value = metalness;
|
||||||
|
mat.maps[MAP_ROUGHNESS].value = roughness;
|
||||||
|
mat.maps[MAP_OCCLUSION].value = 1.0f;
|
||||||
|
mat.maps[MAP_EMISSION].value = 0.5f;
|
||||||
|
mat.maps[MAP_HEIGHT].value = 0.5f;
|
||||||
|
|
||||||
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
|
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
#define MAX_LIGHTS 4
|
|
||||||
#define MAX_REFLECTION_LOD 4.0
|
#define MAX_REFLECTION_LOD 4.0
|
||||||
#define MAX_DEPTH_LAYER 20
|
#define MAX_DEPTH_LAYER 20
|
||||||
#define MIN_DEPTH_LAYER 10
|
#define MIN_DEPTH_LAYER 10
|
||||||
|
|
||||||
|
#define MAX_LIGHTS 4
|
||||||
#define LIGHT_DIRECTIONAL 0
|
#define LIGHT_DIRECTIONAL 0
|
||||||
#define LIGHT_POINT 1
|
#define LIGHT_POINT 1
|
||||||
|
|
||||||
|
|
177
examples/models/rlights.h
Normal file
177
examples/models/rlights.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib.lights - Some useful functions to deal with lights data
|
||||||
|
*
|
||||||
|
* CONFIGURATION:
|
||||||
|
*
|
||||||
|
* #define RLIGHTS_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) 2017 Victor Fisac and Ramon Santamaria
|
||||||
|
*
|
||||||
|
* 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 RLIGHTS_H
|
||||||
|
#define RLIGHTS_H
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define MAX_LIGHTS 4 // Max lights supported by shader
|
||||||
|
#define LIGHT_DISTANCE 3.5f // Light distance from world center
|
||||||
|
#define LIGHT_HEIGHT 1.0f // Light height position
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum {
|
||||||
|
LIGHT_DIRECTIONAL,
|
||||||
|
LIGHT_POINT
|
||||||
|
} LightType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool enabled;
|
||||||
|
LightType type;
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 target;
|
||||||
|
Color color;
|
||||||
|
int enabledLoc;
|
||||||
|
int typeLoc;
|
||||||
|
int posLoc;
|
||||||
|
int targetLoc;
|
||||||
|
int colorLoc;
|
||||||
|
} Light;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" { // Prevents name mangling of functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
int lightsCount = 0; // Current amount of created lights
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader); // Defines a light and get locations from PBR shader
|
||||||
|
void UpdateLightValues(Shader shader, Light light); // Send to PBR shader light values
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RLIGHTS_H
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************************
|
||||||
|
*
|
||||||
|
* RLIGHTS IMPLEMENTATION
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
#if defined(RLIGHTS_IMPLEMENTATION)
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module specific Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Defines a light and get locations from PBR shader
|
||||||
|
Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader)
|
||||||
|
{
|
||||||
|
Light light = { 0 };
|
||||||
|
|
||||||
|
if (lightsCount < MAX_LIGHTS)
|
||||||
|
{
|
||||||
|
light.enabled = true;
|
||||||
|
light.type = type;
|
||||||
|
light.position = pos;
|
||||||
|
light.target = targ;
|
||||||
|
light.color = color;
|
||||||
|
|
||||||
|
char enabledName[32] = "lights[x].enabled\0";
|
||||||
|
char typeName[32] = "lights[x].type\0";
|
||||||
|
char posName[32] = "lights[x].position\0";
|
||||||
|
char targetName[32] = "lights[x].target\0";
|
||||||
|
char colorName[32] = "lights[x].color\0";
|
||||||
|
enabledName[7] = '0' + lightsCount;
|
||||||
|
typeName[7] = '0' + lightsCount;
|
||||||
|
posName[7] = '0' + lightsCount;
|
||||||
|
targetName[7] = '0' + lightsCount;
|
||||||
|
colorName[7] = '0' + lightsCount;
|
||||||
|
|
||||||
|
light.enabledLoc = GetShaderLocation(shader, enabledName);
|
||||||
|
light.typeLoc = GetShaderLocation(shader, typeName);
|
||||||
|
light.posLoc = GetShaderLocation(shader, posName);
|
||||||
|
light.targetLoc = GetShaderLocation(shader, targetName);
|
||||||
|
light.colorLoc = GetShaderLocation(shader, colorName);
|
||||||
|
|
||||||
|
UpdateLightValues(shader, light);
|
||||||
|
lightsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to PBR shader light values
|
||||||
|
void UpdateLightValues(Shader shader, Light light)
|
||||||
|
{
|
||||||
|
// Send to shader light enabled state and type
|
||||||
|
SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1);
|
||||||
|
SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1);
|
||||||
|
|
||||||
|
// Send to shader light position values
|
||||||
|
float position[3] = { light.position.x, light.position.y, light.position.z };
|
||||||
|
SetShaderValue(shader, light.posLoc, position, 3);
|
||||||
|
|
||||||
|
// Send to shader light target position values
|
||||||
|
float target[3] = { light.target.x, light.target.y, light.target.z };
|
||||||
|
SetShaderValue(shader, light.targetLoc, target, 3);
|
||||||
|
|
||||||
|
// Send to shader light color values
|
||||||
|
float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 };
|
||||||
|
SetShaderValue(shader, light.colorLoc, diff, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RLIGHTS_IMPLEMENTATION
|
103
src/models.c
103
src/models.c
|
@ -1272,6 +1272,9 @@ Material LoadMaterial(const char *fileName)
|
||||||
TraceLog(LOG_WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
|
TraceLog(LOG_WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Our material uses the default shader (DIFFUSE, SPECULAR, NORMAL)
|
||||||
|
material.shader = GetShaderDefault();
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,8 +1285,8 @@ Material LoadMaterialDefault(void)
|
||||||
|
|
||||||
material.shader = GetShaderDefault();
|
material.shader = GetShaderDefault();
|
||||||
material.maps[MAP_DIFFUSE].texture = GetTextureDefault(); // White texture (1x1 pixel)
|
material.maps[MAP_DIFFUSE].texture = GetTextureDefault(); // White texture (1x1 pixel)
|
||||||
//material.maps[MAP_NORMAL].tex; // NOTE: By default, not set
|
//material.maps[MAP_NORMAL].texture; // NOTE: By default, not set
|
||||||
//material.maps[MAP_SPECULAR].tex; // NOTE: By default, not set
|
//material.maps[MAP_SPECULAR].texture; // NOTE: By default, not set
|
||||||
|
|
||||||
material.maps[MAP_DIFFUSE].color = WHITE; // Diffuse color
|
material.maps[MAP_DIFFUSE].color = WHITE; // Diffuse color
|
||||||
material.maps[MAP_SPECULAR].color = WHITE; // Specular color
|
material.maps[MAP_SPECULAR].color = WHITE; // Specular color
|
||||||
|
@ -1291,58 +1294,6 @@ Material LoadMaterialDefault(void)
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps)
|
|
||||||
Material LoadMaterialPBR(Texture2D hdr, Color albedo, float metalness, float roughness)
|
|
||||||
{
|
|
||||||
Material mat = { 0 }; // NOTE: All maps textures are set to { 0 }
|
|
||||||
|
|
||||||
#define PATH_PBR_VS "resources/shaders/pbr.vs" // Path to physically based rendering vertex shader
|
|
||||||
#define PATH_PBR_FS "resources/shaders/pbr.fs" // Path to physically based rendering fragment shader
|
|
||||||
|
|
||||||
mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS);
|
|
||||||
|
|
||||||
// Get required locations points for PBR material
|
|
||||||
// NOTE: Those location names must be available and used in the shader code
|
|
||||||
mat.shader.locs[LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
|
|
||||||
mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
|
|
||||||
mat.shader.locs[LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
|
|
||||||
mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
|
|
||||||
|
|
||||||
// Set view matrix location
|
|
||||||
mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix");
|
|
||||||
mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view");
|
|
||||||
mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos");
|
|
||||||
|
|
||||||
// Set up material properties color
|
|
||||||
mat.maps[MAP_ALBEDO].color = albedo;
|
|
||||||
mat.maps[MAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
|
|
||||||
mat.maps[MAP_METALNESS].value = metalness;
|
|
||||||
mat.maps[MAP_ROUGHNESS].value = roughness;
|
|
||||||
mat.maps[MAP_OCCLUSION].value = 1.0f;
|
|
||||||
mat.maps[MAP_EMISSION].value = 0.0f;
|
|
||||||
mat.maps[MAP_HEIGHT].value = 0.0f;
|
|
||||||
|
|
||||||
#define CUBEMAP_SIZE 512 // Cubemap texture size
|
|
||||||
#define IRRADIANCE_SIZE 32 // Irradiance map from cubemap texture size
|
|
||||||
#define PREFILTERED_SIZE 256 // Prefiltered HDR environment map texture size
|
|
||||||
#define BRDF_SIZE 512 // BRDF LUT texture map size
|
|
||||||
|
|
||||||
// Set up environment materials cubemap
|
|
||||||
Texture2D cubemap = GenTextureCubemap(hdr, CUBEMAP_SIZE);
|
|
||||||
mat.maps[MAP_IRRADIANCE].texture = GenTextureIrradiance(cubemap, IRRADIANCE_SIZE);
|
|
||||||
mat.maps[MAP_PREFILTER].texture = GenTexturePrefilter(cubemap, PREFILTERED_SIZE);
|
|
||||||
mat.maps[MAP_BRDF].texture = GenTextureBRDF(cubemap, BRDF_SIZE);
|
|
||||||
UnloadTexture(cubemap);
|
|
||||||
|
|
||||||
return mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload material from memory
|
// Unload material from memory
|
||||||
void UnloadMaterial(Material material)
|
void UnloadMaterial(Material material)
|
||||||
{
|
{
|
||||||
|
@ -1358,96 +1309,96 @@ void UnloadMaterial(Material material)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set material texture
|
// Set material texture
|
||||||
void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture)
|
void SetMaterialTexture(Material *mat, int mapType, Texture2D texture)
|
||||||
{
|
{
|
||||||
mat->maps[texmapType].texture = texture;
|
mat->maps[mapType].texture = texture;
|
||||||
|
|
||||||
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
|
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
|
||||||
int location = -1;
|
int location = -1;
|
||||||
switch (texmapType)
|
switch (mapType)
|
||||||
{
|
{
|
||||||
case MAP_ALBEDO:
|
case MAP_ALBEDO:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "albedo.useSampler");
|
location = GetShaderLocation(mat->shader, "albedo.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_NORMAL:
|
case MAP_NORMAL:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "normals.useSampler");
|
location = GetShaderLocation(mat->shader, "normals.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_METALNESS:
|
case MAP_METALNESS:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "metalness.useSampler");
|
location = GetShaderLocation(mat->shader, "metalness.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_ROUGHNESS:
|
case MAP_ROUGHNESS:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "roughness.useSampler");
|
location = GetShaderLocation(mat->shader, "roughness.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_OCCLUSION:
|
case MAP_OCCLUSION:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
|
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_EMISSION:
|
case MAP_EMISSION:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "emission.useSampler");
|
location = GetShaderLocation(mat->shader, "emission.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_HEIGHT:
|
case MAP_HEIGHT:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "height.useSampler");
|
location = GetShaderLocation(mat->shader, "height.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 1 }, 1);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset texture from material and unload it from GPU
|
// Unset texture from material and unload it from GPU
|
||||||
void UnsetMaterialTexture(Material *mat, int texmapType)
|
void UnsetMaterialTexture(Material *mat, int mapType)
|
||||||
{
|
{
|
||||||
UnloadTexture(mat->maps[texmapType].texture);
|
UnloadTexture(mat->maps[mapType].texture);
|
||||||
mat->maps[texmapType].texture = (Texture2D){ 0 };
|
mat->maps[mapType].texture = (Texture2D){ 0 };
|
||||||
|
|
||||||
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
|
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
|
||||||
int location = -1;
|
int location = -1;
|
||||||
switch (texmapType)
|
switch (mapType)
|
||||||
{
|
{
|
||||||
case MAP_ALBEDO:
|
case MAP_ALBEDO:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "albedo.useSampler");
|
location = GetShaderLocation(mat->shader, "albedo.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_NORMAL:
|
case MAP_NORMAL:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "normals.useSampler");
|
location = GetShaderLocation(mat->shader, "normals.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_METALNESS:
|
case MAP_METALNESS:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "metalness.useSampler");
|
location = GetShaderLocation(mat->shader, "metalness.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_ROUGHNESS:
|
case MAP_ROUGHNESS:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "roughness.useSampler");
|
location = GetShaderLocation(mat->shader, "roughness.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_OCCLUSION:
|
case MAP_OCCLUSION:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
|
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_EMISSION:
|
case MAP_EMISSION:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "emission.useSampler");
|
location = GetShaderLocation(mat->shader, "emission.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
case MAP_HEIGHT:
|
case MAP_HEIGHT:
|
||||||
{
|
{
|
||||||
location = GetShaderLocation(mat->shader, "height.useSampler");
|
location = GetShaderLocation(mat->shader, "height.useSampler");
|
||||||
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
|
SetShaderValuei(mat->shader, location, (int[1]){ 0 }, 1);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2188,7 +2139,7 @@ static Material LoadMTL(const char *fileName)
|
||||||
{
|
{
|
||||||
#define MAX_BUFFER_SIZE 128
|
#define MAX_BUFFER_SIZE 128
|
||||||
|
|
||||||
Material material = { 0 }; // LoadDefaultMaterial();
|
Material material = { 0 };
|
||||||
|
|
||||||
char buffer[MAX_BUFFER_SIZE];
|
char buffer[MAX_BUFFER_SIZE];
|
||||||
Vector3 color = { 1.0f, 1.0f, 1.0f };
|
Vector3 color = { 1.0f, 1.0f, 1.0f };
|
||||||
|
|
14
src/raylib.h
14
src/raylib.h
|
@ -996,10 +996,9 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||||
// Material loading/unloading functions
|
// Material loading/unloading functions
|
||||||
RLAPI Material LoadMaterial(const char *fileName); // Load material from file
|
RLAPI Material LoadMaterial(const char *fileName); // Load material from file
|
||||||
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
||||||
RLAPI Material LoadMaterialPBR(Texture2D cubemap, Color albedo, float metalness, float roughness); // Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS...)
|
|
||||||
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
||||||
RLAPI void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture); // Set material texture
|
RLAPI void SetMaterialTexture(Material *mat, int mapType, Texture2D texture); // Set material texture
|
||||||
RLAPI void UnsetMaterialTexture(Material *mat, int texmapType); // Unset texture from material and unload it from GPU
|
RLAPI void UnsetMaterialTexture(Material *mat, int mapType); // Unset texture from material and unload it from GPU
|
||||||
|
|
||||||
// Model drawing functions
|
// Model drawing functions
|
||||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||||
|
@ -1048,10 +1047,11 @@ RLAPI void SetMatrixProjection(Matrix proj); // Set
|
||||||
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
|
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
|
||||||
|
|
||||||
// Texture maps generation (PBR)
|
// Texture maps generation (PBR)
|
||||||
RLAPI Texture2D GenTextureCubemap(Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
|
// NOTE: Required shaders should be provided
|
||||||
RLAPI Texture2D GenTextureIrradiance(Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
|
RLAPI Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
|
||||||
RLAPI Texture2D GenTexturePrefilter(Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
|
RLAPI Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
|
||||||
RLAPI Texture2D GenTextureBRDF(Texture2D cubemap, int size); // Generate BRDF texture using cubemap data
|
RLAPI Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
|
||||||
|
RLAPI Texture2D GenTextureBRDF(Shader shader, Texture2D cubemap, int size); // Generate BRDF texture using cubemap data
|
||||||
|
|
||||||
// Shading begin/end functions
|
// Shading begin/end functions
|
||||||
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
|
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
|
||||||
|
|
197
src/rlgl.c
197
src/rlgl.c
|
@ -1957,15 +1957,14 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
// Bind shader program
|
// Bind shader program
|
||||||
glUseProgram(material.shader.id);
|
glUseProgram(material.shader.id);
|
||||||
|
|
||||||
|
|
||||||
// Matrices and other values required by shader
|
// Matrices and other values required by shader
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
// Calculate and send to shader model matrix (used by PBR shader)
|
// Calculate and send to shader model matrix (used by PBR shader)
|
||||||
SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_MODEL], transform);
|
SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_MODEL], transform);
|
||||||
|
|
||||||
// Upload to shader material.colDiffuse
|
// Upload to shader material.colDiffuse
|
||||||
glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255,
|
if (material.shader.locs[LOC_COLOR_DIFFUSE] != -1)
|
||||||
|
glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255,
|
||||||
(float)material.maps[MAP_DIFFUSE].color.g/255,
|
(float)material.maps[MAP_DIFFUSE].color.g/255,
|
||||||
(float)material.maps[MAP_DIFFUSE].color.b/255,
|
(float)material.maps[MAP_DIFFUSE].color.b/255,
|
||||||
(float)material.maps[MAP_DIFFUSE].color.a/255);
|
(float)material.maps[MAP_DIFFUSE].color.a/255);
|
||||||
|
@ -1977,6 +1976,9 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
(float)material.maps[MAP_SPECULAR].color.b/255,
|
(float)material.maps[MAP_SPECULAR].color.b/255,
|
||||||
(float)material.maps[MAP_SPECULAR].color.a/255);
|
(float)material.maps[MAP_SPECULAR].color.a/255);
|
||||||
|
|
||||||
|
if (material.shader.locs[LOC_MATRIX_VIEW] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_VIEW], modelview);
|
||||||
|
if (material.shader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_PROJECTION], projection);
|
||||||
|
|
||||||
// At this point the modelview matrix just contains the view matrix (camera)
|
// At this point the modelview matrix just contains the view matrix (camera)
|
||||||
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
||||||
Matrix matView = modelview; // View matrix (camera)
|
Matrix matView = modelview; // View matrix (camera)
|
||||||
|
@ -2417,7 +2419,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||||
// Get the location of the named uniform
|
// Get the location of the named uniform
|
||||||
GLuint location = glGetUniformLocation(shader.id, name);
|
GLuint location = glGetUniformLocation(shader.id, name);
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "[SHDR ID %i] Active uniform [%s] set at location: %i", shader.id, name, location);
|
TraceLog(LOG_DEBUG, "[SHDR ID %i] Active uniform [%s] set at location: %i", shader.id, name, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2529,18 +2531,13 @@ void SetMatrixModelview(Matrix view)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate cubemap texture from HDR texture
|
// Generate cubemap texture from HDR texture
|
||||||
Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
|
Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size)
|
||||||
{
|
{
|
||||||
Texture2D cubemap = { 0 };
|
Texture2D cubemap = { 0 };
|
||||||
|
|
||||||
#define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader
|
|
||||||
#define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader
|
|
||||||
|
|
||||||
Shader shader = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS);
|
|
||||||
|
|
||||||
// Get cubemap shader locations
|
// Get cubemap shader locations
|
||||||
int projectionLoc = GetShaderLocation(shader, "projection");
|
//int projectionLoc = GetShaderLocation(shader, "projection"); // Already set at SetShaderDefaultLocations()
|
||||||
int viewLoc = GetShaderLocation(shader, "view");
|
//int viewLoc = GetShaderLocation(shader, "view"); // Already set at SetShaderDefaultLocations()
|
||||||
int texmapLoc = GetShaderLocation(shader, "equirectangularMap");
|
int texmapLoc = GetShaderLocation(shader, "equirectangularMap");
|
||||||
|
|
||||||
SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1); // Set default active texture to 0
|
SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1); // Set default active texture to 0
|
||||||
|
@ -2586,7 +2583,7 @@ Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
|
||||||
glUseProgram(shader.id);
|
glUseProgram(shader.id);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, skyHDR.id);
|
glBindTexture(GL_TEXTURE_2D, skyHDR.id);
|
||||||
SetShaderValueMatrix(shader, projectionLoc, fboProjection);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
|
||||||
|
|
||||||
// Note: don't forget to configure the viewport to the capture dimensions
|
// Note: don't forget to configure the viewport to the capture dimensions
|
||||||
glViewport(0, 0, size, size);
|
glViewport(0, 0, size, size);
|
||||||
|
@ -2594,7 +2591,7 @@ Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 6; i++)
|
for (unsigned int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_VIEW], fboViews[i]);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap.id, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap.id, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
GenDrawCube();
|
GenDrawCube();
|
||||||
|
@ -2607,8 +2604,6 @@ Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
|
||||||
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
||||||
//glEnable(GL_CULL_FACE);
|
//glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
UnloadShader(shader);
|
|
||||||
|
|
||||||
cubemap.width = size;
|
cubemap.width = size;
|
||||||
cubemap.height = size;
|
cubemap.height = size;
|
||||||
|
|
||||||
|
@ -2616,18 +2611,13 @@ Texture2D GenTextureCubemap(Texture2D skyHDR, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate irradiance texture using cubemap data
|
// Generate irradiance texture using cubemap data
|
||||||
Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
|
Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size)
|
||||||
{
|
{
|
||||||
Texture2D irradiance = { 0 };
|
Texture2D irradiance = { 0 };
|
||||||
|
|
||||||
#define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
|
|
||||||
#define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader
|
|
||||||
|
|
||||||
Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS);
|
|
||||||
|
|
||||||
// Get irradiance shader locations
|
// Get irradiance shader locations
|
||||||
int projectionLoc = GetShaderLocation(shader, "projection");
|
//int projectionLoc = GetShaderLocation(shader, "projection"); // Already set at SetShaderDefaultLocations()
|
||||||
int viewLoc = GetShaderLocation(shader, "view");
|
//int viewLoc = GetShaderLocation(shader, "view"); // Already set at SetShaderDefaultLocations()
|
||||||
int texmapLoc = GetShaderLocation(shader, "environmentMap");
|
int texmapLoc = GetShaderLocation(shader, "environmentMap");
|
||||||
|
|
||||||
// Set up shaders constant values
|
// Set up shaders constant values
|
||||||
|
@ -2669,7 +2659,7 @@ Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
|
||||||
glUseProgram(shader.id);
|
glUseProgram(shader.id);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
|
||||||
SetShaderValueMatrix(shader, projectionLoc, fboProjection);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
|
||||||
|
|
||||||
// Note: don't forget to configure the viewport to the capture dimensions
|
// Note: don't forget to configure the viewport to the capture dimensions
|
||||||
glViewport(0, 0, size, size);
|
glViewport(0, 0, size, size);
|
||||||
|
@ -2677,7 +2667,7 @@ Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 6; i++)
|
for (unsigned int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_VIEW], fboViews[i]);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradiance.id, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, irradiance.id, 0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
GenDrawCube();
|
GenDrawCube();
|
||||||
|
@ -2689,8 +2679,6 @@ Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
|
||||||
// Reset viewport dimensions to default
|
// Reset viewport dimensions to default
|
||||||
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
UnloadShader(shader);
|
|
||||||
|
|
||||||
irradiance.width = size;
|
irradiance.width = size;
|
||||||
irradiance.height = size;
|
irradiance.height = size;
|
||||||
|
|
||||||
|
@ -2698,18 +2686,13 @@ Texture2D GenTextureIrradiance(Texture2D cubemap, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate prefilter texture using cubemap data
|
// Generate prefilter texture using cubemap data
|
||||||
Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
|
Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size)
|
||||||
{
|
{
|
||||||
Texture2D prefilter = { 0 };
|
Texture2D prefilter = { 0 };
|
||||||
|
|
||||||
#define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader
|
|
||||||
#define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" // Path to reflection prefilter calculation fragment shader
|
|
||||||
|
|
||||||
Shader shader = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS);
|
|
||||||
|
|
||||||
// Get prefilter shader locations
|
// Get prefilter shader locations
|
||||||
int projectionLoc = GetShaderLocation(shader, "projection");
|
//int projectionLoc = GetShaderLocation(shader, "projection"); // Already set at SetShaderDefaultLocations()
|
||||||
int viewLoc = GetShaderLocation(shader, "view");
|
//int viewLoc = GetShaderLocation(shader, "view"); // Already set at SetShaderDefaultLocations()
|
||||||
int roughnessLoc = GetShaderLocation(shader, "roughness");
|
int roughnessLoc = GetShaderLocation(shader, "roughness");
|
||||||
int texmapLoc = GetShaderLocation(shader, "environmentMap");
|
int texmapLoc = GetShaderLocation(shader, "environmentMap");
|
||||||
|
|
||||||
|
@ -2754,7 +2737,7 @@ Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
|
||||||
glUseProgram(shader.id);
|
glUseProgram(shader.id);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
|
||||||
SetShaderValueMatrix(shader, projectionLoc, fboProjection);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
|
||||||
|
@ -2775,7 +2758,7 @@ Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 6; ++i)
|
for (unsigned int i = 0; i < 6; ++i)
|
||||||
{
|
{
|
||||||
SetShaderValueMatrix(shader, viewLoc, fboViews[i]);
|
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_VIEW], fboViews[i]);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, prefilter.id, mip);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, prefilter.id, mip);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
GenDrawCube();
|
GenDrawCube();
|
||||||
|
@ -2788,8 +2771,6 @@ Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
|
||||||
// Reset viewport dimensions to default
|
// Reset viewport dimensions to default
|
||||||
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
UnloadShader(shader);
|
|
||||||
|
|
||||||
prefilter.width = size;
|
prefilter.width = size;
|
||||||
prefilter.height = size;
|
prefilter.height = size;
|
||||||
|
|
||||||
|
@ -2797,15 +2778,10 @@ Texture2D GenTexturePrefilter(Texture2D cubemap, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate BRDF texture using cubemap data
|
// Generate BRDF texture using cubemap data
|
||||||
Texture2D GenTextureBRDF(Texture2D cubemap, int size)
|
Texture2D GenTextureBRDF(Shader shader, Texture2D cubemap, int size)
|
||||||
{
|
{
|
||||||
Texture2D brdf = { 0 };
|
Texture2D brdf = { 0 };
|
||||||
|
|
||||||
#define PATH_BRDF_VS "resources/shaders/brdf.vs" // Path to bidirectional reflectance distribution function vertex shader
|
|
||||||
#define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader
|
|
||||||
|
|
||||||
Shader shader = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS);
|
|
||||||
|
|
||||||
// Generate BRDF convolution texture
|
// Generate BRDF convolution texture
|
||||||
glGenTextures(1, &brdf.id);
|
glGenTextures(1, &brdf.id);
|
||||||
glBindTexture(GL_TEXTURE_2D, brdf.id);
|
glBindTexture(GL_TEXTURE_2D, brdf.id);
|
||||||
|
@ -2835,8 +2811,6 @@ Texture2D GenTextureBRDF(Texture2D cubemap, int size)
|
||||||
// Reset viewport dimensions to default
|
// Reset viewport dimensions to default
|
||||||
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
UnloadShader(shader);
|
|
||||||
|
|
||||||
brdf.width = size;
|
brdf.width = size;
|
||||||
brdf.height = size;
|
brdf.height = size;
|
||||||
|
|
||||||
|
@ -3380,6 +3354,8 @@ static void SetShaderDefaultLocations(Shader *shader)
|
||||||
|
|
||||||
// Get handles to GLSL uniform locations (vertex shader)
|
// Get handles to GLSL uniform locations (vertex shader)
|
||||||
shader->locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader->id, "mvpMatrix");
|
shader->locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader->id, "mvpMatrix");
|
||||||
|
shader->locs[LOC_MATRIX_PROJECTION] = glGetUniformLocation(shader->id, "projection");
|
||||||
|
shader->locs[LOC_MATRIX_VIEW] = glGetUniformLocation(shader->id, "view");
|
||||||
|
|
||||||
// Get handles to GLSL uniform locations (fragment shader)
|
// Get handles to GLSL uniform locations (fragment shader)
|
||||||
shader->locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader->id, "colDiffuse");
|
shader->locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader->id, "colDiffuse");
|
||||||
|
@ -3894,9 +3870,9 @@ static void GenDrawQuad(void)
|
||||||
|
|
||||||
// Link vertex attributes
|
// Link vertex attributes
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float)));
|
||||||
|
|
||||||
// Draw quad
|
// Draw quad
|
||||||
glBindVertexArray(quadVAO);
|
glBindVertexArray(quadVAO);
|
||||||
|
@ -3908,79 +3884,76 @@ static void GenDrawQuad(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders a 1x1 3D cube in NDC
|
// Renders a 1x1 3D cube in NDC
|
||||||
GLuint cubeVAO = 0;
|
|
||||||
GLuint cubeVBO = 0;
|
|
||||||
static void GenDrawCube(void)
|
static void GenDrawCube(void)
|
||||||
{
|
{
|
||||||
// Lazy initialization
|
unsigned int cubeVAO = 0;
|
||||||
if (cubeVAO == 0)
|
unsigned int cubeVBO = 0;
|
||||||
{
|
|
||||||
GLfloat vertices[] = {
|
|
||||||
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f , 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
|
||||||
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
|
||||||
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set up cube VAO
|
float vertices[] = {
|
||||||
glGenVertexArrays(1, &cubeVAO);
|
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
glGenBuffers(1, &cubeVBO);
|
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f , 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
// Fill buffer
|
// Set up cube VAO
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
|
glGenVertexArrays(1, &cubeVAO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
glGenBuffers(1, &cubeVBO);
|
||||||
|
|
||||||
// Link vertex attributes
|
// Fill buffer
|
||||||
glBindVertexArray(cubeVAO);
|
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
|
||||||
glEnableVertexAttribArray(0);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)0);
|
|
||||||
glEnableVertexAttribArray(1);
|
// Link vertex attributes
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
|
glBindVertexArray(cubeVAO);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (GLvoid*)(6*sizeof(GLfloat)));
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glEnableVertexAttribArray(1);
|
||||||
glBindVertexArray(0);
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float)));
|
||||||
}
|
glEnableVertexAttribArray(2);
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float)));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// Draw cube
|
// Draw cube
|
||||||
glBindVertexArray(cubeVAO);
|
glBindVertexArray(cubeVAO);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
//glDeleteBuffers(1, &cubeVBO);
|
glDeleteBuffers(1, &cubeVBO);
|
||||||
//glDeleteVertexArrays(1, &cubeVAO);
|
glDeleteVertexArrays(1, &cubeVAO);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
#if defined(SUPPORT_VR_SIMULATOR)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue