logError("Failed to import solid from %s", path);
return NULL;
}
-
+
#if IMPORT_DEBUG_
const struct aiMetadata* meta = scene->mMetaData;
logDebug("Metadata from %s: %p", path, meta);
printMetadata(meta);
printAiNodeMetadata(scene->mRootNode);
#endif // IMPORT_DEBUG_
-
+
const unsigned int numMeshes = scene->mNumMeshes;
const unsigned int numMaterials = scene->mNumMaterials;
// TODO Consider assets with some arrays empty, and prevent zero mallocs
-
+
Solid* solid = malloc(sizeof(Solid));
solid->numMeshes = numMeshes;
solid->meshes = malloc(numMeshes * sizeof(Mesh));
solid->numMaterials = numMaterials;
solid->materials = malloc(numMaterials * sizeof(Material));
-
+
for (unsigned int meshIndex = 0; meshIndex < numMeshes; ++meshIndex) {
const struct aiMesh* aiMesh = scene->mMeshes[meshIndex];
const unsigned int numVertices = aiMesh->mNumVertices;
const unsigned int numFaces = aiMesh->mNumFaces;
-
+
Mesh mesh = { .numVertices = numVertices,
.vertices = malloc(numVertices * sizeof(Vector)),
.normals = NULL,
.numFaces = numFaces,
.faces = malloc(numFaces * sizeof(Face)),
.materialIndex = aiMesh->mMaterialIndex };
-
+
for (unsigned int vertIndex = 0; vertIndex < numVertices; ++vertIndex) {
mesh.vertices[vertIndex] = convertAiVector3D(
aiMesh->mVertices[vertIndex]);
}
-
+
if (aiMesh->mNormals != NULL) {
mesh.normals = malloc(numVertices * sizeof(Vector));
for (unsigned int normIndex = 0; normIndex < numVertices; ++normIndex) {
aiMesh->mNormals[normIndex]);
}
}
-
+
mesh.textureCoords = malloc(numVertices * sizeof(Vector));
for (unsigned int texcIndex = 0; texcIndex < numVertices; ++texcIndex) {
mesh.textureCoords[texcIndex] = convertAiVector3D(
aiMesh->mTextureCoords[0][texcIndex]);
}
-
+
for (unsigned int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
const struct aiFace aiFace = aiMesh->mFaces[faceIndex];
const unsigned int numIndices = aiFace.mNumIndices;
-
+
Face face = { .numIndices = numIndices,
.indices = malloc(numIndices * sizeof(size_t)),
.normals = malloc(numIndices * sizeof(Vector)) };
-
+
for (unsigned int i = 0; i < numIndices; ++i) {
face.indices[i] = aiFace.mIndices[i];
}
-
+
if (numIndices == 3) {
Vector normal = triangleNormal(mesh.vertices[face.indices[0]],
mesh.vertices[face.indices[1]],
face.normals = NULL;
}
}
-
+
mesh.faces[faceIndex] = face;
}
// TODO Actually clean up the stuff inside
free(mesh.faces);
mesh.faces = smoothedFaces;
-
+
solid->meshes[meshIndex] = mesh;
}
-
+
GLuint* textureIds = malloc(numMaterials * sizeof(GLuint));
glGenTextures(numMaterials, textureIds);
-
+
for (unsigned int matIndex = 0; matIndex < numMaterials; ++matIndex) {
Material material = { .textureId = textureIds[matIndex] };
dropString(key);
#endif // IMPORT_DEBUG_
-
+
glBindTexture(GL_TEXTURE_2D, material.textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
+
struct aiString originalTexturePath;
if (aiGetMaterialTexture(scene->mMaterials[matIndex],
aiTextureType_DIFFUSE,
char* texturePath = malloc(strlen("assets/") + textureFilenameLength + 1);
strcpy(texturePath, "assets/");
strncat(texturePath, textureFilename, textureFilenameLength);
-
+
TgaImage* textureImage = readTga(texturePath);
if (textureImage == NULL) {
logError("Importing solid from %s: Cannot read texture file %s", path, texturePath);
free(textureImage);
}
}
-
+
solid->materials[matIndex] = material;
}
glBindTexture(GL_TEXTURE_2D, 0);
-
+
aiReleaseImport(scene);
return solid;
}
*/
static const char* replaceFileExtension(const struct aiString path, const char* ext) {
size_t lengthToCopy = path.length;
-
+
char* lastDotSubstr = strrchr(path.data, '.');
if (lastDotSubstr != NULL) {
if (strpbrk(lastDotSubstr, "\\/") == NULL) {
lengthToCopy = lastDotSubstr - path.data;
}
}
-
+
size_t extLength = strlen(ext) + 1;
char* newPath = malloc(lengthToCopy + extLength);
strncpy(newPath, path.data, lengthToCopy);
strncpy(newPath + lengthToCopy, ext, extLength);
-
+
return newPath;
}
void initRender() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-
+
GLfloat light0_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f};
GLfloat light0_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat light0_specular[] = {0.96f, 0.98f, 1.0f, 1.0f};
GLfloat light0_position[] = {5.0f, 10.0f, 5.0f, 0.0f}; // (w == 0.0f) == directional
-
+
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
-
+
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05f);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005f);
-
+
//glShadeModel(GL_FLAT);
}
if (solid == NULL) {
return;
}
-
+
glMatrixMode(GL_MODELVIEW);
glColor3f(0.5f, 1.0f, 0.0f);
-
+
for (size_t meshIndex = 0; meshIndex < solid->numMeshes; ++meshIndex) {
const Mesh mesh = solid->meshes[meshIndex];
glBindTexture(GL_TEXTURE_2D,
solid->materials[mesh.materialIndex].textureId);
-
+
for (size_t faceIndex = 0; faceIndex < mesh.numFaces; ++faceIndex) {
const Face face = mesh.faces[faceIndex];
-
+
if (debugRender && face.normals) {
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
}
-
+
GLenum faceMode;
switch (face.numIndices) {
case 1: faceMode = GL_POINTS; break;
case 3: faceMode = GL_TRIANGLES; break;
default: faceMode = GL_POLYGON; break;
}
-
+
glBegin(faceMode);
-
+
for (size_t i = 0; i < face.numIndices; ++i) {
size_t vertIndex = face.indices[i];
if (face.normals) {
Vector vertex = mesh.vertices[vertIndex];
glVertex3f(vertex.x, vertex.y, vertex.z);
}
-
+
glEnd();
}
}
logError("Null image received, cannot build level");
return;
}
-
+
if (image->header.imageBpp != 32) {
logError("Invalid level image format (%d bpp)", image->header.imageBpp);
return;
}
-
+
BlockGrid newGrid = { .width = image->header.imageWidth,
.depth = image->header.imageHeight,
.blocks = malloc(image->header.imageWidth
* image->header.imageHeight
* sizeof(Block*)) };
-
+
for (size_t row = 0; row < newGrid.depth; ++row) {
for (size_t x = 0; x < newGrid.width; ++x) {
// Flip the image vertically due to (0, 0) being bottom left
size_t z = newGrid.depth - row - 1;
-
+
uint32_t pixelColorARGB = ((uint32_t*) image->bytes)[(row * newGrid.width) + x];
Block* block;
switch (pixelColorARGB) {
setBlockInGrid(newGrid, x, z, block);
}
}
-
+
levelGrid = newGrid;
}