forked from repalash/xatlas.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
C99 shared library build and API example. jpcy#80
- Loading branch information
Showing
4 changed files
with
218 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/* | ||
MIT License | ||
Copyright (c) 2018-2020 Jonathan Young | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
/* | ||
example | ||
This example shows how to use the xatlas API to generate a unique set of texture coordinates. | ||
Input: an .obj model file. | ||
Output: | ||
* an .obj model file (example_output.obj). This is simplistic for example purposes, it doesn't copy materials from the input .obj file. | ||
* texture coordinates rasterized to images, colored by chart (example_charts*.tga) and by triangle (example_tris*.tga). | ||
*/ | ||
#include <assert.h> | ||
#include <stdarg.h> | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <time.h> | ||
#include "../xatlas_c.h" | ||
#include "objzero/objzero.h" | ||
|
||
#ifdef _MSC_VER | ||
#define STRICMP _stricmp | ||
#include <windows.h> | ||
static CRITICAL_SECTION s_progressMutex; | ||
#else | ||
#include <strings.h> | ||
#define STRICMP strcasecmp | ||
#endif | ||
|
||
static bool s_verbose = false; | ||
|
||
static int Print(const char *format, ...) | ||
{ | ||
va_list arg; | ||
va_start(arg, format); | ||
printf("\r"); // Clear progress text. | ||
const int result = vprintf(format, arg); | ||
va_end(arg); | ||
return result; | ||
} | ||
|
||
// May be called from any thread. | ||
static bool ProgressCallback(xatlasProgressCategory category, int progress, void *userData) | ||
{ | ||
(void)userData; | ||
// Don't interupt verbose printing. | ||
if (s_verbose) | ||
return true; | ||
#ifdef _MSC_VER | ||
EnterCriticalSection(&s_progressMutex); | ||
#endif | ||
printf("\r %s [", xatlasProgressCategoryString(category)); | ||
for (int i = 0; i < 10; i++) | ||
printf(progress / ((i + 1) * 10) ? "*" : " "); | ||
printf("] %d%%", progress); | ||
fflush(stdout); | ||
if (progress == 100) | ||
printf("\n"); | ||
#ifdef _MSC_VER | ||
LeaveCriticalSection(&s_progressMutex); | ||
#endif | ||
return true; | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
#ifdef _MSC_VER | ||
InitializeCriticalSection(&s_progressMutex); | ||
#endif | ||
if (argc < 2) { | ||
printf("Usage: %s input_file.obj [options]\n", argv[0]); | ||
printf(" Options:\n"); | ||
printf(" -verbose\n"); | ||
return 1; | ||
} | ||
s_verbose = (argc >= 3 && STRICMP(argv[2], "-verbose") == 0); | ||
// Load object file. | ||
printf("Loading '%s'...\n", argv[1]); | ||
objz_setIndexFormat(OBJZ_INDEX_FORMAT_U32); | ||
objzModel *model = objz_load(argv[1]); | ||
if (!model) { | ||
printf("%s\n", objz_getError()); | ||
return EXIT_FAILURE; | ||
} | ||
if (objz_getError()) // Print warnings. | ||
printf("%s\n", objz_getError()); | ||
// Create empty atlas. | ||
xatlasSetPrint(Print, s_verbose); | ||
xatlasAtlas *atlas = xatlasCreate(); | ||
// Set progress callback. | ||
xatlasSetProgressCallback(atlas, ProgressCallback, NULL); | ||
// Add mesh to atlas. | ||
const uint32_t vertexStride = (uint32_t)(sizeof(float) * 8); | ||
xatlasMeshDecl meshDecl; | ||
xatlasMeshDeclInit(&meshDecl); | ||
meshDecl.vertexCount = model->numVertices; | ||
meshDecl.vertexPositionData = model->vertices; | ||
meshDecl.vertexPositionStride = vertexStride; | ||
if (model->flags & OBJZ_FLAG_NORMALS) { | ||
meshDecl.vertexNormalData = (float *)model->vertices + 5; | ||
meshDecl.vertexNormalStride = vertexStride; | ||
} | ||
if (model->flags & OBJZ_FLAG_TEXCOORDS) { | ||
meshDecl.vertexUvData = (float *)model->vertices + 3; | ||
meshDecl.vertexUvStride = vertexStride; | ||
} | ||
meshDecl.indexCount = model->numIndices; | ||
meshDecl.indexData = model->indices; | ||
meshDecl.indexFormat = XATLAS_INDEX_FORMAT_UINT32; | ||
xatlasAddMeshError error = xatlasAddMesh(atlas, &meshDecl, 1); | ||
if (error != XATLAS_ADD_MESH_ERROR_SUCCESS) { | ||
xatlasDestroy(atlas); | ||
printf("\rError adding mesh: %s\n", xatlasAddMeshErrorString(error)); | ||
return EXIT_FAILURE; | ||
} | ||
xatlasAddMeshJoin(atlas); // Not necessary. Only called here so geometry totals are printed after the AddMesh progress indicator. | ||
printf(" %u total vertices\n", meshDecl.vertexCount); | ||
printf(" %u total faces\n", meshDecl.indexCount / 3); | ||
// Generate atlas. | ||
printf("Generating atlas\n"); | ||
xatlasGenerate(atlas, NULL, NULL); | ||
printf(" %d charts\n", atlas->chartCount); | ||
printf(" %d atlases\n", atlas->atlasCount); | ||
for (uint32_t i = 0; i < atlas->atlasCount; i++) | ||
printf(" %d: %0.2f%% utilization\n", i, atlas->utilization[i] * 100.0f); | ||
printf(" %ux%u resolution\n", atlas->width, atlas->height); | ||
printf(" %u total vertices\n", atlas->meshes[0].vertexCount); | ||
// Cleanup. | ||
xatlasDestroy(atlas); | ||
objz_destroy(model); | ||
printf("Done\n"); | ||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,12 +31,26 @@ Copyright NVIDIA Corporation 2006 -- Ignacio Castano <[email protected]> | |
#pragma once | ||
#ifndef XATLAS_C_H | ||
#define XATLAS_C_H | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef XATLAS_EXPORT_API | ||
#define XATLAS_EXPORT_API 0 | ||
#endif | ||
|
||
#ifndef XATLAS_API | ||
#if XATLAS_EXPORT_API | ||
#define XATLAS_API __declspec(dllexport) | ||
#else | ||
#define XATLAS_API | ||
#endif | ||
#endif | ||
|
||
typedef enum | ||
{ | ||
XATLAS_CHART_TYPE_PLANAR, | ||
|
@@ -195,23 +209,23 @@ typedef void *(*xatlasReallocFunc)(void *, size_t); | |
typedef void (*xatlasFreeFunc)(void *); | ||
typedef int (*xatlasPrintFunc)(const char *, ...); | ||
|
||
xatlasAtlas *xatlasCreate(); | ||
void xatlasDestroy(xatlasAtlas *atlas); | ||
xatlasAddMeshError xatlasAddMesh(xatlasAtlas *atlas, const xatlasMeshDecl *meshDecl, uint32_t meshCountHint); | ||
void xatlasAddMeshJoin(xatlasAtlas *atlas); | ||
xatlasAddMeshError xatlasAddUvMesh(xatlasAtlas *atlas, const xatlasUvMeshDecl *decl); | ||
void xatlasComputeCharts(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions); | ||
void xatlasPackCharts(xatlasAtlas *atlas, const xatlasPackOptions *packOptions); | ||
void xatlasGenerate(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions, const xatlasPackOptions *packOptions); | ||
void xatlasSetProgressCallback(xatlasAtlas *atlas, xatlasProgressFunc progressFunc, void *progressUserData); | ||
void xatlasSetAlloc(xatlasReallocFunc reallocFunc, xatlasFreeFunc freeFunc); | ||
void xatlasSetPrint(xatlasPrintFunc print, bool verbose); | ||
const char *xatlasAddMeshErrorString(xatlasAddMeshError error); | ||
const char *xatlasProgressCategoryString(xatlasProgressCategory category); | ||
void xatlasMeshDeclInit(xatlasMeshDecl *meshDecl); | ||
void xatlasUvMeshDeclInit(xatlasUvMeshDecl *uvMeshDecl); | ||
void xatlasChartOptionsInit(xatlasChartOptions *chartOptions); | ||
void xatlasPackOptionsInit(xatlasPackOptions *packOptions); | ||
XATLAS_API xatlasAtlas *xatlasCreate(); | ||
XATLAS_API void xatlasDestroy(xatlasAtlas *atlas); | ||
XATLAS_API xatlasAddMeshError xatlasAddMesh(xatlasAtlas *atlas, const xatlasMeshDecl *meshDecl, uint32_t meshCountHint); | ||
XATLAS_API void xatlasAddMeshJoin(xatlasAtlas *atlas); | ||
XATLAS_API xatlasAddMeshError xatlasAddUvMesh(xatlasAtlas *atlas, const xatlasUvMeshDecl *decl); | ||
XATLAS_API void xatlasComputeCharts(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions); | ||
XATLAS_API void xatlasPackCharts(xatlasAtlas *atlas, const xatlasPackOptions *packOptions); | ||
XATLAS_API void xatlasGenerate(xatlasAtlas *atlas, const xatlasChartOptions *chartOptions, const xatlasPackOptions *packOptions); | ||
XATLAS_API void xatlasSetProgressCallback(xatlasAtlas *atlas, xatlasProgressFunc progressFunc, void *progressUserData); | ||
XATLAS_API void xatlasSetAlloc(xatlasReallocFunc reallocFunc, xatlasFreeFunc freeFunc); | ||
XATLAS_API void xatlasSetPrint(xatlasPrintFunc print, bool verbose); | ||
XATLAS_API const char *xatlasAddMeshErrorString(xatlasAddMeshError error); | ||
XATLAS_API const char *xatlasProgressCategoryString(xatlasProgressCategory category); | ||
XATLAS_API void xatlasMeshDeclInit(xatlasMeshDecl *meshDecl); | ||
XATLAS_API void xatlasUvMeshDeclInit(xatlasUvMeshDecl *uvMeshDecl); | ||
XATLAS_API void xatlasChartOptionsInit(xatlasChartOptions *chartOptions); | ||
XATLAS_API void xatlasPackOptionsInit(xatlasPackOptions *packOptions); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
|