diff --git a/src/rlgl.h b/src/rlgl.h index c5c51319a..a645aa038 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -696,7 +696,7 @@ RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dat RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements data on GPU buffer RLAPI void rlUnloadVertexArray(unsigned int vaoId); // Unload vertex array (vao) RLAPI void rlUnloadVertexBuffer(unsigned int vboId); // Unload vertex buffer object -RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer); // Set vertex attribute data configuration +RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset); // Set vertex attribute data configuration RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); // Set vertex attribute data divisor RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value, when attribute to provided RLAPI void rlDrawVertexArray(int offset, int count); // Draw vertex array (currently active vao) @@ -3824,14 +3824,14 @@ unsigned int rlLoadVertexArray(void) } // Set vertex attribute -void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer) +void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // NOTE: Data type could be: GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT // Additional types (depends on OpenGL version or extensions): // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, // - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV - glVertexAttribPointer(index, compSize, type, normalized, stride, pointer); + glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offset); #endif } diff --git a/src/rmodels.c b/src/rmodels.c index 207fb1afe..e669a2f0c 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1603,7 +1603,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i for (unsigned int i = 0; i < 4; i++) { rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i); - rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4))); + rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4)); rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1); } @@ -5109,9 +5109,18 @@ static Model LoadGLTF(const char *fileName) } else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_0, vec2, float/u8n/u16n + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n { - // TODO: Support additional texture coordinates: TEXCOORD_1 -> mesh.texcoords2 + // Support up to 2 texture coordinates attributes + float *texcoordPtr = NULL; + int index = data->meshes[i].primitives[p].attributes[j].index; + if (index == 0) texcoordPtr = model.meshes[meshIndex].texcoords; + else if (index == 1) texcoordPtr = model.meshes[meshIndex].texcoords2; + else + { + TRACELOG(LOG_WARNING, "MODEL: [%s] No more than 2 texture coordinates attributes supported", fileName); + continue; + } cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; @@ -5120,44 +5129,44 @@ static Model LoadGLTF(const char *fileName) if (attribute->component_type == cgltf_component_type_r_32f) // vec2, float { // Init raylib mesh texcoords to copy glTF attribute data - model.meshes[meshIndex].texcoords = RL_MALLOC(attribute->count*2*sizeof(float)); + texcoordPtr = RL_MALLOC(attribute->count*2*sizeof(float)); // Load 3 components of float data type into mesh.texcoords - LOAD_ATTRIBUTE(attribute, 2, float, model.meshes[meshIndex].texcoords) + LOAD_ATTRIBUTE(attribute, 2, float, texcoordPtr) } else if (attribute->component_type == cgltf_component_type_r_8u) // vec2, u8n { // Init raylib mesh texcoords to copy glTF attribute data - model.meshes[meshIndex].texcoords = RL_MALLOC(attribute->count*2*sizeof(float)); + texcoordPtr = RL_MALLOC(attribute->count*2*sizeof(float)); // Load data into a temp buffer to be converted to raylib data type unsigned short *temp = RL_MALLOC(attribute->count*2*sizeof(unsigned char)); LOAD_ATTRIBUTE(attribute, 2, unsigned char, temp); // Convert data to raylib texcoord data type (float) - for (unsigned int t = 0; t < attribute->count*2; t++) model.meshes[meshIndex].texcoords[t] = (float)temp[t]/255.0f; + for (unsigned int t = 0; t < attribute->count*2; t++) texcoordPtr[t] = (float)temp[t]/255.0f; RL_FREE(temp); } else if (attribute->component_type == cgltf_component_type_r_16u) // vec2, u16n { // Init raylib mesh texcoords to copy glTF attribute data - model.meshes[meshIndex].texcoords = RL_MALLOC(attribute->count*2*sizeof(float)); + texcoordPtr = RL_MALLOC(attribute->count*2*sizeof(float)); // Load data into a temp buffer to be converted to raylib data type unsigned short *temp = RL_MALLOC(attribute->count*2*sizeof(unsigned short)); LOAD_ATTRIBUTE(attribute, 2, unsigned short, temp); // Convert data to raylib texcoord data type (float) - for (unsigned int t = 0; t < attribute->count*2; t++) model.meshes[meshIndex].texcoords[t] = (float)temp[t]/65535.0f; + for (unsigned int t = 0; t < attribute->count*2; t++) texcoordPtr[t] = (float)temp[t]/65535.0f; RL_FREE(temp); } - else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); + else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported", fileName); } else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); } - else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_0, vec3/vec4, float/u8n/u16n + else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n { cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; diff --git a/src/rtextures.c b/src/rtextures.c index 35757ba18..90c0de21c 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -316,14 +316,18 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int unsigned char *dataPtr = fileData; unsigned int size = GetPixelDataSize(width, height, format); - if (headerSize > 0) dataPtr += headerSize; + if (size <= dataSize) // Security check + { + // Offset file data to expected raw image by header size + if ((headerSize > 0) && ((headerSize + size) <= dataSize)) dataPtr += headerSize; - image.data = RL_MALLOC(size); // Allocate required memory in bytes - memcpy(image.data, dataPtr, size); // Copy required data to image - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = format; + image.data = RL_MALLOC(size); // Allocate required memory in bytes + memcpy(image.data, dataPtr, size); // Copy required data to image + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = format; + } UnloadFileData(fileData); }