void Object::setTexture(std::string const& filename) { glhckTexture* t = glhckTextureNew(filename.data(), 0, nullptr); glhckObjectTexture(o, t); glhckTextureFree(t); }
/* \brief import MikuMikuDance PMD file */ int _glhckImportPMD(_glhckObject *object, const char *file, const glhckImportModelParameters *params, glhckGeometryIndexType itype, glhckGeometryVertexType vtype) { FILE *f; char *texturePath; mmd_data *mmd = NULL; glhckAtlas *atlas = NULL; glhckMaterial *material = NULL; glhckTexture *texture = NULL, **textureList = NULL; glhckImportVertexData *vertexData = NULL; glhckImportIndexData *indices = NULL, *stripIndices = NULL; unsigned int geometryType = GLHCK_TRIANGLE_STRIP; unsigned int i, i2, ix, start, numFaces, numIndices = 0; CALL(0, "%p, %s, %p", object, file, params); if (!(f = fopen(file, "rb"))) goto read_fail; if (!(mmd = mmd_new(f))) goto mmd_no_memory; if (mmd_read_header(mmd) != 0) goto mmd_import_fail; if (mmd_read_vertex_data(mmd) != 0) goto mmd_import_fail; if (mmd_read_index_data(mmd) != 0) goto mmd_import_fail; if (mmd_read_material_data(mmd) != 0) goto mmd_import_fail; /* close file */ NULLDO(fclose, f); if (mmd->header.name) { DEBUG(GLHCK_DBG_CRAP, "%s\n", mmd->header.name); } if (mmd->header.comment) printf("%s\n\n", mmd->header.comment); if (!(vertexData = _glhckCalloc(mmd->num_vertices, sizeof(glhckImportVertexData)))) goto mmd_no_memory; if (!(indices = _glhckMalloc(mmd->num_indices * sizeof(unsigned int)))) goto mmd_no_memory; if (!(textureList = _glhckCalloc(mmd->num_materials, sizeof(_glhckTexture*)))) goto mmd_no_memory; if (!(atlas = glhckAtlasNew())) goto mmd_no_memory; /* add all textures to atlas packer */ for (i = 0; i < mmd->num_materials; ++i) { if (!mmd->materials[i].texture) continue; if (!(texturePath = _glhckImportTexturePath(mmd->materials[i].texture, file))) continue; if ((texture = glhckTextureNewFromFile(texturePath, NULL, NULL))) { glhckAtlasInsertTexture(atlas, texture); glhckTextureFree(texture); textureList[i] = texture; } _glhckFree(texturePath); } for (i = 0; i < mmd->num_materials && !textureList[i]; ++i); if (i >= mmd->num_materials) { /* no textures found */ NULLDO(glhckAtlasFree, atlas); NULLDO(_glhckFree, textureList); } else { /* pack textures */ if (glhckAtlasPack(atlas, GLHCK_RGBA, 1, 0, glhckTextureDefaultParameters()) != RETURN_OK) goto fail; } /* assign data */ for (i = 0, start = 0; i < mmd->num_materials; ++i, start += numFaces) { numFaces = mmd->materials[i].face; for (i2 = start; i2 < start + numFaces; ++i2) { ix = mmd->indices[i2]; /* vertices */ vertexData[ix].vertex.x = mmd->vertices[ix*3+0]; vertexData[ix].vertex.y = mmd->vertices[ix*3+1]; vertexData[ix].vertex.z = mmd->vertices[ix*3+2]; /* normals */ vertexData[ix].normal.x = mmd->normals[ix*3+0]; vertexData[ix].normal.y = mmd->normals[ix*3+1]; vertexData[ix].normal.z = mmd->normals[ix*3+2]; /* texture coords */ vertexData[ix].coord.x = mmd->coords[ix*2+0]; vertexData[ix].coord.y = mmd->coords[ix*2+1] * -1; /* fix coords */ if (vertexData[ix].coord.x < 0.0f) vertexData[ix].coord.x += 1.0f; if (vertexData[ix].coord.y < 0.0f) vertexData[ix].coord.y += 1.0f; /* if there is packed texture */ if (atlas && textureList[i]) { kmVec2 coord; coord.x = vertexData[ix].coord.x; coord.y = vertexData[ix].coord.y; glhckAtlasTransformCoordinates(atlas, textureList[i], &coord, &coord); vertexData[ix].coord.x = coord.x; vertexData[ix].coord.y = coord.y; } indices[i2] = ix; } } if (atlas) { if (!(material = glhckMaterialNew(glhckAtlasGetTexture(atlas)))) goto mmd_no_memory; glhckObjectMaterial(object, material); NULLDO(glhckMaterialFree, material); NULLDO(glhckAtlasFree, atlas); NULLDO(_glhckFree, textureList); } /* triangle strip geometry */ if (!(stripIndices = _glhckTriStrip(indices, mmd->num_indices, &numIndices))) { /* failed, use non stripped geometry */ geometryType = GLHCK_TRIANGLES; numIndices = mmd->num_indices; stripIndices = indices; } else NULLDO(_glhckFree, indices); /* set geometry */ glhckObjectInsertIndices(object, itype, stripIndices, numIndices); glhckObjectInsertVertices(object, vtype, vertexData, mmd->num_vertices); object->geometry->type = geometryType; /* finish */ NULLDO(_glhckFree, vertexData); NULLDO(_glhckFree, stripIndices); NULLDO(mmd_free, mmd); RET(0, "%d", RETURN_OK); return RETURN_OK; read_fail: DEBUG(GLHCK_DBG_ERROR, "Failed to open: %s", file); goto fail; mmd_import_fail: DEBUG(GLHCK_DBG_ERROR, "MMD importing failed."); goto fail; mmd_no_memory: DEBUG(GLHCK_DBG_ERROR, "MMD not enough memory."); fail: IFDO(fclose, f); IFDO(glhckAtlasFree, atlas); IFDO(mmd_free, mmd); IFDO(_glhckFree, textureList); IFDO(_glhckFree, vertexData); IFDO(_glhckFree, indices); IFDO(_glhckFree, stripIndices); RET(0, "%d", RETURN_FAIL); return RETURN_FAIL; }
int main(int argc, char **argv) { GLFWwindow* window; glhckTexture *texture; glhckMaterial *material; glhckObject *cube, *sprite, *cube2, *sprite3, *camObj; glhckCamera *camera; const kmAABB *aabb; kmVec3 cameraPos = { 0, 0, 0 }; kmVec3 cameraRot = { 0, 0, 0 }; float spinRadius; int queuePrinted = 0; float now = 0; float last = 0; unsigned int frameCounter = 0; unsigned int FPS = 0; unsigned int fpsDelay = 0; float duration = 0; float delta = 0; char WIN_TITLE[256]; memset(WIN_TITLE, 0, sizeof(WIN_TITLE)); glfwSetErrorCallback(error_callback); if (!glfwInit()) return EXIT_FAILURE; puts("-!- glfwinit"); glhckCompileFeatures features; glhckGetCompileFeatures(&features); if (features.render.glesv1 || features.render.glesv2) { glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_DEPTH_BITS, 16); } if (features.render.glesv2) { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); } if (features.render.opengl) { glfwWindowHint(GLFW_DEPTH_BITS, 24); } if (!(window = glfwCreateWindow(WIDTH, HEIGHT, "display test", NULL, NULL))) return EXIT_FAILURE; glfwMakeContextCurrent(window); puts("-!- window create"); /* Turn on VSYNC if driver allows */ glfwSwapInterval(0); if (!glhckContextCreate(argc, argv)) return EXIT_FAILURE; puts("-!- glhck init"); if (!glhckDisplayCreate(WIDTH, HEIGHT, GLHCK_RENDER_AUTO)) return EXIT_FAILURE; puts("-!- glhck display create"); RUNNING = 1; /* test camera */ if (!(camera = glhckCameraNew())) return EXIT_FAILURE; glhckCameraRange(camera, 1.0f, 1000.0f); camObj = glhckCameraGetObject(camera); if (!(texture = glhckTextureNewFromFile("example/media/glhck.png", NULL, NULL))) return EXIT_FAILURE; if (!(material = glhckMaterialNew(texture))) return EXIT_FAILURE; glhckTextureFree(texture); sprite = glhckSpriteNew(texture, 0, 0); cube2 = glhckCubeNew(1.0f); glhckObjectDrawAABB(cube2, 1); glhckObjectDrawOBB(cube2, 1); glhckObjectScalef(cube2, 1.0f, 1.0f, 2.0f); glhckObjectMaterial(cube2, material); sprite3 = glhckObjectCopy(sprite); glhckObjectScalef(sprite, 0.05f, 0.05f, 0.05f); glhckObjectPositionf(sprite3, 64*2, 48*2, 0); #define SKIP_MMD 0 #define SKIP_OCTM 0 #define SKIP_ASSIMP 0 #if SKIP_MMD # define MMD_PATH "" #else # define MMD_PATH "example/media/madoka/md_m.pmd" #endif #if SKIP_OCTM # define OCTM_PATH "" #else # define OCTM_PATH "example/media/ambulance/ambulance.ctm" #endif /* cmake -DGLHCK_IMPORT_ASSIMP=YES */ #if SKIP_ASSIMP # define ASSIMP_PATH "" #else //# define ASSIMP_PATH "example/media/chaosgate/chaosgate.obj" //# define ASSIMP_PATH "example/media/room/room.obj" //# define ASSIMP_PATH "example/media/alletine.x" # define ASSIMP_PATH "example/media/player.x" #endif glhckImportModelParameters animatedParams; memcpy(&animatedParams, glhckImportDefaultModelParameters(), sizeof(glhckImportModelParameters)); animatedParams.animated = 1; if ((cube = glhckModelNewEx(MMD_PATH, 1.0f, NULL, GLHCK_INDEX_SHORT, GLHCK_VERTEX_V3S))) { cameraPos.y = 10.0f; cameraPos.z = -40.0f; } else if ((cube = glhckModelNewEx(OCTM_PATH, 5.0f, NULL, GLHCK_INDEX_SHORT, GLHCK_VERTEX_V3S))) { cameraPos.y = 10.0f; cameraPos.z = -40.0f; glhckObjectPositionf(cube, 0.0f, 5.0f, 0.0f); } else if ((cube = glhckModelNewEx(ASSIMP_PATH, 0.1f, &animatedParams, GLHCK_INDEX_SHORT, GLHCK_VERTEX_V3S))) { glhckMaterial *mat; glhckTexture *tex; if ((tex = glhckTextureNewFromFile("example/media/texture-b.png", NULL, NULL))) { if ((mat = glhckMaterialNew(tex))) glhckObjectMaterial(cube, mat); glhckTextureFree(tex); } glhckObjectMovef(cube, 0, 15, 0); cameraPos.y = 10.0f; cameraPos.z = -40.0f; } else if ((cube = glhckCubeNew(1.0f))) { glhckObjectMaterial(cube, material); cameraPos.z = -20.0f; } else return EXIT_FAILURE; #define SHADOW 0 #if SHADOW glhckShader *shader = glhckShaderNew(NULL, "VSM.GLhck.Lighting.ShadowMapping.Unpacking.Fragment", NULL); glhckShader *depthShader = glhckShaderNew(NULL, "VSM.GLhck.Depth.Packing.Fragment", NULL); glhckShader *depthRenderShader = glhckShaderNew(NULL, "VSM.GLhck.DepthRender.Unpacking.Fragment", NULL); glhckShaderSetUniform(shader, "ShadowMap", 1, &((int[]){1}));
void UfoLaser::term() { glhckTextureFree(TEXTURE); }
static int processModel(const char *file, glhckObject *object, glhckObject *current, const struct aiScene *sc, const struct aiNode *nd, glhckGeometryIndexType itype, glhckGeometryVertexType vtype, const glhckImportModelParameters *params) { unsigned int m, f; unsigned int numVertices = 0, numIndices = 0; unsigned int ioffset, voffset; glhckImportIndexData *indices = NULL; glhckImportVertexData *vertexData = NULL; glhckMaterial *material = NULL; glhckTexture **textureList = NULL, *texture = NULL; glhckAtlas *atlas = NULL; const struct aiMesh *mesh; const struct aiFace *face; int canFreeCurrent = 0; int hasTexture = 0; assert(file); assert(object && current); assert(sc && nd); /* combine && atlas loading path */ if (params->flatten) { /* prepare atlas for texture combining */ if (!(atlas = glhckAtlasNew())) goto assimp_no_memory; /* texturelist for offseting coordinates */ if (!(textureList = _glhckCalloc(nd->mNumMeshes, sizeof(_glhckTexture*)))) goto assimp_no_memory; /* gather statistics */ for (m = 0; m != nd->mNumMeshes; ++m) { mesh = sc->mMeshes[nd->mMeshes[m]]; if (!mesh->mVertices) continue; for (f = 0; f != mesh->mNumFaces; ++f) { face = &mesh->mFaces[f]; if (!face) goto fail; numIndices += face->mNumIndices; } numVertices += mesh->mNumVertices; if ((texture = textureFromMaterial(file, sc->mMaterials[mesh->mMaterialIndex]))) { glhckAtlasInsertTexture(atlas, texture); glhckTextureFree(texture); textureList[m] = texture; hasTexture = 1; } } /* allocate vertices */ if (!(vertexData = _glhckCalloc(numVertices, sizeof(glhckImportVertexData)))) goto assimp_no_memory; /* allocate indices */ if (!(indices = _glhckMalloc(numIndices * sizeof(glhckImportIndexData)))) goto assimp_no_memory; /* pack combined textures */ if (hasTexture) { if (glhckAtlasPack(atlas, GLHCK_RGBA, 1, 0, glhckTextureDefaultParameters()) != RETURN_OK) goto fail; } else { NULLDO(glhckAtlasFree, atlas); NULLDO(_glhckFree, textureList); } /* join vertex data */ for (m = 0, ioffset = 0, voffset = 0; m != nd->mNumMeshes; ++m) { mesh = sc->mMeshes[nd->mMeshes[m]]; if (!mesh->mVertices) continue; if (textureList) texture = textureList[m]; else texture = NULL; joinMesh(mesh, voffset, indices+ioffset, vertexData+voffset, atlas, texture); for (f = 0; f != mesh->mNumFaces; ++f) { face = &mesh->mFaces[f]; if (!face) goto fail; ioffset += face->mNumIndices; } voffset += mesh->mNumVertices; } /* create material */ if (hasTexture && !(material = glhckMaterialNew(texture))) goto assimp_no_memory; /* finally build the model */ if (buildModel(current, numIndices, numVertices, indices, vertexData, itype, vtype) == RETURN_OK) { _glhckObjectFile(current, nd->mName.data); if (material) glhckObjectMaterial(current, material); if (!(current = glhckObjectNew())) goto fail; glhckObjectAddChild(object, current); glhckObjectFree(current); canFreeCurrent = 1; } /* free stuff */ IFDO(glhckAtlasFree, atlas); IFDO(glhckMaterialFree, material); IFDO(_glhckFree, textureList); NULLDO(_glhckFree, vertexData); NULLDO(_glhckFree, indices); } else { /* default loading path */ for (m = 0, ioffset = 0, voffset = 0; m != nd->mNumMeshes; ++m) { mesh = sc->mMeshes[nd->mMeshes[m]]; if (!mesh->mVertices) continue; /* gather statistics */ numIndices = 0; for (f = 0; f != mesh->mNumFaces; ++f) { face = &mesh->mFaces[f]; if (!face) goto fail; numIndices += face->mNumIndices; } numVertices = mesh->mNumVertices; // FIXME: create materialFromAssimpMaterial // that returns glhckMaterial with correct stuff /* get texture */ hasTexture = 0; if ((texture = textureFromMaterial(file, sc->mMaterials[mesh->mMaterialIndex]))) hasTexture = 1; /* create material */ if (hasTexture && !(material = glhckMaterialNew(texture))) goto assimp_no_memory; /* allocate vertices */ if (!(vertexData = _glhckCalloc(numVertices, sizeof(glhckImportVertexData)))) goto assimp_no_memory; /* allocate indices */ if (!(indices = _glhckMalloc(numIndices * sizeof(glhckImportIndexData)))) goto assimp_no_memory; /* fill arrays */ joinMesh(mesh, 0, indices, vertexData, NULL, NULL); /* build model */ if (buildModel(current, numIndices, numVertices, indices, vertexData, itype, vtype) == RETURN_OK) { /* FIXME: UGLY */ char pointer[16]; snprintf(pointer, sizeof(pointer), "%p", mesh); _glhckObjectFile(current, pointer); if (material) glhckObjectMaterial(current, material); if (!(current = glhckObjectNew())) goto fail; glhckObjectAddChild(object, current); glhckObjectFree(current); canFreeCurrent = 1; } /* free stuff */ NULLDO(_glhckFree, vertexData); NULLDO(_glhckFree, indices); IFDO(glhckTextureFree, texture); IFDO(glhckMaterialFree, material); } } /* process childrens */ for (m = 0; m != nd->mNumChildren; ++m) { if (processModel(file, object, current, sc, nd->mChildren[m], itype, vtype, params) == RETURN_OK) { if (!(current = glhckObjectNew())) goto fail; glhckObjectAddChild(object, current); glhckObjectFree(current); canFreeCurrent = 1; } } /* we din't do anything to the next * allocated object, so free it */ if (canFreeCurrent) glhckObjectRemoveFromParent(current); return RETURN_OK; assimp_no_memory: DEBUG(GLHCK_DBG_ERROR, "Assimp not enough memory."); fail: IFDO(_glhckFree, vertexData); IFDO(_glhckFree, indices); IFDO(_glhckFree, textureList); IFDO(glhckTextureFree, texture); IFDO(glhckMaterialFree, material); IFDO(glhckAtlasFree, atlas); if (canFreeCurrent) glhckObjectRemoveFromParent(current); return RETURN_FAIL; }
/* \brief render scene */ GLHCKAPI void glhckRender(void) { unsigned int ti, oi, ts, os, tc, oc; char kt; glhckTexture *t; glhckObject *o; __GLHCKobjectQueue *objects; __GLHCKtextureQueue *textures; GLHCK_INITIALIZED(); TRACE(2); /* can't render */ if (!glhckInitialized() || !_glhckRenderInitialized()) return; objects = &GLHCKRD()->objects; textures = &GLHCKRD()->textures; /* store counts for enumeration, +1 for untexture objects */ tc = textures->count+1; oc = objects->count; /* nothing to draw */ if (!oc) return; /* draw in sorted texture order */ for (ti = 0, ts = 0; ti != tc; ++ti) { if (ti < tc-1) { if (!(t = textures->queue[ti])) continue; } else t = NULL; /* untextured object */ for (oi = 0, os = 0, kt = 0; oi != oc; ++oi) { if (!(o = objects->queue[oi])) continue; if (o->material) { /* don't draw if not same texture or opaque, * opaque objects are drawn last */ if (o->material->texture != t || (o->material->blenda != GLHCK_ZERO || o->material->blendb != GLHCK_ZERO)) { if (o->material->texture == t) kt = 1; /* don't remove texture from queue */ if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } } else if (t) { /* no material, but texture requested */ if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } /* render object */ glhckObjectRender(o); glhckObjectFree(o); /* referenced on draw call */ objects->queue[oi] = NULL; --objects->count; } /* check if we need texture again or not */ if (kt) { if (ts != ti) textures->queue[ti] = NULL; textures->queue[ts++] = t; } else { if (t) { glhckTextureFree(t); /* ref is increased on draw call! */ textures->queue[ti] = NULL; --textures->count; } } } /* store counts for enumeration, +1 for untextured objects */ tc = textures->count+1; oc = objects->count; /* FIXME: shift queue here */ if (oc) { } /* draw opaque objects next, * FIXME: this should not be done in texture order, * instead draw from farthest to nearest. (I hate opaque objects) */ for (ti = 0; ti != tc && oc; ++ti) { if (ti < tc-1) { if (!(t = textures->queue[ti])) continue; } else t = NULL; /* untextured object */ for (oi = 0, os = 0; oi != oc; ++oi) { if (!(o = objects->queue[oi])) continue; if (o->material) { /* don't draw if not same texture */ if (o->material->texture != t) { if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } } else if (t) { if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } /* render object */ glhckObjectRender(o); glhckObjectFree(o); /* referenced on draw call */ objects->queue[oi] = NULL; --objects->count; } /* this texture is done for */ if (t) { glhckTextureFree(t); /* ref is increased on draw call! */ textures->queue[ti] = NULL; --textures->count; } /* no texture, time to break */ if (!t) break; } /* FIXME: shift queue here if leftovers */ /* good we got no leftovers \o/ */ if (objects->count) { /* something was left un-drawn :o? */ for (oi = 0; oi != objects->count; ++oi) glhckObjectFree(objects->queue[oi]); memset(objects->queue, 0, objects->count * sizeof(glhckObject*)); objects->count = 0; } if (textures->count) { /* something was left un-drawn :o? */ DEBUG(GLHCK_DBG_CRAP, "COUNT UNLEFT %u", textures->count); for (ti = 0; ti != textures->count; ++ti) glhckTextureFree(textures->queue[ti]); memset(textures->queue, 0, textures->count * sizeof(glhckTexture*)); textures->count = 0; } }
void Shot::term() { glhckTextureFree(TEXTURE); }
void Plasma::term() { glhckTextureFree(TEXTURE); }