我需要在本机代码中使用const char *
,因此,我将java端的参数作为jstring
并使用以下语句
JNIEXPORT int JNICALL JNIFUNCTION_DEMO(AddMarkerAndModel(JNIEnv* env, jobject object, jstring modelfileString , jstring marker_config_string)) {
int free_marker_space_index=-1;
for (int i = 0; i < NUM_MODELS; i++) {
if (models[i].not_null==false) {
free_marker_space_index = i;
break;
}
}
if(free_marker_space_index==-1){
//means no space for marker left
return free_marker_space_index;
}
const char *marker_config = env->GetStringUTFChars( marker_config_string, NULL);
LOGE("[KARTIK]marker_config is : %s",marker_config);
models[free_marker_space_index].patternID = arwAddMarker(marker_config);
arwSetMarkerOptionBool(models[free_marker_space_index].patternID, ARW_MARKER_OPTION_SQUARE_USE_CONT_POSE_ESTIMATION, false);
arwSetMarkerOptionBool(models[free_marker_space_index].patternID, ARW_MARKER_OPTION_FILTERED, true);
const char *modelfile = env->GetStringUTFChars( modelfileString, NULL);
LOGE("[KARTIK]modelFile is : %s",modelfile);
models[free_marker_space_index].obj = glmReadOBJ2(modelfile, 0, 0); // context 0, don't read textures yet.
if (!models[free_marker_space_index].obj) {
LOGE("Error loading model from file '%s'.", modelfile);
exit(-1);
}
// LOGV("just checking this function..no error..don't worry");
//printf("just checking this function..no error..don't worry");
glmScale(models[free_marker_space_index].obj, 0.035f);
//glmRotate(models[0].obj, 3.14159f / 2.0f, 1.0f, 0.0f, 0.0f);
glmCreateArrays(models[free_marker_space_index].obj, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
models[free_marker_space_index].visible = false;
models[free_marker_space_index].not_null=true;
//LOGV("ReleaseStringUTFChars");
env->ReleaseStringUTFChars(modelfileString, modelfile);
env->ReleaseStringUTFChars(marker_config_string, marker_config);
return free_marker_space_index;
}
该函数表示无法读取其代码在glm.c中的mtl文件..该文件的一部分在下面...看一下ReadOBJ和ReadMTL函数
#include <Eden/glm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h> // USHRT_MAX
#include <Eden/EdenMath.h> // M_PI, sqrtf(), acosf(), asinf(), fabsf()
#ifndef EDEN_OPENGLES
# define DISABLE_GL_STATE_CACHE
#endif
#include "glStateCache.h"
#ifndef GL_GENERATE_MIPMAP
# define GL_GENERATE_MIPMAP 0x8191
#endif
#define glmDefaultGroupName "default"
#define T(x) (model->triangles[(x)])
/* _GLMnode: general purpose node, used by glmVertexNormals() to build a
linked list of triangles containing a particular vertex. */
typedef struct _GLMnode {
GLuint index; // Which triangle this node is tracking.
GLuint indexindex; // Which of the points in this triangle this node is tracking.
GLboolean averaged;
struct _GLMnode* next; // The next node in the list, or NULL if this node is the tail.
} GLMnode;
/* _GLMnode: general purpose node, used by glmDrawArrays() to build a
linked list of triangles containing a particular vertex. */
typedef struct _GLMnode2 {
GLushort index; // Index into list of per-vertex data values. Each 3 defines a triangle.
struct _GLMnode2* next; // The next node in the list, or NULL if this node is the tail.
} GLMnode2;
#define glmMax(a, b) ((a) > (b) ? (a) : (b))
#define glmMin(a, b) ((a) < (b) ? (a) : (b))
/* glmFindMaterial: Find a material in the model */
static GLuint glmFindMaterial(GLMmodel* model, char* name)
{
GLuint i;
/* XXX doing a linear search on a string key'd list is pretty lame,
but it works and is fast enough for now. */
for (i = 0; i < model->nummaterials; i++) {
if (!strcmp(model->materials[i].name, name))
goto found;
}
/* didn't find the name, so print a warning and return the default
material (0). */
EDEN_LOGe("glmFindMaterial(): can't find material \"%s\".\n", name);
i = 0;
found:
return i;
}
/* glmDirName: return the directory given a path
*
* path - filesystem path
*
* NOTE: the return value should be free'd.
*/
static char*
glmDirName(char* path)
{
char* dir;
char* s;
dir = strdup(path);
s = strrchr(dir, '/');
if (s)
s[1] = '\0'; // place end of string after last separator
else
dir[0] = '\0';
return dir;
}
#ifdef GLM_MATERIAL_TEXTURES
static GLboolean readTextureAndSendToGL(const int contextIndex, char *texturefilename, TEXTURE_INDEX_t *texturemap_index, char *texturemap_hasAlpha, const GLboolean flipH, const GLboolean flipV)
{
TEXTURE_INFO_t textureInfo = { // PRL 2003-08-06: Defaults for texturemaps.
NULL, // pointer to name will go here.
GL_TRUE, // generate mipmaps.
0, // internal format (0 = don't attempt conversion).
GL_LINEAR_MIPMAP_LINEAR, // minification mode.
GL_LINEAR, // magnification mode.
GL_REPEAT, // wrap_s.
GL_REPEAT, // wrap_t.
0.5, // priority.
GL_REPLACE, // env_mode.
//{0.0,0.0,0.0,0.0} // env_color.
};
static char initedSurfaces = FALSE;
textureInfo.pathname = texturefilename;
if (!initedSurfaces) {
EdenSurfacesInit(1, 256); // Up to 256 textures, into 1 OpenGL context.
initedSurfaces = TRUE;
}
if (!EdenSurfacesTextureLoad2(contextIndex, 1, &textureInfo, texturemap_index, texturemap_hasAlpha, flipH, flipV)) {
EDEN_LOGe("EdenSurfacesTextureLoad() couldn't read texture file \"%s\".\n", texturefilename);
return (FALSE);
}
return (TRUE);
}
#endif // GLM_MATERIAL_TEXTURES
/* glmReadMTL: read a wavefront material library file
*
* model - properly initialized GLMmodel structure
* name - name of the material library
* contextIndex - PRL: index to the current OpenGL context (for texturing.) If you have only
* one OpenGL context (the most common case) set this parameter to 0.
*/
static GLboolean
glmReadMTL(GLMmodel* model, char* name, const int contextIndex, const GLboolean readTexturesNow)
{
FILE* file;
char* dir;
char* filename;
char buf[128];
GLuint nummaterials, i;
dir = glmDirName(model->pathname);
filename = (char*)malloc(sizeof(char) * (strlen(dir) + strlen(name) + 1));
strcpy(filename, dir);
strcat(filename, name);
free(dir);
file = fopen(filename, "r");
if (!file) {
EDEN_LOGe("glmReadMTL() failed: can't open material file \"%s\".\n", filename);
return (FALSE);
}
/* count the number of materials in the file */
nummaterials = 1; // default material 0 is always defined.
while(fscanf(file, "%s", buf) != EOF) {
switch(buf[0]) {
case '#': /* comment */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
case 'n': /* newmtl */
fgets(buf, sizeof(buf), file);
nummaterials++;
//sscanf(buf, "%s %s", buf, buf);
break;
default:
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
}
}
rewind(file);
model->materials = (GLMmaterial*)malloc(sizeof(GLMmaterial) * nummaterials);
model->nummaterials = nummaterials;
/* set the defaults for each material */
for (i = 0; i < nummaterials; i++) {
model->materials[i].name = NULL;
model->materials[i].shininess = 65.0;
model->materials[i].diffuse[0] = 0.8;
model->materials[i].diffuse[1] = 0.8;
model->materials[i].diffuse[2] = 0.8;
model->materials[i].diffuse[3] = 1.0; // Opaque.
model->materials[i].ambient[0] = 0.2;
model->materials[i].ambient[1] = 0.2;
model->materials[i].ambient[2] = 0.2;
model->materials[i].ambient[3] = 1.0;
model->materials[i].specular[0] = 0.0;
model->materials[i].specular[1] = 0.0;
model->materials[i].specular[2] = 0.0;
model->materials[i].specular[3] = 1.0;
#ifdef GLM_MATERIAL_TEXTURES
model->materials[i].texturemap = NULL; // PRL 20030806: No texture by default.
model->materials[i].texturemappath = NULL;
model->materials[i].texturemap_index = (TEXTURE_INDEX_t)0;
model->materials[i].texturemap_hasAlpha = 0;
#endif // GLM_MATERIAL_TEXTURES
model->materials[i].illum = 2; // Is 2 the default?
}
model->materials[0].name = strdup("default");
/* now, read in the data */
nummaterials = 0;
while(fscanf(file, "%s", buf) != EOF) {
switch(buf[0]) {
case '#': /* comment */
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
case 'n': /* newmtl */
fgets(buf, sizeof(buf), file);
sscanf(buf, "%s %s", buf, buf);
nummaterials++;
model->materials[nummaterials].name = strdup(buf);
break;
case 'N':
switch (buf[1]) {
case 's':
fscanf(file, "%f", &model->materials[nummaterials].shininess);
/* wavefront shininess is from [0, 1000], so scale to [0, 127] for OpenGL */
model->materials[nummaterials].shininess /= 1000.0;
model->materials[nummaterials].shininess *= 128.0;
break;
default:
// Unsupported options:
// Ni = Refraction index. Values range from 1 upwards. A value of 1 will cause no refraction. A higher value implies refraction.
fgets(buf, sizeof(buf), file);
break;
}
break;
case 'K':
switch(buf[1]) {
case 'd':
fscanf(file, "%f %f %f",
&model->materials[nummaterials].diffuse[0],
&model->materials[nummaterials].diffuse[1],
&model->materials[nummaterials].diffuse[2]);
break;
case 's':
fscanf(file, "%f %f %f",
&model->materials[nummaterials].specular[0],
&model->materials[nummaterials].specular[1],
&model->materials[nummaterials].specular[2]);
break;
case 'a':
fscanf(file, "%f %f %f",
&model->materials[nummaterials].ambient[0],
&model->materials[nummaterials].ambient[1],
&model->materials[nummaterials].ambient[2]);
break;
default:
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
}
break;
case 'd': // PRL 20030806: dissolve factor, pseudo-transparency.
fscanf(file, "%f", &model->materials[nummaterials].diffuse[3]);
break;
#ifdef GLM_MATERIAL_TEXTURES
case 'm': // PRL 20030806: texturemap.
if (strstr(buf, "map_Kd")) { // Process diffuse colour map.
fgets(buf, sizeof(buf), file); // Read up to (and including) EOL from file into string.
buf[strlen(buf)-1] = '\0'; // nuke '\n'.
model->materials[nummaterials].texturemap = strdup(buf+1); // Save relative path from mtl file. +1 skips leading space.
// Handle relative paths from model and material.
dir = glmDirName(filename);
model->materials[nummaterials].texturemappath = (char*)malloc(sizeof(char) * (strlen(dir) + strlen(model->materials[nummaterials].texturemap) + 1));
strcpy(model->materials[nummaterials].texturemappath, dir);
strcat(model->materials[nummaterials].texturemappath, model->materials[nummaterials].texturemap);
free(dir);
if (readTexturesNow) {
if (!readTextureAndSendToGL(contextIndex, model->materials[nummaterials].texturemappath, &(model->materials[nummaterials].texturemap_index), &(model->materials[nummaterials].texturemap_hasAlpha), FALSE, model->flipTextureV)) {
EDEN_LOGe("glmReadMTL(): Error loading texture.\n");
}
}
} else {
// Unsupported options:
// map_Ka, ambient colour map.
// map_Ks, specular colour map.
fgets(buf, sizeof(buf), file); // eat up rest of line.
}
break;
#endif // GLM_MATERIAL_TEXTURES
case 'i': // Illumination model.
fscanf(file, "%d", &model->materials[nummaterials].illum);
break;
default:
/* eat up rest of line */
fgets(buf, sizeof(buf), file);
break;
}
}
free(filename);
return (TRUE);
}
/* glmWriteMTL: write a wavefront material library file
*
* model - properly initialized GLMmodel structure
* modelpath - pathname of the model being written
* mtllibname - name of the material library to be written
*/
static GLvoid
glmWriteMTL(GLMmodel* model, char* modelpath, char* mtllibname)
{
FILE* file;
char* dir;
char* filename;
GLMmaterial* material;
GLuint i;
dir = glmDirName(modelpath);
filename = (char*)malloc(sizeof(char) * (strlen(dir)+strlen(mtllibname)));
strcpy(filename, dir);
strcat(filename, mtllibname);
free(dir);
/* open the file */
file = fopen(filename, "w");
if (!file) {
EDEN_LOGe("glmWriteMTL() failed: can't open file \"%s\".\n",
filename);
exit(1);
}
free(filename);
/* spit out a header */
fprintf(file, "# \n");
fprintf(file, "# Wavefront MTL generated by GLM library\n");
fprintf(file, "# \n");
fprintf(file, "# GLM library\n");
fprintf(file, "# Nate Robins\n");
fprintf(file, "# [email protected]\n");
fprintf(file, "# http://www.pobox.com/~ndr\n");
fprintf(file, "# \n\n");
for (i = 0; i < model->nummaterials; i++) {
material = &model->materials[i];
fprintf(file, "newmtl %s\n", material->name);
fprintf(file, "Ka %f %f %f\n",
material->ambient[0], material->ambient[1], material->ambient[2]);
fprintf(file, "Kd %f %f %f\n",
material->diffuse[0], material->diffuse[1], material->diffuse[2]);
fprintf(file, "Ks %f %f %f\n",
material->specular[0],material->specular[1],material->specular[2]);
fprintf(file, "Ns %f\n", material->shininess / 128.0 * 1000.0);
if (material->diffuse[3] != 1.0) fprintf(file, "d %f\n", material->diffuse[3]); // PRL 20030806: dissolve factor, pseudo-transparency.
#ifdef GLM_MATERIAL_TEXTURES
if (material->texturemap) fprintf(file, "map_Kd %s\n", material->texturemap); // PRL 20030806: texturemap.
#endif // GLM_MATERIAL_TEXTURES
fprintf(file, "illum %d\n", material->illum);
fprintf(file, "\n");
}
}
static void trim(char *buf)
{
size_t index;
if (!buf) return;
index = strlen(buf);
if (!index) return;
index--;
// Strip trailing CR and NL chars.
while (index && (buf[index] == '\r' || buf[index] == '\n')) {
buf[index] = '\0';
index--;
}
}
GLMmodel*
glmReadOBJ(const char *filename, const int contextIndex)
{
return (glmReadOBJ3(filename, contextIndex, TRUE, FALSE));
}
GLMmodel*
glmReadOBJ2(const char *filename, const int contextIndex, const GLboolean readTexturesNow)
{
return (glmReadOBJ3(filename, contextIndex, readTexturesNow, FALSE));
}
GLMmodel*
glmReadOBJ3(const char *filename, const int contextIndex, const GLboolean readTexturesNow, const GLboolean flipTextureV)
{
GLMmodel* model;
FILE* file;
/* open the file */
file = fopen(filename, "r");
if (!file) {
EDEN_LOGe("glmReadOBJ() failed: can't open data file \"%s\".\n", filename);
return (NULL);
}
/* allocate a new model */
model = (GLMmodel*)malloc(sizeof(GLMmodel));
model->pathname = strdup(filename);
model->mtllibname = NULL;
model->numvertices = 0;
model->vertices = NULL;
model->numnormals = 0;
model->normals = NULL;
model->numtexcoords = 0;
model->texcoords = NULL;
model->numfacetnorms = 0;
model->facetnorms = NULL;
model->numtriangles = 0;
model->triangles = NULL;
model->nummaterials = 0;
model->materials = NULL;
model->numgroups = 0;
model->groups = NULL;
model->arrays = NULL;
model->arrayMode = 0;
model->readTextureRequired = !readTexturesNow;
model->flipTextureV = flipTextureV;
/* make a first pass through the file to get a count of the number
of vertices, normals, texcoords & triangles */
glmFirstPass(model, file, contextIndex, readTexturesNow);
/* allocate memory */
model->vertices = (GLfloat*)malloc(sizeof(GLfloat) *
3 * (model->numvertices + 1)); // Uses + 1 because vertices, normals and texcoords are numbered from 1, not 0.
model->triangles = (GLMtriangle*)malloc(sizeof(GLMtriangle) *
model->numtriangles);
if (model->numnormals) {
model->normals = (GLfloat*)malloc(sizeof(GLfloat) *
3 * (model->numnormals + 1)); // Uses + 1 because vertices, normals and texcoords are numbered from 1, not 0.
}
if (model->numtexcoords) {
model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) *
2 * (model->numtexcoords + 1)); // Uses + 1 because vertices, normals and texcoords are numbered from 1, not 0.
}
/* rewind to beginning of file and read in the data this pass */
rewind(file);
glmSecondPass(model, file);
/* close the file */
fclose(file);
return model;
}
但是,以下代码段有效
JNIEXPORT void JNICALL JNIFUNCTION_DEMO(Initialise(JNIEnv* env, jobject object)) {
for(int i=0;i<NUM_MODELS;i++){
models[i].patternID=-1;
// models[i].transformationMatrix=PUT_SOME_PLACEHOLDER_TEMPORARY_VARIABLE_HERE;
models[i].visible=false;
models[i].obj=NULL;
models[i].not_null=false;
//mean they are null ...
}
const char *model1file = "Data/models/pinball/Ferrari_Modena_Spider.obj";
models[0].patternID = arwAddMarker("nft;DataNFT/pinball");
arwSetMarkerOptionBool(models[0].patternID, ARW_MARKER_OPTION_SQUARE_USE_CONT_POSE_ESTIMATION, false);
arwSetMarkerOptionBool(models[0].patternID, ARW_MARKER_OPTION_FILTERED, true);
models[0].obj = glmReadOBJ2(model1file, 0, 0); // context 0, don't read textures yet.
if (!models[0].obj) {
LOGE("Error loading model from file '%s'.", model1file);
exit(-1);
}
glmScale(models[0].obj, 0.035f);
//glmRotate(models[0].obj, 3.14159f / 2.0f, 1.0f, 0.0f, 0.0f);
glmCreateArrays(models[0].obj, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
models[0].visible = false;
models[0].not_null = true;
LOGE("trying to add a marker in Initialise");
}
唯一的区别似乎是,在初始化时,我已经对路径进行了硬编码....但是在addMarkerandModel中...我给它们作为通过jni传递的参数
请帮忙!!!!
最佳答案
只需几个步骤,即可在ARToolKit的glm中读取.obj文件。首先,解析.obj文件,然后加载所有引用的.mtl文件,最后,如果.mtl文件引用了纹理(ARToolKit的glm阅读器仅支持2幂次方的.sgi和JPEG),则OpenGL上下文可用后,这些文件将被延迟加载。
如果遇到无法找到.mtl文件的错误,则表明第一步实际上是正确的。 glm能够找到和读取.obj文件,但是.obj文件引用了找不到的.mtl文件。
在文本编辑器中浏览您的.obj文件,找到所有.mtl引用,然后进行编辑,以便引用正确的相对路径。
关于c++ - 无法将jstring用作 native 代码中的参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43842215/