ページ 11

PSPSDKによる3D表示について

Posted: 2014年1月21日(火) 23:37
by メカ
PSPSDKを使って3Dモデルの表示をしたいのですが上手くできません。
恐らくどこかのコードが間違っていると思います。
もしくはやり方が全然違うかもしれません
下記のコードで
int model_test=LoadModel("test.x");
DrawModel(VGet(0.0f,0.0f,0.0f),model_test);
を実行すると表示出来るようにしたいのですがどこが間違ってるか教えて下さい。
VGetは表示する位置の設定用につけましたがまだ未実装です。
色などもまだ出来てません。
実行すると変な三角形が出てきて3Dモデルでは無いものが出てきます。
恐らくどこかが間違えていると思われます。
どなたか助けてください
ご回答お待ちしておりますm(__)m

コード:

#include <pspkernel.h>
#include <psprtc.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include <pspgum.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fastmath.h>

#define MODELDATASIZE 5000
#define MODELNUM 2

PSP_MODULE_INFO( "walk_through", PSP_MODULE_USER, 1, 0 );
PSP_MAIN_THREAD_ATTR( PSP_THREAD_ATTR_USER );

typedef ScePspFVector3 VECTOR;
int numModel;

/*
typedef struct VertexN8V32F
{
	s8 nx, ny, nz;
	float x, y, z;
}VertexN8V32F;*/
typedef struct ModelData{
	int numVertices;//頂点数
	int numFaces;//面数
	float normal_x[MODELDATASIZE],normal_y[MODELDATASIZE],normal_z[MODELDATASIZE];//法線
	float x[MODELDATASIZE], y[MODELDATASIZE], z[MODELDATASIZE];
	int index[MODELDATASIZE * 3];
	float texture_x[MODELDATASIZE],texture_y[MODELDATASIZE];//UVマップ
};
//グローバル変数
struct ModelData Model[MODELNUM];
static u32 __attribute__((aligned(16)))guList[262144];

static inline VECTOR VGet(float x,float y,float z){VECTOR res = {x,y,z};return res;}

static int exit_callback( int arg1, int arg2, void *common )
{
	sceKernelExitGame();
	return 0;
}
static int CallbackThread( SceSize args, void *argp )
{
	sceKernelRegisterExitCallback( sceKernelCreateCallback("Exit Callback", exit_callback, NULL) );
	sceKernelSleepThreadCB();
	return 0;
}
static int SetUpCallbacks()
{
	SceUID thid = sceKernelCreateThread( "update_thread", CallbackThread, 0x11, 0xFA0, 0, NULL );	
	if( thid >= 0 )
		sceKernelStartThread( thid, 0, 0 );

	return thid;
}
void DrawModel(VECTOR pos,int mhandle){
	VertexN8V32F *vertices;
	if( sceGuGetStatus( GU_TEXTURE_2D ) )sceGuDisable( GU_TEXTURE_2D );
	vertices = (VertexN8V32F*)sceGuGetMemory( Model[mhandle].numFaces * 3 * sizeof(VertexN8V32F) );
	// 法線ベクトルの設定
	for(int i=0,j=0;i<Model[mhandle].numFaces;i++,j=j+3){
		vertices[i].nx = Model[numModel].x[Model[numModel].index[j]];
		vertices[i].ny = Model[numModel].y[Model[numModel].index[j+1]];
		vertices[i].nz = Model[numModel].z[Model[numModel].index[j+2]];
			}
	//3D描画
	sceGumDrawArray( GU_TRIANGLES, GU_NORMAL_8BIT|GU_VERTEX_32BITF|GU_TRANSFORM_3D, Model[mhandle].numFaces * 3, NULL, vertices );

}
int LoadModel(char*filename){
	numModel++;
    //C言語のファイルポインタを用いてファイルオープン
    FILE *fp;
    //if ((fp = fopen(filename, "r")) == NULL)NSLog(@"can not open file");
	fp = fopen(filename, "r");
    char texname[300] = {0};//テクスチャ(画像)ファイル名
    char ext[3] = {0};
    char keyword[300] = {0};//ファイル文字読み込み用 関数名
    char string[300] = {0};//ファイル文字読み込み用 行読み込み
    float x,y,z = 0;
    float u,v = 0;
    int dammy,//4のインデックス(四角形)を検索用
		id0,id1,id2,id3 = 0;
    int Plus_NumIndex = 0;
    fseek(fp,SEEK_SET,0);
    while(!feof(fp)){
        //キーワードを読み込む
        fscanf(fp,"%s",&keyword);
        //頂点
        //keywordに読み込んだ文字列と"Mesh"が一致したとき
        if(strcmp(keyword,"Mesh") == 0){
            //2回改行
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            //頂点数
            Model[numModel].numVertices = atoi(string);
            //頂点数だけ改行、面数が記載されている行へ
            for(int i = 0; i < Model[numModel].numVertices ; i++)
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            //面数
            fgets(string,sizeof(string),fp);
            //面数
            Model[numModel].numFaces = atoi(string);
            //4のインデックスを調査
            for(int i = 0; i < Model[numModel].numFaces; i++){
                fscanf(fp,"%d;",&dammy);	
                fgets(string,sizeof(string),fp);
                //4のインデックス
                if(dammy == 4){
					//三角形に分割するので面が増える
                    //それを今カウント
                    Plus_NumIndex++;
                }
            }
            //面数に増える面数を足す
            Model[numModel].numFaces = Model[numModel].numFaces + Plus_NumIndex;
        }
   } 
    int NumIndex = Model[numModel].numFaces*3;
    //インデックスのメモリ確保
    ushort index[NumIndex];
    //ファイルポインタを先頭へ
    fseek(fp,SEEK_SET,0);
    while(!feof(fp)){
		//キーワードを読み込む
        fscanf(fp,"%s",&keyword);
        //キーワードが"Mesh"のとき
        if(strcmp(keyword,"Mesh") == 0){
            //2回改行
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            //頂点座標
            for(int i = 0; i < Model[numModel].numVertices; i++){
                //fscanf(fp,"%f;%f;%f;,",&x,&y,&z);
                Model[numModel].x[i] = x;
                Model[numModel].y[i] = y;
                Model[numModel].z[i] = z;
            }
            //3回改行
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            //インデックスデータ
            for(int i = 0,j = 0, n = NumIndex; i < n; i+=3,j++){	
                fscanf(fp,"%d;",&dammy);	
                //4のインデックス
                if(dammy == 4){	
					//二つの三角形に分割
                    fscanf(fp,"%d,%d,%d,%d;,",&id0,&id1,&id2,&id3);
                    index[i] = id0;		Model[numModel].index[i]= id0;//Model[numModel].nx[j] = id0;
                    index[i + 1] = id1;	Model[numModel].index[i+1]= id1;//Model[numModel].ny[j] = id0;
                    index[i + 2] = id3;	Model[numModel].index[i+2]= id3;//Model[numModel].nz[j] = id0;
                    i+=3;	
                    index[i] = id1;		Model[numModel].index[i]= id1;
                    index[i + 1] = id2;	Model[numModel].index[i+1]= id2;
                    index[i + 2] = id3;	Model[numModel].index[i+2]= id3;
                }
                //3のインデックス
                if(dammy == 3){
                    //そのままイ読み込む
                    fscanf(fp,"%d,%d,%d;,",&id0,&id1,&id2);
                    index[i] = id0;		Model[numModel].index[i]= id0;
                    index[i + 1] = id1;	Model[numModel].index[i+1]= id1;
                    index[i + 2] = id2;	Model[numModel].index[i+2]= id2;
                }	
            }
        }
	//テクスチャファイル名を取得
        if(strcmp(keyword,"TextureFilename") == 0){
            fgets(string,sizeof(string),fp);
            //テクスチャファイル名
            fscanf(fp,"%s",&texname); 
            //2重引用符を除去
            for(int i=0; i<300; i++){
                if(texname[i] == '\"')
                    texname[i] = '\0';
            }
            for(int i=0; i<300; i++)
                texname[i] = texname[i+1];
            //画像ファイルの拡張子を得る
            for(int i=0; i<300; i++){
                if(texname[i] == '.'){
                    ext[0] = texname[i+1];
                    ext[1] = texname[i+2];
                    ext[2] = texname[i+3];
                    texname[i] = '\0';
                    texname[i+1] = '\0';
                    texname[i+2] = '\0';
                    texname[i+3] = '\0';
                }
            }
        }
    //法線
    if(strcmp(keyword,"MeshNormals") == 0){
        //2回改行
        fgets(string,sizeof(string),fp);
        fgets(string,sizeof(string),fp);
        //法線
        for(int i = 0; i < Model[numModel].numVertices; i++){
            fscanf(fp,"%f;%f;%f;,",&x,&y,&z);
            Model[numModel].normal_x[i] = x;
            Model[numModel].normal_y[i] = y;
            Model[numModel].normal_z[i] = z;
        }
    }
        //UV
        if(strcmp(keyword,"MeshTextureCoords") == 0){
            //2回改行
            fgets(string,sizeof(string),fp);
            fgets(string,sizeof(string),fp);
            //UV
            for(int i = 0; i < Model[numModel].numVertices; i++){
                fscanf(fp,"%f;%f;,",&u,&v);
                Model[numModel].texture_x[i] = u;
                Model[numModel].texture_y[i] = v;
            }
        }
    }
    fclose(fp);
	return (numModel);
}