From 2679c4ae9b2fefdb0c150a7cd576d5d3297b027b Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 21 Jul 2017 09:34:09 +0200 Subject: [PATCH] Review mesh loading and textures generation --- examples/models/models_cubicmap.c | 2 +- examples/models/models_material_pbr.c | 5 +++++ examples/models/models_skybox.c | 31 ++++++++++++--------------- src/models.c | 20 ++++++++++++++--- src/raylib.h | 13 ++++++----- src/rlgl.c | 12 ++++------- 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/examples/models/models_cubicmap.c b/examples/models/models_cubicmap.c index 177cf890..268d480a 100644 --- a/examples/models/models_cubicmap.c +++ b/examples/models/models_cubicmap.c @@ -27,7 +27,7 @@ int main() Texture2D cubicmap = LoadTextureFromImage(image); // Convert image to texture to display (VRAM) Mesh mesh = GenMeshCubicmap(image, (Vector3){ 1.0f, 1.0f, 1.0f }); - Model model = LoadModelFromMesh(mesh, false); + Model model = LoadModelFromMesh(mesh); // NOTE: By default each cube is mapped to one part of texture atlas Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c index f443e245..d55aa773 100644 --- a/examples/models/models_material_pbr.c +++ b/examples/models/models_material_pbr.c @@ -142,6 +142,11 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); + + // Setup required shader locations + SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, 1); + SetShaderValuei(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, 1); + SetShaderValuei(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, 1); Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE); diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c index d347854f..500cb19b 100644 --- a/examples/models/models_skybox.c +++ b/examples/models/models_skybox.c @@ -24,24 +24,24 @@ int main() // 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 + // Load skybox model Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); - Model skybox = LoadModelFromMesh(cube, false); + Model skybox = LoadModelFromMesh(cube); + + // Load skybox shader and set required locations + // NOTE: Some locations are automatically set at shader loading skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs"); - - Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); - skybox.material.maps[MAP_CUBEMAP].texture = GenTextureCubemap(texHDR, 512); SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ MAP_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); - + // Load cubemap shader and setup required shader locations + Shader shdrCubemap = LoadShader("resources/shaders/cubemap.vs", "resources/shaders/cubemap.fs"); + SetShaderValuei(shdrCubemap, GetShaderLocation(shdrCubemap, "environmentMap"), (int[1]){ 0 }, 1); + + Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); + skybox.material.maps[MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, texHDR, 512); + + UnloadShader(shdrCubemap); // Cubemap generation shader not required any more + SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -53,9 +53,6 @@ int main() // 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 diff --git a/src/models.c b/src/models.c index 03e0cb45..7dce9fa6 100644 --- a/src/models.c +++ b/src/models.c @@ -597,12 +597,13 @@ Model LoadModel(const char *fileName) } // Load model from generated mesh -Model LoadModelFromMesh(Mesh mesh, bool dynamic) +// WARNING: A shallow copy of mesh is generated, passed by value, +// as long as struct contains pointers to data and some values, we get a copy +// of mesh pointing to same data as original version... be careful! +Model LoadModelFromMesh(Mesh mesh) { Model model = { 0 }; - rlLoadMesh(&mesh, dynamic); - model.mesh = mesh; model.transform = MatrixIdentity(); model.material = LoadMaterialDefault(); @@ -646,6 +647,7 @@ void UnloadMesh(Mesh *mesh) } // Generated cuboid mesh +// NOTE: Vertex data is uploaded to GPU Mesh GenMeshCube(float width, float height, float length) { Mesh mesh = { 0 }; @@ -759,11 +761,15 @@ Mesh GenMeshCube(float width, float height, float length) mesh.vertexCount = 24; mesh.triangleCount = 12; + + // Upload vertex data to GPU (static mesh) + rlLoadMesh(&mesh, false); return mesh; } // Generate a mesh from heightmap +// NOTE: Vertex data is uploaded to GPU Mesh GenMeshHeightmap(Image heightmap, Vector3 size) { #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3) @@ -865,10 +871,15 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size) } free(pixels); + + // Upload vertex data to GPU (static mesh) + rlLoadMesh(&mesh, false); return mesh; } +// Generate a cubes mesh from pixel data +// NOTE: Vertex data is uploaded to GPU Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) { Mesh mesh = { 0 }; @@ -1219,6 +1230,9 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) free(mapTexcoords); free(cubicmapPixels); // Free image pixel data + + // Upload vertex data to GPU (static mesh) + rlLoadMesh(&mesh, false); return mesh; } diff --git a/src/raylib.h b/src/raylib.h index 22ef06cb..cc5b0bb6 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -409,10 +409,11 @@ typedef struct BoundingBox { } BoundingBox; // Vertex data definning a mesh +// NOTE: Data stored in CPU memory (and GPU) typedef struct Mesh { int vertexCount; // Number of vertices stored in arrays int triangleCount; // Number of triangles stored (indexed or not) - + float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5) @@ -981,15 +982,19 @@ RLAPI void DrawGizmo(Vector3 position); // Model loading/unloading functions RLAPI Model LoadModel(const char *fileName); // Load model from files (mesh and material) -RLAPI Model LoadModelFromMesh(Mesh mesh, bool dynamic); // Load model from generated mesh +RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh 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 GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with desired subdivisions) RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh +//RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere) +//RLAPI Mesh GenMeshCylinder(float radiusTop, float radiusBottom, float height, int slices); // Generate cylinder mesh +//RLAPI Mesh GenMeshTorus(float radius1, float radius2, int radSeg, int sides); // Generate torus mesh +//RLAPI Mesh GenMeshTube(float radius1, float radius2, float height, int sides); // Generate tube 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 @@ -997,8 +1002,6 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); RLAPI Material LoadMaterial(const char *fileName); // Load material from file RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) -RLAPI void SetMaterialTexture(Material *mat, int mapType, Texture2D texture); // Set material texture -RLAPI void UnsetMaterialTexture(Material *mat, int mapType); // Unset texture from material and unload it from GPU // Model drawing functions RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) diff --git a/src/rlgl.c b/src/rlgl.c index 44b20b61..3160c744 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2520,10 +2520,7 @@ Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size) Texture2D cubemap = { 0 }; #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // NOTE: SetShaderDefaultLocations() already setups locations for projection and view Matrix in shader - // TODO: Locations should be taken out of this function... too shader dependant... - SetShaderValuei(shader, GetShaderLocation(shader, "environmentMap"), (int[1]){ 0 }, 1); - - SetShaderValuei(shader, texmapLoc, (int[1]){ 0 }, 1); // Set default active texture to 0 + // Other locations should be setup externally in shader before calling the function // Set up depth face culling and cubemap seamless glDisable(GL_CULL_FACE); @@ -2600,8 +2597,7 @@ Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // NOTE: SetShaderDefaultLocations() already setups locations for projection and view Matrix in shader - // TODO: Locations should be taken out of this function... too shader dependant... - SetShaderValuei(shader, GetShaderLocation(shader, "environmentMap"), (int[1]){ 0 }, 1); + // Other locations should be setup externally in shader before calling the function // Setup framebuffer unsigned int fbo, rbo; @@ -2672,9 +2668,9 @@ Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // NOTE: SetShaderDefaultLocations() already setups locations for projection and view Matrix in shader + // Other locations should be setup externally in shader before calling the function // TODO: Locations should be taken out of this function... too shader dependant... - int roughnessLoc = GetShaderLocation(shader, "roughness"); - SetShaderValuei(shader, GetShaderLocation(shader, "environmentMap"), (int[1]){ 0 }, 1); + int roughnessLoc = GetShaderLocation(shader, "roughness"); // Setup framebuffer unsigned int fbo, rbo;