Manual integration of material-pbr into develop

This commit is contained in:
Ray 2017-07-17 00:33:40 +02:00
parent 025dab9907
commit 6546474fa4
13 changed files with 1595 additions and 546 deletions

View file

@ -25,11 +25,13 @@ int main()
Image image = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM) Image image = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM)
Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM) Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM)
Model map = LoadCubicmap(image); // Load cubicmap model (generate model from image)
Mesh mesh = GenMeshCubicmap(image, VectorOne());
Model model = LoadModelFromMesh(mesh, false);
// NOTE: By default each cube is mapped to one part of texture atlas // NOTE: By default each cube is mapped to one part of texture atlas
Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture
map.material.texDiffuse = texture; // Set map diffuse texture model.material.maps[TEXMAP_DIFFUSE].tex = texture; // Set map diffuse texture
Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
@ -56,7 +58,7 @@ int main()
Begin3dMode(camera); Begin3dMode(camera);
DrawModel(map, mapPosition, 1.0f, WHITE); DrawModel(model, mapPosition, 1.0f, WHITE);
End3dMode(); End3dMode();
@ -76,7 +78,7 @@ int main()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadTexture(cubicmap); // Unload cubicmap texture UnloadTexture(cubicmap); // Unload cubicmap texture
UnloadTexture(texture); // Unload map texture UnloadTexture(texture); // Unload map texture
UnloadModel(map); // Unload map model UnloadModel(model); // Unload map model
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View file

@ -0,0 +1,185 @@
/*******************************************************************************************
*
* raylib [models] example - PBR material
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#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
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;
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()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available)
InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material");
// Define the camera to look into our 3d world
Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
// Load model and PBR material
Model model = LoadModel("resources/pbr/trooper.obj");
Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
SetMaterialTexture(&model.material, TEXMAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png"));
SetMaterialTexture(&model.material, TEXMAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png"));
SetMaterialTexture(&model.material, TEXMAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png"));
SetMaterialTexture(&model.material, TEXMAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png"));
SetMaterialTexture(&model.material, TEXMAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png"));
// Set textures filtering for better quality
SetTextureFilter(model.material.maps[TEXMAP_ALBEDO].tex, FILTER_BILINEAR);
SetTextureFilter(model.material.maps[TEXMAP_NORMAL].tex, FILTER_BILINEAR);
SetTextureFilter(model.material.maps[TEXMAP_METALNESS].tex, FILTER_BILINEAR);
SetTextureFilter(model.material.maps[TEXMAP_ROUGHNESS].tex, FILTER_BILINEAR);
SetTextureFilter(model.material.maps[TEXMAP_OCCLUSION].tex, 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
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),
CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 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) };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update camera
// Send to material PBR shader camera view position
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
SetShaderValue(model.material.shader, model.material.shader.locs[LOC_VECTOR_VIEW], cameraPos, 3);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
DrawModel(model, VectorZero(), 1.0f, WHITE);
DrawGrid(10, 1.0f);
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(model); // Unload skybox model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
// 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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View file

@ -0,0 +1,89 @@
/*******************************************************************************************
*
* raylib [models] example - Skybox loading and drawing
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
// Define the camera to look into our 3d world
Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
// Load skybox model and shader
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
Model skybox = LoadModelFromMesh(cube, false);
skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
Texture2D texHDR = LoadTexture("resources/pinetree.hdr");
skybox.material.maps[TEXMAP_CUBEMAP].tex = rlGenMapCubemap(texHDR, 512);
SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ TEXMAP_CUBEMAP }, 1);
// Get skybox shader locations
skybox.material.shader.locs[LOC_MATRIX_PROJECTION] = GetShaderLocation(skybox.material.shader, "projection");
skybox.material.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(skybox.material.shader, "view");
// Then before rendering, configure the viewport to the actual screen dimensions
Matrix proj = MatrixPerspective(60.0, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
MatrixTranspose(&proj);
SetShaderValueMatrix(skybox.material.shader, skybox.material.shader.locs[LOC_MATRIX_PROJECTION], proj);
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update camera
Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
SetShaderValueMatrix(skybox.material.shader, skybox.material.shader.locs[LOC_MATRIX_VIEW], view);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
DrawModel(skybox, VectorZero(), 1.0f, RED);
DrawGrid(10, 1.0f);
End3dMode();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(skybox); // Unload skybox model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 KiB

View file

@ -38,7 +38,7 @@ int main()
"resources/shaders/glsl330/grayscale.fs"); // Load model shader "resources/shaders/glsl330/grayscale.fs"); // Load model shader
dwarf.material.shader = shader; // Set shader effect to 3d model dwarf.material.shader = shader; // Set shader effect to 3d model
dwarf.material.texDiffuse = texture; // Bind texture to model dwarf.material.maps[TEXMAP_DIFFUSE].tex = texture; // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View file

@ -809,7 +809,7 @@ void EndDrawing(void)
{ {
// Get image data for the current frame (from backbuffer) // Get image data for the current frame (from backbuffer)
// NOTE: This process is very slow... :( // NOTE: This process is very slow... :(
unsigned char *screenData = rlglReadScreenPixels(screenWidth, screenHeight); unsigned char *screenData = rlReadScreenPixels(screenWidth, screenHeight);
GifWriteFrame(screenData, screenWidth, screenHeight, 10, 8, false); GifWriteFrame(screenData, screenWidth, screenHeight, 10, 8, false);
free(screenData); // Free image data free(screenData); // Free image data
@ -994,10 +994,10 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
MatrixTranspose(&matView); MatrixTranspose(&matView);
//#define USE_RLGL_UNPROJECT //#define USE_RLGL_UNPROJECT
#if defined(USE_RLGL_UNPROJECT) // OPTION 1: Use rlglUnproject() #if defined(USE_RLGL_UNPROJECT) // OPTION 1: Use rlUnproject()
Vector3 nearPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView); Vector3 nearPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView); Vector3 farPoint = rlUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
#else // OPTION 2: Compute unprojection directly here #else // OPTION 2: Compute unprojection directly here
@ -1201,7 +1201,7 @@ void SetConfigFlags(char flags)
void TakeScreenshot(const char *fileName) void TakeScreenshot(const char *fileName)
{ {
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight); unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG
free(imgData); free(imgData);

View file

@ -76,9 +76,6 @@ static Mesh LoadOBJ(const char *fileName); // Load OBJ mesh data
static Material LoadMTL(const char *fileName); // Load MTL material data static Material LoadMTL(const char *fileName); // Load MTL material data
#endif #endif
static Mesh GenMeshHeightmap(Image image, Vector3 size);
static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -587,110 +584,32 @@ void DrawGizmo(Vector3 position)
rlPopMatrix(); rlPopMatrix();
} }
// Load mesh from file // Load model from files (mesh and material)
Mesh LoadMesh(const char *fileName)
{
Mesh mesh = { 0 };
#if defined(SUPPORT_FILEFORMAT_OBJ)
if (IsFileExtension(fileName, ".obj")) mesh = LoadOBJ(fileName);
#else
TraceLog(LOG_WARNING, "[%s] Mesh fileformat not supported, it can't be loaded", fileName);
#endif
if (mesh.vertexCount == 0) TraceLog(LOG_WARNING, "Mesh could not be loaded");
else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
// TODO: Initialize default mesh data in case loading fails, maybe a cube?
return mesh;
}
// Load mesh from vertex data
// NOTE: All vertex data arrays must be same size: vertexCount
Mesh LoadMeshEx(int vertexCount, float *vData, float *vtData, float *vnData, Color *cData)
{
Mesh mesh = { 0 };
mesh.vertexCount = vertexCount;
mesh.triangleCount = vertexCount/3;
mesh.vertices = vData;
mesh.texcoords = vtData;
mesh.texcoords2 = NULL;
mesh.normals = vnData;
mesh.tangents = NULL;
mesh.colors = (unsigned char *)cData;
mesh.indices = NULL;
rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
return mesh;
}
// Load model from file
Model LoadModel(const char *fileName) Model LoadModel(const char *fileName)
{ {
Model model = { 0 }; Model model = { 0 };
model.mesh = LoadMesh(fileName); model.mesh = LoadMesh(fileName);
model.transform = MatrixIdentity(); model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial(); model.material = LoadMaterialDefault();
return model; return model;
} }
// Load model from mesh data // Load model from generated mesh
Model LoadModelFromMesh(Mesh data, bool dynamic) Model LoadModelFromMesh(Mesh mesh, bool dynamic)
{ {
Model model = { 0 }; Model model = { 0 };
model.mesh = data; rlLoadMesh(&mesh, dynamic);
rlglLoadMesh(&model.mesh, dynamic); // Upload vertex data to GPU
model.mesh = mesh;
model.transform = MatrixIdentity(); model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial(); model.material = LoadMaterialDefault();
return model; return model;
} }
// Load heightmap model from image data
// NOTE: model map size is defined in generic units
Model LoadHeightmap(Image heightmap, Vector3 size)
{
Model model = { 0 };
model.mesh = GenMeshHeightmap(heightmap, size);
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
return model;
}
// Load cubes-based map model from image data
Model LoadCubicmap(Image cubicmap)
{
Model model = { 0 };
model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0f, 1.5f, 1.0f });
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
return model;
}
// Unload mesh from memory (RAM and/or VRAM)
void UnloadMesh(Mesh *mesh)
{
rlglUnloadMesh(mesh);
}
// Unload model from memory (RAM and/or VRAM) // Unload model from memory (RAM and/or VRAM)
void UnloadModel(Model model) void UnloadModel(Model model)
{ {
@ -700,49 +619,190 @@ void UnloadModel(Model model)
TraceLog(LOG_INFO, "Unloaded model data (mesh and material) from RAM and VRAM"); TraceLog(LOG_INFO, "Unloaded model data (mesh and material) from RAM and VRAM");
} }
// Load material data (from file) // Load mesh from file
Material LoadMaterial(const char *fileName) Mesh LoadMesh(const char *fileName)
{ {
Material material = { 0 }; Mesh mesh = { 0 };
#if defined(SUPPORT_FILEFORMAT_MTL) #if defined(SUPPORT_FILEFORMAT_OBJ)
if (IsFileExtension(fileName, ".mtl")) material = LoadMTL(fileName); if (IsFileExtension(fileName, ".obj")) mesh = LoadOBJ(fileName);
#else #else
TraceLog(LOG_WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName); TraceLog(WARNING, "[%s] Mesh fileformat not supported, it can't be loaded", fileName);
#endif #endif
return material; if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded");
else rlLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
// TODO: Initialize default mesh data in case loading fails, maybe a cube?
return mesh;
} }
// Load default material (uses default models shader) // Unload mesh from memory (RAM and/or VRAM)
Material LoadDefaultMaterial(void) void UnloadMesh(Mesh *mesh)
{ {
Material material = { 0 }; rlUnloadMesh(mesh);
material.shader = GetDefaultShader();
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set
//material.texSpecular; // NOTE: By default, not set
material.colDiffuse = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient color
material.colSpecular = WHITE; // Specular color
material.glossiness = 100.0f; // Glossiness level
return material;
} }
// Unload material from memory // Generated cuboid mesh
void UnloadMaterial(Material material) Mesh GenMeshCube(float width, float height, float length)
{ {
rlDeleteTextures(material.texDiffuse.id); Mesh mesh = { 0 };
rlDeleteTextures(material.texNormal.id); /*
rlDeleteTextures(material.texSpecular.id); float 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
};
*/
float vertices[] = {
-width/2, -height/2, length/2,
width/2, -height/2, length/2,
width/2, height/2, length/2,
-width/2, height/2, length/2,
-width/2, -height/2, -length/2,
-width/2, height/2, -length/2,
width/2, height/2, -length/2,
width/2, -height/2, -length/2,
-width/2, height/2, -length/2,
-width/2, height/2, length/2,
width/2, height/2, length/2,
width/2, height/2, -length/2,
-width/2, -height/2, -length/2,
width/2, -height/2, -length/2,
width/2, -height/2, length/2,
-width/2, -height/2, length/2,
width/2, -height/2, -length/2,
width/2, height/2, -length/2,
width/2, height/2, length/2,
width/2, -height/2, length/2,
-width/2, -height/2, -length/2,
-width/2, -height/2, length/2,
-width/2, height/2, length/2,
-width/2, height/2, -length/2
};
float texcoords[] = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
float normals[] = {
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f
};
mesh.vertices = (float *)malloc(24*3*sizeof(float));
memcpy(mesh.vertices, vertices, 24*3*sizeof(float));
mesh.texcoords = (float *)malloc(24*2*sizeof(float));
memcpy(mesh.texcoords, texcoords, 24*2*sizeof(float));
mesh.normals = (float *)malloc(24*3*sizeof(float));
memcpy(mesh.normals, normals, 24*3*sizeof(float));
mesh.indices = (unsigned short *)malloc(36*sizeof(unsigned short));
int k = 0;
// Indices can be initialized right now
for (int i = 0; i < 36; i+=6)
{
mesh.indices[i] = 4*k;
mesh.indices[i+1] = 4*k+1;
mesh.indices[i+2] = 4*k+2;
mesh.indices[i+3] = 4*k;
mesh.indices[i+4] = 4*k+2;
mesh.indices[i+5] = 4*k+3;
k++;
}
mesh.vertexCount = 24;
mesh.triangleCount = 12;
return mesh;
} }
// Generate a mesh from heightmap // Generate a mesh from heightmap
static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
{ {
#define GRAY_VALUE(c) ((c.r+c.g+c.b)/3) #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
@ -847,7 +907,7 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
return mesh; return mesh;
} }
static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
{ {
Mesh mesh = { 0 }; Mesh mesh = { 0 };
@ -1201,6 +1261,202 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
return mesh; return mesh;
} }
// Load material data (from file)
Material LoadMaterial(const char *fileName)
{
Material material = { 0 };
#if defined(SUPPORT_FILEFORMAT_MTL)
if (IsFileExtension(fileName, ".mtl")) material = LoadMTL(fileName);
#else
TraceLog(WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
#endif
return material;
}
// Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
Material LoadMaterialDefault(void)
{
Material material = { 0 };
material.shader = GetShaderDefault();
material.maps[TEXMAP_DIFFUSE].tex = GetTextureDefault(); // White texture (1x1 pixel)
//material.maps[TEXMAP_NORMAL].tex; // NOTE: By default, not set
//material.maps[TEXMAP_SPECULAR].tex; // NOTE: By default, not set
material.maps[TEXMAP_DIFFUSE].color = WHITE; // Diffuse color
material.maps[TEXMAP_SPECULAR].color = WHITE; // Specular color
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 };
#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_TEXMAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
mat.shader.locs[LOC_TEXMAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
mat.shader.locs[LOC_TEXMAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
mat.shader.locs[LOC_TEXMAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
mat.shader.locs[LOC_TEXMAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
mat.shader.locs[LOC_TEXMAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
mat.shader.locs[LOC_TEXMAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
mat.shader.locs[LOC_TEXMAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
mat.shader.locs[LOC_TEXMAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
mat.shader.locs[LOC_TEXMAP_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[TEXMAP_ALBEDO].color = albedo;
mat.maps[TEXMAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
mat.maps[TEXMAP_METALNESS].value = metalness;
mat.maps[TEXMAP_ROUGHNESS].value = roughness;
mat.maps[TEXMAP_OCCLUSION].value = 1.0f;
mat.maps[TEXMAP_EMISSION].value = 0.0f;
mat.maps[TEXMAP_HEIGHT].value = 0.0f;
#define CUBEMAP_SIZE 1024 // 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 = rlGenMapCubemap(hdr, CUBEMAP_SIZE);
mat.maps[TEXMAP_IRRADIANCE].tex = rlGenMapIrradiance(cubemap, IRRADIANCE_SIZE);
mat.maps[TEXMAP_PREFILTER].tex = rlGenMapPrefilter(cubemap, PREFILTERED_SIZE);
mat.maps[TEXMAP_BRDF].tex = rlGenMapBRDF(cubemap, BRDF_SIZE);
UnloadTexture(cubemap);
// NOTE: All maps textures are set to { 0 }
// Reset viewport dimensions to default
rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
return mat;
}
// Unload material from memory
void UnloadMaterial(Material material)
{
// Unload material shader
UnloadShader(material.shader);
// Unload loaded texture maps
for (int i = 0; i < MAX_MATERIAL_TEXTURE_MAPS; i++)
{
// NOTE: We already check for (tex.id > 0) inside function
rlDeleteTextures(material.maps[i].tex.id);
}
}
// Set material texture
void SetMaterialTexture(Material *mat, int texmapType, Texture2D texture)
{
mat->maps[texmapType].tex = texture;
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
int location = -1;
switch (texmapType)
{
case TEXMAP_ALBEDO:
{
location = GetShaderLocation(mat->shader, "albedo.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_NORMAL:
{
location = GetShaderLocation(mat->shader, "normals.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_METALNESS:
{
location = GetShaderLocation(mat->shader, "metalness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_ROUGHNESS:
{
location = GetShaderLocation(mat->shader, "roughness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_OCCLUSION:
{
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_EMISSION:
{
location = GetShaderLocation(mat->shader, "emission.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
case TEXMAP_HEIGHT:
{
location = GetShaderLocation(mat->shader, "height.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 1 }, 1);
} break;
}
}
// Unset texture from material and unload it from GPU
void UnsetMaterialTexture(Material *mat, int texmapType)
{
UnloadTexture(mat->maps[texmapType].tex);
mat->maps[texmapType].tex = (Texture2D){ 0 };
// Update MaterialProperty use sampler state to use texture fetch instead of color attribute
int location = -1;
switch (texmapType)
{
case TEXMAP_ALBEDO:
{
location = GetShaderLocation(mat->shader, "albedo.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_NORMAL:
{
location = GetShaderLocation(mat->shader, "normals.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_METALNESS:
{
location = GetShaderLocation(mat->shader, "metalness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_ROUGHNESS:
{
location = GetShaderLocation(mat->shader, "roughness.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_OCCLUSION:
{
location = GetShaderLocation(mat->shader, "occlusion.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_EMISSION:
{
location = GetShaderLocation(mat->shader, "emission.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
case TEXMAP_HEIGHT:
{
location = GetShaderLocation(mat->shader, "height.useSampler");
SetShaderValuei(mat->shader, location, (int [1]){ 0 }, 1);
} break;
}
}
// Draw a model (with texture if set) // Draw a model (with texture if set)
void DrawModel(Model model, Vector3 position, float scale, Color tint) void DrawModel(Model model, Vector3 position, float scale, Color tint)
{ {
@ -1225,9 +1481,9 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates //Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
model.transform = MatrixMultiply(model.transform, matTransform); model.transform = MatrixMultiply(model.transform, matTransform);
model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color? model.material.maps[TEXMAP_DIFFUSE].color = tint; // TODO: Multiply tint color by diffuse color?
rlglDrawMesh(model.mesh, model.material, model.transform); rlDrawMesh(model.mesh, model.material, model.transform);
} }
// Draw a model wires (with texture if set) // Draw a model wires (with texture if set)
@ -1980,23 +2236,24 @@ static Material LoadMTL(const char *fileName)
case 'a': // Ka float float float Ambient color (RGB) case 'a': // Ka float float float Ambient color (RGB)
{ {
sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Ka %f %f %f", &color.x, &color.y, &color.z);
material.colAmbient.r = (unsigned char)(color.x*255); // TODO: Support ambient color
material.colAmbient.g = (unsigned char)(color.y*255); //material.colAmbient.r = (unsigned char)(color.x*255);
material.colAmbient.b = (unsigned char)(color.z*255); //material.colAmbient.g = (unsigned char)(color.y*255);
//material.colAmbient.b = (unsigned char)(color.z*255);
} break; } break;
case 'd': // Kd float float float Diffuse color (RGB) case 'd': // Kd float float float Diffuse color (RGB)
{ {
sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Kd %f %f %f", &color.x, &color.y, &color.z);
material.colDiffuse.r = (unsigned char)(color.x*255); material.maps[TEXMAP_DIFFUSE].color.r = (unsigned char)(color.x*255);
material.colDiffuse.g = (unsigned char)(color.y*255); material.maps[TEXMAP_DIFFUSE].color.g = (unsigned char)(color.y*255);
material.colDiffuse.b = (unsigned char)(color.z*255); material.maps[TEXMAP_DIFFUSE].color.b = (unsigned char)(color.z*255);
} break; } break;
case 's': // Ks float float float Specular color (RGB) case 's': // Ks float float float Specular color (RGB)
{ {
sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z); sscanf(buffer, "Ks %f %f %f", &color.x, &color.y, &color.z);
material.colSpecular.r = (unsigned char)(color.x*255); material.maps[TEXMAP_SPECULAR].color.r = (unsigned char)(color.x*255);
material.colSpecular.g = (unsigned char)(color.y*255); material.maps[TEXMAP_SPECULAR].color.g = (unsigned char)(color.y*255);
material.colSpecular.b = (unsigned char)(color.z*255); material.maps[TEXMAP_SPECULAR].color.b = (unsigned char)(color.z*255);
} break; } break;
case 'e': // Ke float float float Emmisive color (RGB) case 'e': // Ke float float float Emmisive color (RGB)
{ {
@ -2012,7 +2269,7 @@ static Material LoadMTL(const char *fileName)
int shininess = 0; int shininess = 0;
sscanf(buffer, "Ns %i", &shininess); sscanf(buffer, "Ns %i", &shininess);
material.glossiness = (float)shininess; //material.params[PARAM_GLOSSINES] = (float)shininess;
} }
else if (buffer[1] == 'i') // Ni int Refraction index. else if (buffer[1] == 'i') // Ni int Refraction index.
{ {
@ -2028,12 +2285,12 @@ static Material LoadMTL(const char *fileName)
if (buffer[5] == 'd') // map_Kd string Diffuse color texture map. if (buffer[5] == 'd') // map_Kd string Diffuse color texture map.
{ {
result = sscanf(buffer, "map_Kd %s", mapFileName); result = sscanf(buffer, "map_Kd %s", mapFileName);
if (result != EOF) material.texDiffuse = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_DIFFUSE].tex = LoadTexture(mapFileName);
} }
else if (buffer[5] == 's') // map_Ks string Specular color texture map. else if (buffer[5] == 's') // map_Ks string Specular color texture map.
{ {
result = sscanf(buffer, "map_Ks %s", mapFileName); result = sscanf(buffer, "map_Ks %s", mapFileName);
if (result != EOF) material.texSpecular = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_SPECULAR].tex = LoadTexture(mapFileName);
} }
else if (buffer[5] == 'a') // map_Ka string Ambient color texture map. else if (buffer[5] == 'a') // map_Ka string Ambient color texture map.
{ {
@ -2043,12 +2300,12 @@ static Material LoadMTL(const char *fileName)
case 'B': // map_Bump string Bump texture map. case 'B': // map_Bump string Bump texture map.
{ {
result = sscanf(buffer, "map_Bump %s", mapFileName); result = sscanf(buffer, "map_Bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'b': // map_bump string Bump texture map. case 'b': // map_bump string Bump texture map.
{ {
result = sscanf(buffer, "map_bump %s", mapFileName); result = sscanf(buffer, "map_bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'd': // map_d string Opacity texture map. case 'd': // map_d string Opacity texture map.
{ {
@ -2063,7 +2320,7 @@ static Material LoadMTL(const char *fileName)
{ {
float alpha = 1.0f; float alpha = 1.0f;
sscanf(buffer, "d %f", &alpha); sscanf(buffer, "d %f", &alpha);
material.colDiffuse.a = (unsigned char)(alpha*255); material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)(alpha*255);
} }
else if (buffer[1] == 'i') // disp string Displacement map else if (buffer[1] == 'i') // disp string Displacement map
{ {
@ -2073,13 +2330,13 @@ static Material LoadMTL(const char *fileName)
case 'b': // bump string Bump texture map case 'b': // bump string Bump texture map
{ {
result = sscanf(buffer, "bump %s", mapFileName); result = sscanf(buffer, "bump %s", mapFileName);
if (result != EOF) material.texNormal = LoadTexture(mapFileName); if (result != EOF) material.maps[TEXMAP_NORMAL].tex = LoadTexture(mapFileName);
} break; } break;
case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d case 'T': // Tr float Transparency Tr (alpha). Tr is inverse of d
{ {
float ialpha = 0.0f; float ialpha = 0.0f;
sscanf(buffer, "Tr %f", &ialpha); sscanf(buffer, "Tr %f", &ialpha);
material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255); material.maps[TEXMAP_DIFFUSE].color.a = (unsigned char)((1.0f - ialpha)*255);
} break; } break;
case 'r': // refl string Reflection texture map case 'r': // refl string Reflection texture map

View file

@ -291,6 +291,11 @@
#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta #define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta
#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo) #define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo)
// Shader and material limits
#define MAX_SHADER_LOCATIONS 32
#define MAX_MATERIAL_TEXTURE_MAPS 12
#define MAX_MATERIAL_PARAMS 8
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Structures Definition // Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -420,43 +425,24 @@ typedef struct Mesh {
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader type (generic)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
int normalLoc; // Normal attribute location point (default-location = 2)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int colorLoc; // Color attibute location point (default-location = 3)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int colDiffuseLoc; // Diffuse color uniform location point (fragment shader)
int colAmbientLoc; // Ambient color uniform location point (fragment shader)
int colSpecularLoc; // Specular color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Material type // Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map textures) Shader shader;
TextureMap maps[MAX_MATERIAL_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_TEXTURE_MAPS
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Model type // Model type
@ -540,6 +526,54 @@ typedef enum {
LOG_OTHER LOG_OTHER
} LogType; } LogType;
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
LOC_VERTEX_TEXCOORD02,
LOC_VERTEX_NORMAL,
LOC_VERTEX_TANGENT,
LOC_VERTEX_COLOR,
LOC_MATRIX_MVP,
LOC_MATRIX_MODEL,
LOC_MATRIX_VIEW,
LOC_MATRIX_PROJECTION,
LOC_VECTOR_VIEW,
LOC_COLOR_DIFFUSE,
LOC_COLOR_SPECULAR,
LOC_COLOR_AMBIENT,
LOC_TEXMAP_ALBEDO, // LOC_TEXMAP_DIFFUSE
LOC_TEXMAP_METALNESS, // LOC_TEXMAP_SPECULAR
LOC_TEXMAP_NORMAL,
LOC_TEXMAP_ROUGHNESS,
LOC_TEXMAP_OCCUSION,
LOC_TEXMAP_EMISSION,
LOC_TEXMAP_HEIGHT,
LOC_TEXMAP_CUBEMAP,
LOC_TEXMAP_IRRADIANCE,
LOC_TEXMAP_PREFILTER,
LOC_TEXMAP_BRDF
} ShaderLocationIndex;
#define LOC_TEXMAP_DIFFUSE LOC_TEXMAP_ALBEDO
#define LOC_TEXMAP_SPECULAR LOC_TEXMAP_METALNESS
typedef enum {
TEXMAP_ALBEDO = 0, // TEXMAP_DIFFUSE
TEXMAP_METALNESS = 1, // TEXMAP_SPECULAR
TEXMAP_NORMAL = 2,
TEXMAP_ROUGHNESS = 3,
TEXMAP_OCCLUSION,
TEXMAP_EMISSION,
TEXMAP_HEIGHT,
TEXMAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_BRDF
} TexmapIndex;
#define TEXMAP_DIFFUSE TEXMAP_ALBEDO
#define TEXMAP_SPECULAR TEXMAP_METALNESS
// Texture formats // Texture formats
// NOTE: Support depends on OpenGL version and platform // NOTE: Support depends on OpenGL version and platform
typedef enum { typedef enum {
@ -944,19 +978,26 @@ RLAPI void DrawGizmo(Vector3 position);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Model loading/unloading functions // Model loading/unloading functions
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file RLAPI Model LoadModel(const char *fileName); // Load model from files (mesh and material)
RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data RLAPI Model LoadModelFromMesh(Mesh mesh, bool dynamic); // Load model from generated mesh
RLAPI Model LoadModel(const char *fileName); // Load model from file
RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data
RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data
RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM)
// Mesh loading/unloading functions
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
//RLAPI void UpdateMesh(Mesh *mesh, int type, void *data); // Update mesh data (CPU and GPU)
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// 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 LoadDefaultMaterial(void); // Load default material (uses default models shader) 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 UnsetMaterialTexture(Material *mat, int texmapType); // 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)
@ -993,8 +1034,10 @@ RLAPI char *LoadText(const char *fileName); // Loa
RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetShaderDefault(void); // Get default shader
RLAPI Texture2D GetDefaultTexture(void); // Get default texture RLAPI Texture2D GetTextureDefault(void); // Get default texture
RLAPI Texture2D rlGenMapCubemap(Texture2D skyHDR, int size); // Generate cubemap texture map from HDR texture
// Shader configuration functions // Shader configuration functions
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location

File diff suppressed because it is too large Load diff

View file

@ -146,6 +146,54 @@ typedef unsigned char byte;
typedef enum { false, true } bool; typedef enum { false, true } bool;
#endif #endif
typedef enum {
LOC_VERTEX_POSITION = 0,
LOC_VERTEX_TEXCOORD01,
LOC_VERTEX_TEXCOORD02,
LOC_VERTEX_NORMAL,
LOC_VERTEX_TANGENT,
LOC_VERTEX_COLOR,
LOC_MATRIX_MVP,
LOC_MATRIX_MODEL,
LOC_MATRIX_VIEW,
LOC_MATRIX_PROJECTION,
LOC_VECTOR_VIEW,
LOC_COLOR_DIFFUSE,
LOC_COLOR_SPECULAR,
LOC_COLOR_AMBIENT,
LOC_TEXMAP_ALBEDO, // LOC_TEXMAP_DIFFUSE
LOC_TEXMAP_METALNESS, // LOC_TEXMAP_SPECULAR
LOC_TEXMAP_NORMAL,
LOC_TEXMAP_ROUGHNESS,
LOC_TEXMAP_OCCUSION,
LOC_TEXMAP_EMISSION,
LOC_TEXMAP_HEIGHT,
LOC_TEXMAP_CUBEMAP,
LOC_TEXMAP_IRRADIANCE,
LOC_TEXMAP_PREFILTER,
LOC_TEXMAP_BRDF
} ShaderLocationIndex;
#define LOC_TEXMAP_DIFFUSE LOC_TEXMAP_ALBEDO
#define LOC_TEXMAP_SPECULAR LOC_TEXMAP_METALNESS
typedef enum {
TEXMAP_ALBEDO = 0, // TEXMAP_DIFFUSE
TEXMAP_METALNESS = 1, // TEXMAP_SPECULAR
TEXMAP_NORMAL = 2,
TEXMAP_ROUGHNESS = 3,
TEXMAP_OCCLUSION,
TEXMAP_EMISSION,
TEXMAP_HEIGHT,
TEXMAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
TEXMAP_BRDF
} TexmapIndex;
#define TEXMAP_DIFFUSE TEXMAP_ALBEDO
#define TEXMAP_SPECULAR TEXMAP_METALNESS
// Color type, RGBA (32bit) // Color type, RGBA (32bit)
typedef struct Color { typedef struct Color {
unsigned char r; unsigned char r;
@ -187,43 +235,29 @@ typedef unsigned char byte;
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh; } Mesh;
// Shader type (generic shader) // Shader and material limits
#define MAX_SHADER_LOCATIONS 32
#define MAX_MATERIAL_TEXTURE_MAPS 12
#define MAX_MATERIAL_PARAMS 8
// Shader type (generic)
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int locs[MAX_SHADER_LOCATIONS]; // Initialized on LoadShader(), set to MAX_SHADER_LOCATIONS
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int normalLoc; // Normal attribute location point (default-location = 2)
int colorLoc; // Color attibute location point (default-location = 3)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int colDiffuseLoc; // Color uniform location point (fragment shader)
int colAmbientLoc; // Ambient color uniform location point (fragment shader)
int colSpecularLoc; // Specular color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader; } Shader;
// Material type // Material texture map
typedef struct TextureMap {
Texture2D tex;
Color color;
float value;
} TextureMap;
// Material type (generic)
typedef struct Material { typedef struct Material {
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) Shader shader;
TextureMap maps[MAX_TEXTURE_MAPS]; // Initialized on LoadMaterial*(), set to MAX_TEXTURE_MAPS
Texture2D texDiffuse; // Diffuse texture float *params; // Initialized on LoadMaterial*(), set to MAX_MATERIAL_PARAMS
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material; } Material;
// Camera type, defines a camera position/orientation in 3d space // Camera type, defines a camera position/orientation in 3d space
@ -360,6 +394,7 @@ void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth) void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
int rlGetVersion(void); // Returns current OpenGL version int rlGetVersion(void); // Returns current OpenGL version
Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality // Functions Declaration - rlgl functionality
@ -369,24 +404,26 @@ void rlglClose(void); // De-init rlgl
void rlglDraw(void); // Draw VAO/VBO void rlglDraw(void); // Draw VAO/VBO
void rlglLoadExtensions(void *loader); // Load OpenGL extensions void rlglLoadExtensions(void *loader); // Load OpenGL extensions
unsigned int rlglLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU // Textures data management
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void *data); // Update GPU texture with new data void rlUpdateTexture(unsigned int id, int width, int height, int format, const void *data); // Update GPU texture with new data
void rlglGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture void rlUnloadTexture(unsigned int id);
void rlGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture
void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
RenderTexture2D rlLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids // Vertex data management
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer) void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
void rlglDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform void rlUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer)
void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU void rlDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
void rlUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates // Texture maps generation (PBR)
Texture2D rlGenMapCubemap(Texture2D skyHDR, int size); // Generate cubemap texture map from HDR texture
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) Texture2D rlGenMapIrradiance(Texture2D cubemap, int size); // Generate irradiance texture map
void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data Texture2D rlGenMapPrefilter(Texture2D cubemap, int size); // Generate prefilter texture map
Texture2D rlGenMapBRDF(Texture2D cubemap, int size); // Generate BRDF texture map
// VR functions exposed to core module but not to raylib users
void BeginVrDrawing(void); // Begin VR drawing configuration
void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
// NOTE: There is a set of shader related functions that are available to end user, // NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h // to avoid creating function wrappers through core module, they have been directly declared in raylib.h
@ -399,8 +436,8 @@ void EndVrDrawing(void); // End VR drawing process (and deskt
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
void UnloadShader(Shader shader); // Unload a custom shader from memory void UnloadShader(Shader shader); // Unload a custom shader from memory
Shader GetDefaultShader(void); // Get default shader Shader GetShaderDefault(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture Texture2D GetTextureDefault(void); // Get default texture
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
@ -415,15 +452,15 @@ void EndShaderMode(void); // End custo
void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
void EndBlendMode(void); // End blending mode (reset to default: alpha blending) void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
void TraceLog(int msgType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
float *MatrixToFloat(Matrix mat); // Get float array from Matrix data
void InitVrSimulator(int vrDevice); // Init VR simulator for selected device void InitVrSimulator(int vrDevice); // Init VR simulator for selected device
void CloseVrSimulator(void); // Close VR simulator for current device void CloseVrSimulator(void); // Close VR simulator for current device
void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
void BeginVrDrawing(void); // Begin VR stereo rendering void BeginVrDrawing(void); // Begin VR stereo rendering
void EndVrDrawing(void); // End VR stereo rendering void EndVrDrawing(void); // End VR stereo rendering
void TraceLog(int msgType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -119,7 +119,7 @@ void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color)
float d = sqrtf(dx*dx + dy*dy); float d = sqrtf(dx*dx + dy*dy);
float angle = asinf(dy/d); float angle = asinf(dy/d);
rlEnableTexture(GetDefaultTexture().id); rlEnableTexture(GetTextureDefault().id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef((float)startPos.x, (float)startPos.y, 0); rlTranslatef((float)startPos.x, (float)startPos.y, 0);
@ -203,7 +203,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
} }
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
{ {
rlEnableTexture(GetDefaultTexture().id); // Default white texture rlEnableTexture(GetTextureDefault().id); // Default white texture
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
for (int i = 0; i < 360; i += 20) for (int i = 0; i < 360; i += 20)
@ -253,7 +253,7 @@ void DrawRectangleRec(Rectangle rec, Color color)
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color) void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
{ {
rlEnableTexture(GetDefaultTexture().id); rlEnableTexture(GetTextureDefault().id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef((float)rec.x, (float)rec.y, 0); rlTranslatef((float)rec.x, (float)rec.y, 0);
@ -309,7 +309,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
} }
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
{ {
rlEnableTexture(GetDefaultTexture().id); // Default white texture rlEnableTexture(GetTextureDefault().id); // Default white texture
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -376,7 +376,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
} }
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
{ {
rlEnableTexture(GetDefaultTexture().id); // Default white texture rlEnableTexture(GetTextureDefault().id); // Default white texture
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);

View file

@ -63,8 +63,8 @@
#include <string.h> // Required for: strcmp(), strrchr(), strncmp() #include <string.h> // Required for: strcmp(), strrchr(), strncmp()
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
// Required for: rlglLoadTexture() rlDeleteTextures(), // Required for: rlLoadTexture() rlDeleteTextures(),
// rlglGenerateMipmaps(), some funcs for DrawTexturePro() // rlGenerateMipmaps(), some funcs for DrawTexturePro()
#include "utils.h" // Required for: fopen() Android mapping #include "utils.h" // Required for: fopen() Android mapping
@ -384,7 +384,7 @@ Texture2D LoadTextureFromImage(Image image)
{ {
Texture2D texture = { 0 }; Texture2D texture = { 0 };
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps); texture.id = rlLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
texture.width = image.width; texture.width = image.width;
texture.height = image.height; texture.height = image.height;
@ -399,7 +399,7 @@ Texture2D LoadTextureFromImage(Image image)
// Load texture for rendering (framebuffer) // Load texture for rendering (framebuffer)
RenderTexture2D LoadRenderTexture(int width, int height) RenderTexture2D LoadRenderTexture(int width, int height)
{ {
RenderTexture2D target = rlglLoadRenderTexture(width, height); RenderTexture2D target = rlLoadRenderTexture(width, height);
return target; return target;
} }
@ -416,7 +416,7 @@ void UnloadImage(Image image)
// Unload texture from GPU memory (VRAM) // Unload texture from GPU memory (VRAM)
void UnloadTexture(Texture2D texture) void UnloadTexture(Texture2D texture)
{ {
if (texture.id != 0) if (texture.id > 0)
{ {
rlDeleteTextures(texture.id); rlDeleteTextures(texture.id);
@ -427,7 +427,7 @@ void UnloadTexture(Texture2D texture)
// Unload render texture from GPU memory (VRAM) // Unload render texture from GPU memory (VRAM)
void UnloadRenderTexture(RenderTexture2D target) void UnloadRenderTexture(RenderTexture2D target)
{ {
if (target.id != 0) rlDeleteRenderTextures(target); if (target.id > 0) rlDeleteRenderTextures(target);
} }
// Get pixel data from image in the form of Color struct array // Get pixel data from image in the form of Color struct array
@ -525,7 +525,7 @@ Image GetTextureData(Texture2D texture)
if (texture.format < 8) if (texture.format < 8)
{ {
image.data = rlglReadTexturePixels(texture); image.data = rlReadTexturePixels(texture);
if (image.data != NULL) if (image.data != NULL)
{ {
@ -553,7 +553,7 @@ Image GetTextureData(Texture2D texture)
// NOTE: pixels data must match texture.format // NOTE: pixels data must match texture.format
void UpdateTexture(Texture2D texture, const void *pixels) void UpdateTexture(Texture2D texture, const void *pixels)
{ {
rlglUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels); rlUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels);
} }
// Save image to a PNG file // Save image to a PNG file
@ -1660,9 +1660,9 @@ void GenTextureMipmaps(Texture2D *texture)
{ {
TraceLog(LOG_WARNING, "Limited NPOT support, no mipmaps available for NPOT textures"); TraceLog(LOG_WARNING, "Limited NPOT support, no mipmaps available for NPOT textures");
} }
else rlglGenerateMipmaps(texture); else rlGenerateMipmaps(texture);
#else #else
rlglGenerateMipmaps(texture); rlGenerateMipmaps(texture);
#endif #endif
} }
@ -1792,7 +1792,7 @@ void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Co
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint) void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
{ {
// Check if texture is valid // Check if texture is valid
if (texture.id != 0) if (texture.id > 0)
{ {
if (sourceRec.width < 0) sourceRec.x -= sourceRec.width; if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height; if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;