GLMetaseq.c の中身 渡部修平 メタセコイアで作成した 3D モデルを OpenGL で表示させるためには, 工学ナビ ( が公開している C/C++ 用のライブラリ GLMetaseq があ
|
|
|
- あきたけ つちた
- 6 years ago
- Views:
Transcription
1 GLMetaseq.c の中身 渡部修平 メタセコイアで作成した 3D モデルを OpenGL で表示させるためには, 工学ナビ ( が公開している C/C++ 用のライブラリ GLMetaseq があります 作成しているぷろぐらむのプロジェクトに GLMetaseq.h と GLMetaseq.hc を追加し, プログラム中で GLMetaseq.h をインクルードして使用します 以下は GLMeataseq.c のソースです #define GLMETASEQ_C #include "GLMetaseq.h" /* GLMetaseq MIT ライセンス Copyright (c) 2009 Sunao Hashimoto and Keisuke Konishi 以下に定める条件に従い 本ソフトウェアおよび関連文書のファイル ( 以下 ソフトウェア ) の複製を取得するすべての人に対し ソフトウェアを無制限に扱うことを無償で許可します これには ソフトウェアの複製を使用 複写 変更 結合 掲載 頒布 サブライセンス および / または販売する権利 およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます 上記の著作権表示および本許諾表示を ソフトウェアのすべての複製または重要な部分に記載するものとします ソフトウェアは 現状のまま で 明示であるか暗黙であるかを問わず 何らの保証もなく提供されます ここでいう保証とは 商品性 特定の目的への適合性 および権利非侵害についての保証も含みますが それに限定されるものではありません 作者または著作権者は 契約行為 不法行為 またはそれ以外であろうと ソフトウェアに起因または関連し あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求 損害 その他の義務について何らの責任も負わないものとします */ このソース内でのみ有効なグローバル変数 static TEXTURE_POOL l_texpool[max_texture]; // テクスチャプール static int l_texpoolnum; // テクスチャの数 static int l_glmetaseqinitialized = 0; // 初期化フラグ 関数宣言 #ifdef cplusplus extern "C" void endianconverter(void *addr,unsigned int size); void TGAHeaderEndianConverter( STR_TGA_HEAD *tgah ); int IsExtensionSupported( char* sztargetextension ); GLuint mqosettexturepool(char *texfile, char *alpfile, unsigned char alpha ); void mqocleartexturepool(); GLubyte* mqoloadtextureex(char *texfile,char *alpfile,int *tex_size,unsigned char alpha); int mqoloadfile(mqo_object *mqoobj,char *filename,double scale,unsigned char alpha);
2 MQO_OBJECT* int mqocreatelist(int num); mqocreatelistobject( MQO_OBJECT *obj, int id, char *filename,double scale,unsigned char alpha); void void void void void void void int void void mqocalllistobject(mqo_object object[],int num); mqoclearobject(mqo_object object[],int from,int num); mqodeleteobject(mqo_object * object,int num); mqogetdirectory(const char *path_file, char *path_dir); mqosnormal(glpoint3f A, glpoint3f B, glpoint3f C, glpoint3f *normal); mqoreadmaterial(file *fp, MQO_MATDATA M[]); mqoreadvertex(file *fp, glpoint3f V[]); mqoreadbvertex(file *fp,glpoint3f V[]); mqoreadface(file *fp, MQO_FACE F[]); mqoreadobject(file *fp, MQO_OBJDATA *obj); void mqomakearray(mqo_material *mat, int matpos,mqo_face F[], int fnum,glpoint3f V[], glpoint3f N[], double facet, glcolor4f *mcol, double scale, unsigned char alpha ); glpoint3f *mqovertexnormal(mqo_objdata *obj); void mqomakepolygon(mqo_objdata *readobj, MQO_OBJECT *mqoobj, glpoint3f N[], MQO_MATDATA M[], int n_mat, double scale, unsigned char alpha); void mqomakeobjectsex(mqo_object *mqoobj, MQO_OBJDATA obj[], int n_obj, MQO_MATDATA M[],int n_mat, double scale,unsigned char alpha); #ifdef cplusplus 関数 endianconverter 用途 エンディアン変換 引数 addr アドレス size サイズ 戻値 なし void endianconverter(void *addr,unsigned int size) unsigned int pos; char c; if ( size <= 1 ) return; for ( pos = 0; pos < size/2; pos++ ) c = *(((char *)addr)+pos); *(((char *)addr)+pos) = *(((char *)addr)+(size-1 - pos)); *(((char *)addr)+(size-1 - pos)) = c; 関数 TGAHeaderEndianConverter 用途 TGAのヘッダのエンディアン変換 引数 tgah TGAのヘッダ 戻値 なし void TGAHeaderEndianConverter( STR_TGA_HEAD *tgah ) endianconverter(&tgah->color_map_entry,sizeof(tgah->color_map_entry)); endianconverter(&tgah->x,sizeof(tgah->x)); endianconverter(&tgah->y,sizeof(tgah->y)); endianconverter(&tgah->width,sizeof(tgah->width));
3 endianconverter(&tgah->height,sizeof(tgah->height)); 関数 IsExtensionSupported 用途 OpenGL の拡張機能がサポートされているかどうか調べる 引数 sztargetextension 拡張機能の名前 戻値 : サポートされている,: されていない int IsExtensionSupported( char* sztargetextension ) const unsigned char *pszextensions = NULL; const unsigned char *pszstart; unsigned char *pszwhere, *pszterminator; // Extension の名前が正しいか調べる (NULL や空白は NG) pszwhere = (unsigned char *) strchr( sztargetextension, ' ' ); if ( pszwhere *sztargetextension == (char)null ) return 0; // Extension の文字列を所得する pszextensions = glgetstring( GL_EXTENSIONS ); // 文字列の中に必要な extension があるか調べる pszstart = pszextensions; for (;;) pszwhere = (unsigned char *) strstr( (const char *) pszstart, sztargetextension ); if (!pszwhere ) break; pszterminator = pszwhere + strlen( sztargetextension ); if ( pszwhere == pszstart *( pszwhere - 1 ) == ' ' ) if ( *pszterminator == ' ' *pszterminator == (char)null ) return 1; pszstart = pszterminator; return 0; 関数 mqoinit 用途 メタセコイアローダの初期化 引数 なし 戻値 なし void mqoinit(void) // テクスチャプール初期化 memset(l_texpool,0,sizeof(l_texpool)); l_texpoolnum = 0; // 頂点バッファのサポートのチェック g_isvbosupported = IsExtensionSupported("GL_ARB_vertex_buffer_object"); // g_isvbosupported = 0; #ifdef WIN32 glgenbuffersarb = NULL; glbindbufferarb = NULL; glbufferdataarb = NULL; gldeletebuffersarb = NULL;
4 if ( g_isvbosupported ) // printf("opengl : 頂点バッファをサポートしているので使用します \n"); // GL 関数のポインタを所得する glgenbuffersarb = (PFNGLGENBUFFERSARBPROC) wglgetprocaddress("glgenbuffersarb"); glbindbufferarb = (PFNGLBINDBUFFERARBPROC) wglgetprocaddress("glbindbufferarb"); glbufferdataarb = (PFNGLBUFFERDATAARBPROC) wglgetprocaddress("glbufferdataarb"); gldeletebuffersarb = (PFNGLDELETEBUFFERSARBPROC) wglgetprocaddress("gldeletebuffersarb"); // 初期化フラグ l_glmetaseqinitialized = 1; 関数 mqocleanup 用途 メタセコイアローダの終了処理 引数 なし 戻値 なし void mqocleanup(void) mqocleartexturepool(); // テクスチャプールのクリア 関数 mqosettexturepool 用途 テクスチャプールにテクスチャを読み込む 引数 texfile テクスチャファイル名 alpfile アルファファイル名 alpha アルファ 戻値 テクスチャ ID 仕様 テクスチャがまだ読み込まれていなければ読み込み, テクスチャ登録すでに読み込まれていれば登録したものを返す. GLuint mqosettexturepool(char *texfile, char *alpfile, unsigned char alpha ) int pos; GLubyte *image; for ( pos = 0; pos < l_texpoolnum; pos++ ) if ( alpha!= l_texpool[pos].alpha ) continue; if ( texfile!= NULL ) if ( strcmp(texfile,l_texpool[pos].texfile)!= 0 ) continue; if ( alpfile!= NULL ) if ( strcmp(alpfile,l_texpool[pos].alpfile)!= 0 ) continue; break; if ( pos < l_texpoolnum ) // すでに読み込み済み return l_texpool[pos].texture_id; if ( MAX_TEXTURE <= pos ) printf("%s:mqosettexturepool テクスチャ読み込み領域不足 \n", FILE );
5 return -1; image = mqoloadtextureex(texfile,alpfile,&l_texpool[pos].texsize,alpha); if ( image == NULL ) return -1; if ( texfile!= NULL ) strncpy(l_texpool[pos].texfile,texfile,max_path); if ( alpfile!= NULL ) strncpy(l_texpool[pos].alpfile,alpfile,max_path); l_texpool[pos].alpha = alpha; glpixelstorei(gl_unpack_alignment,4); glpixelstorei(gl_pack_alignment,4); glgentextures(1,&l_texpool[pos].texture_id); glbindtexture(gl_texture_2d,l_texpool[pos].texture_id); // テクスチャを生成 // テクスチャの割り当て gltexparameteri(gl_texture_2d, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gltexparameteri(gl_texture_2d, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glteximage2d(gl_texture_2d, 0, GL_RGBA8, l_texpool[pos].texsize, l_texpool[pos].texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); l_texpoolnum = pos+1; // 登録すれば 読み込んだバッファは不要 free(image); glbindtexture(gl_texture_2d,0); // デフォルトテクスチャの割り当て return l_texpool[pos].texture_id; 関数 mqocleartexturepool() 用途 テクスチャプールの開放 引数 なし 戻値 なし void mqocleartexturepool() int pos; for ( pos = 0; pos < l_texpoolnum; pos++ ) gldeletetextures(1, &l_texpool[pos].texture_id); // テクスチャ情報を削除 memset(l_texpool,0,sizeof(l_texpool)); l_texpoolnum = 0; 関数 mqoloadtextureex 用途 ファイルからテクスチャ画像を作成する 引数 texfile ファイル名 alpfile アルファファイル名 tex_size テクスチャのサイズ ( 一辺の長さ ) を返す 戻値 テクスチャ画像へのポインタ ( 失敗時は NULL) 仕様 bit ビットマップ, および,24,32bitTGA サイズは 一辺がの n 乗の正方形 に限定 libjpeg,libpng( 外部ライブラリ ) が有れば JPEG,PNG の読み込み可能 GLubyte* mqoloadtextureex(char *texfile,char *alpfile,int *tex_size,unsigned char alpha) FILE *fp;
6 size_t namelen; char ext[4]; char wbuf[3]; int istga; int ispng; int isjpeg; int other; int y,x,size; int fl; char *filename[2]; int width[2]; int sts; STR_TGA_HEAD tgah; GLubyte *pimage, *pread; #if DEF_USE_LIBJPEG struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPARRAY jpegimage; #if DEF_USE_LIBPNG unsigned char **pngimage; unsigned long pngwidth, pngheight; int int color_type; pngdepth; filename[0] = texfile; filename[1] = alpfile; width[0] = -1; width[1] = -1; pimage = NULL; fp = NULL; sts = 0; #if DEF_USE_LIBJPEG jpegimage = NULL; #if DEF_USE_LIBPNG pngimage = NULL; size = - 1; for ( fl = 0; fl < 2; fl++ ) // テクスチャ =fl=0 アルファ =fl=1 if ( filename[fl] == NULL ) continue; namelen = strlen(filename[fl]); ext[0] = tolower(filename[fl][namelen-3]); ext[1] = tolower(filename[fl][namelen-2]); ext[2] = tolower(filename[fl][namelen-1]); ext[3] = 0x00; istga = (strcmp(ext,"tga")==0)?1:0; ispng = (strcmp(ext,"png")==0)?1:0; isjpeg = (strcmp(ext,"jpg")==0)?1:0; /* */ if ( (! istga) && (! ispng) &&(! isjpeg) ) filename[fl][namelen-3] = 'b'; filename[fl][namelen-2] = 'm'; filename[fl][namelen-1] = 'p'; /* */ if ( fl == 1 ) // アルファの読み込みは TGAorPNG if (! (istga ispng) ) printf(" アルファのファイルに対応できない %s\n",filename[fl]); break; if ( fp!= NULL ) fclose(fp); if ( (fp=fopen(filename[fl],"rb"))==null ) printf("%s: テクスチャ読み込みエラー [%s]\n", FILE,filename[fl]); continue;
7 // ヘッダのロード if ( istga ) fread(&tgah,sizeof(str_tga_head),1,fp); #if DEF_IS_LITTLE_ENDIAN #else TGAHeaderEndianConverter(&tgah); size = width[fl] = tgah.width; if ( isjpeg ) #if DEF_USE_LIBJPEG unsigned int i; cinfo.err = jpeg_std_error( &jerr ); jpeg_create_decompress( &cinfo ); // 解凍用情報作成 jpeg_stdio_src( &cinfo, fp ); // 読み込みファイル指定 jpeg_read_header( &cinfo, TRUE ); //jpegヘッダ読み込み jpeg_start_decompress( &cinfo ); // 解凍開始 if ( cinfo.out_color_components == 3 && cinfo.out_color_space == JCS_RGB ) if ( jpegimage!= NULL ) for (i = 0; i < cinfo.output_height; i++) free(jpegimage[i]); // 以下 2 行は2 次元配列を解放します free(jpegimage); // 読み込みデータ配列の作成 jpegimage = (JSAMPARRAY)malloc( sizeof( JSAMPROW ) * cinfo.output_height ); for ( i = 0; i < cinfo.output_height; i++ ) jpegimage[i] = (JSAMPROW)malloc( sizeof( JSAMPLE ) * cinfo.out_color_components * cinfo.output_width ); // 解凍データ読み込み while( cinfo.output_scanline < cinfo.output_height ) jpeg_read_scanlines( &cinfo, jpegimage + cinfo.output_scanline, cinfo.output_height - cinfo.output_scanline ); size = width[fl] = cinfo.output_width; jpeg_finish_decompress( &cinfo ); // 解凍終了 jpeg_destroy_decompress( &cinfo ); // 解凍用情報解放 if (!(cinfo.out_color_components == 3 && cinfo.out_color_space == JCS_RGB) ) printf("jpeg 対応できないフォーマット %s\n",filename[fl]); #else printf(" このテクスチャは対応できないフォーマット %s\n",filename[fl]); continue; if ( ispng ) #if DEF_USE_LIBPNG png_structp png_ptr; png_infop info_ptr; int bit_depth, interlace_type; unsigned int i; int j,k; png_ptr = png_create_read_struct( // png_ptr 構造体を確保 初期化します PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); // info_ptr 構造体を確保 初期化します png_init_io(png_ptr, fp); // libpngにfpを知らせます png_read_info(png_ptr, info_ptr); // PNGファイルのヘッダを読み込みます png_get_ihdr(png_ptr, info_ptr, &pngwidth, &pngheight, // IHDRチャンク情報を取得します &bit_depth, &color_type, &interlace_type, &j,&k); if ( pngimage!= NULL )
8 す す for (i = 0; i < pngheight; i++) free(pngimage[i]); // 以下 2 行は 2 次元配列を解放しま free(pngimage); pngimage = (png_bytepp)malloc(pngheight * sizeof(png_bytep)); // 以下 3 行は2 次元配列を確保しま i = png_get_rowbytes(png_ptr, info_ptr); pngdepth = i / pngwidth; for (i = 0; i < pngheight; i++) pngimage[i] = (png_bytep)malloc(png_get_rowbytes(png_ptr, info_ptr)); png_read_image(png_ptr, pngimage); // 画像データを読み込みます png_destroy_read_struct( // 2つの構造体のメモリを解放します &png_ptr, &info_ptr, (png_infopp)null); size = width[fl] = pngwidth; #else printf(" このテクスチャは対応できないフォーマット %s\n",filename[fl]); continue; if ( width[fl] == -1 ) // ココまできてサイズが指定されていない = ビットマップ fseek(fp,14+4,seek_set); // 画像幅が格納されている位置までシーク fread(&size,sizeof(int),1,fp); // BiWidthの情報だけ取得 fseek(fp,14+40,seek_set); // 画素データが格納されている位置までシーク #if DEF_IS_LITTLE_ENDIAN #else endianconverter(&size,sizeof(int)); width[fl] = size; if ( width[0]!= -1 && width[1]!= -1 ) if ( width[0]!= width[1] ) sts = -1; break; if ( fl == 1 && istga ) // アルファの読み込みはTGAの8ビットモノクロor32ビットフル if (!( (tgah.depth == 8 && tgah.type == DEF_TGA_TYPE_MONO) (tgah.depth == 32 && tgah.type == DEF_TGA_TYPE_FULL) ) ) break; if ( fl == 1 && ispng ) // アルファの読み込みはPNGのトゥルーカラー +アルファorグレースケール+アルファ #if DEF_USE_LIBPNG if (!( (color_type== 6 ) (color_type== 4 ) ) ) break; // メモリの確保 if ( pimage == NULL ) pimage = (GLubyte*)malloc(sizeof(unsigned char)*size*size*4); if (pimage==null) return NULL; for (y=0; y<size; y++) pread = pimage + (size-1-y)*4*size; for (x=0; x<size; x++) other = 1; if ( fl == 0 )
9 #if DEF_USE_LIBJPEG #if DEF_USE_LIBPNG #if DEF_USE_LIBPNG fclose(fp); fp = NULL; else if ( isjpeg ) if ( ispng ) pread[0]= jpegimage[size-1-y][x*3]; pread[1]= jpegimage[size-1-y][x*3+1]; pread[2]= jpegimage[size-1-y][x*3+2]; pread[3] = alpha; other = 0; // A if ( color_type == 2 color_type==6 ) pread[0]= pngimage[size-1-y][x*pngdepth]; pread[1]= pngimage[size-1-y][x*pngdepth+1]; pread[2]= pngimage[size-1-y][x*pngdepth+2]; pread[3] = alpha; other = 0; // A if ( color_type == 6 ) pread[3]= pngimage[size-1-y][x*pngdepth+3]; if ( other ) fread(&pread[2],1,1,fp); // B fread(&pread[1],1,1,fp); // G fread(&pread[0],1,1,fp); // R pread[3] = alpha; // A if ( istga && tgah.depth == 32 ) fread(&pread[3],1,1,fp); // A if ( alpha < pread[3] ) pread[3] = alpha; if ( ispng ) if ( sts!= 0 ) if ( pimage!= NULL ) free(pimage); if ( fp!= NULL ) fclose(fp); #if DEF_USE_LIBPNG if ( pngimage!= NULL ) unsigned int uy; if ( color_type == 6 ) // トゥルーカラー + アルファ pread[3]= pngimage[size-1-y][x*pngdepth+3]; if ( color_type == 4 ) // グレースケール + アルファ pread[3]= pngimage[size-1-y][x*pngdepth+1]; if ( alpha < pread[3] ) pread[3] = alpha; if ( istga ) if ( tgah.depth == 32 ) // いらないデータを読み飛ばす fread(wbuf,3,1,fp); // BGR fread(&pread[3],1,1,fp); // A if ( alpha < pread[3] ) pread[3] = alpha; pread+=4; for (uy = 0; uy < pngheight; uy++) free(pngimage[uy]); free(pngimage); // 以下 2 行は 2 次元配列を解放します
10 #if DEF_USE_LIBJPEG if ( jpegimage!= NULL ) unsigned int uy; for (uy = 0; uy < cinfo.output_height; uy++) free(jpegimage[uy]); free(jpegimage); if ( size < 0 ) if ( pimage!= NULL ) free(pimage); pimage = NULL; *tex_size = size; // 以下 2 行は 2 次元配列を解放します return pimage; 関数 mqoloadfile 用途 メタセコイアファイル(*.mqo) からデータを読み込む 引数 mqoobj MQOオブジェクト filename ファイルのパス scale 拡大率 alpha アルファ 戻値 成功 :/ 失敗 : int mqoloadfile( MQO_OBJECT *mqoobj, char *filename, double scale, unsigned char alpha) FILE *fp; MQO_OBJDATA obj[max_object]; MQO_MATDATA *M = NULL; char buf[size_str]; // 文字列読み込みバッファ char path_dir[size_str]; // ディレクトリのパス char path_tex[size_str]; // テクスチャファイルのパス char path_alp[size_str]; // アルファテクスチャファイルのパス int n_mat = 0; // マテリアル数 int n_obj = 0; // オブジェクト数 int i; // Material と Object の読み込み fp = fopen(filename,"rb"); if (fp==null) return 0; mqoobj->alpha = alpha; memset(obj,0,sizeof(obj)); i = 0; while (!feof(fp) ) fgets(buf,size_str,fp); // Material if (strstr(buf,"material")) sscanf(buf,"material %d", &n_mat); M = (MQO_MATDATA*) calloc( n_mat, sizeof(mqo_matdata) ); mqoreadmaterial(fp,m); // Object if (strstr(buf,"object")) sscanf(buf,"object %s", obj[i].objname); mqoreadobject(fp, &obj[i]);
11 n_obj = i; fclose(fp); i++; // パスの取得 mqogetdirectory(filename, path_dir); // テクスチャの登録 for (i=0; i<n_mat; i++) if (M[i].useTex) if (strstr(m[i].texfile,":")) strcpy(path_tex, M[i].texFile); // 絶対パスの場合 else sprintf(path_tex,"%s%s",path_dir,m[i].texfile); // 相対パスの場合 if ( M[i].alpFile[0]!= (char)0 ) if (strstr(m[i].texfile,":")) strcpy(path_alp, M[i].alpFile); else else // 絶対パスの場合 sprintf(path_alp,"%s%s",path_dir,m[i].alpfile); // 相対パスの場合 M[i].texName = mqosettexturepool(path_tex,path_alp,alpha); M[i].texName = mqosettexturepool(path_tex,null,alpha); mqomakeobjectsex( mqoobj, obj, n_obj, M, n_mat, scale, alpha ); // オブジェクトのデータの開放 for (i=0; i<n_obj; i++) free(obj[i].v); free(obj[i].f); // マテリアルの開放 free(m); return 1; 関数 mqocreatelist 用途 MQOオブジェクトを指定数確保する 引数 num MQOオブジェクトの数 戻値 MQO オブジェクト MQO_OBJECT* mqocreatelist(int num) MQO_OBJECT *obj; // 初期化されてなかったら初期化 if (! l_glmetaseqinitialized ) mqoinit(); // 領域確保と初期化 obj = (MQO_OBJECT *)malloc(sizeof(mqo_object)*num); memset(obj, 0, sizeof(mqo_object)*num);
12 return obj; 関数 mqocreatelistobject 用途 メタセコイアファイル (*.mqo) から MQO オブジェクト配列を作成する 引数 mqoobj MQOオブジェクト i 読み込み先番号 (i 番目にMQOファイルを読み込む ) filename ファイルのパス scale 拡大率 alpha アルファ指定 ( 全体のアルファ値を指定 (~)) 戻値 ステータス負 : 異常 0: 正常 int mqocreatelistobject(mqo_object *mqoobj, int i, char *filename, double scale, unsigned char alpha ) int ret; ret = 0; if ( mqoobj == (MQO_OBJECT *)NULL ) return -1; if (! mqoloadfile(&mqoobj[i], filename, scale, alpha)) ret = -1; return ret; 関数 mqocalllistobject 用途 MQOオブジェクトをOpenGLの画面上に呼び出す 引数 mqoobj MQOオブジェクト配列 num 配列番号 (0~) 戻値 なし void mqocalllistobject(mqo_object mqoobj[],int num) MQO_INNER_OBJECT *obj; MQO_MATERIAL *mat; GLfloat matenv[4]; GLint bindgl_texture_2d = 0; GLboolean isgl_texture_2d = GL_FALSE; GLboolean isgl_blend = GL_FALSE; GLint blendgl_src_alpha = 0; GLint intfrontface; int double char dalpha; *base; o, m, offset; if ( mqoobj == NULL) return; glpushmatrix(); // メタセコは頂点の並びが表面からみて右回り glgetintegerv(gl_front_face,&intfrontface); glfrontface(gl_cw); dalpha = (double)mqoobj[num].alpha/(double)255; for ( o=0; o<mqoobj[num].objnum; o++ ) // 内部オブジェクトループ obj = &mqoobj[num].obj[o]; if (! obj->isvisible ) continue; glshademodel(((obj->isshadingflat))?gl_flat:gl_smooth);
13 for ( m = 0; m < obj->matnum; m++ ) // マテリアルループ mat = &obj->mat[m]; if ( mat->datanum == 0 ) continue; if ( mat->isvalidmaterialinfo ) // マテリアルの情報設定 memcpy(matenv,mat->dif,sizeof(matenv)); matenv[3] *= dalpha; glmaterialfv(gl_front_and_back, GL_DIFFUSE, matenv); memcpy(matenv,mat->amb,sizeof(matenv)); matenv[3] *= dalpha; glmaterialfv(gl_front_and_back, GL_AMBIENT, matenv); memcpy(matenv,mat->spc,sizeof(matenv)); matenv[3] *= dalpha; glmaterialfv(gl_front_and_back, GL_SPECULAR, matenv); memcpy(matenv,mat->emi,sizeof(matenv)); matenv[3] *= dalpha; glmaterialfv(gl_front_and_back, GL_EMISSION, matenv); glmaterialf(gl_front_and_back, GL_SHININESS, mat->power); if ( mat->isusetexture) // テクスチャがある場合 glenableclientstate( GL_VERTEX_ARRAY ); glenableclientstate( GL_NORMAL_ARRAY ); glenableclientstate( GL_TEXTURE_COORD_ARRAY ); isgl_texture_2d = glisenabled(gl_texture_2d); isgl_blend = glisenabled(gl_blend); glgetintegerv(gl_texture_binding_2d,&bindgl_texture_2d); // glgetintegerv(gl_blend_src_alpha,&blendgl_src_alpha); glenable(gl_texture_2d); glenable(gl_blend); glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); glbindtexture(gl_texture_2d,mat->texture_id); 点バッファを結びつける if ( g_isvbosupported ) // 頂点バッファ使用 base = (char *)NULL; // アドレスはNULLが先頭 glbindbufferarb( GL_ARRAY_BUFFER_ARB, mat->vbo_id ); // 頂 else // 頂点配列の時は アドレスをそのまま入れる base = (char *)mat->vertex_t[0].point; // 頂点配列を設定 offset = (int)( (char *)mat->vertex_t[0].point - (char *)mat->vertex_t[0].point ); glvertexpointer( 3, GL_FLOAT, sizeof(vertex_texuse), base + offset ); // テクスチャ座標配列を設定 offset = (int)((char *)mat->vertex_t[0].uv-(char *)mat->vertex_t[0].point); gltexcoordpointer( 2, GL_FLOAT, sizeof(vertex_texuse), base + offset ); // 法線配列を設定 offset = (int)((char *)mat->vertex_t[0].normal-(char *)mat->vertex_t[0].point); glnormalpointer( GL_FLOAT, sizeof(vertex_texuse), base+offset ); // 色設定 glcolor4f(mat->color[0],mat->color[1],mat->color[2],mat->color[3]); // 描画実行 gldrawarrays( GL_TRIANGLES, 0, mat->datanum ); glbindtexture(gl_texture_2d,bindgl_texture_2d); if( isgl_blend == GL_FALSE ) gldisable(gl_blend);
14 if( isgl_texture_2d == GL_FALSE ) gldisable(gl_texture_2d); をデフォルトへ if ( g_isvbosupported ) // 頂点バッファ使用 glbindbufferarb( GL_ARRAY_BUFFER_ARB, 0 ); // 頂点バッファ else gldisableclientstate( GL_VERTEX_ARRAY ); gldisableclientstate( GL_NORMAL_ARRAY ); gldisableclientstate( GL_TEXTURE_COORD_ARRAY ); // テクスチャがない場合 glenableclientstate( GL_VERTEX_ARRAY ); glenableclientstate( GL_NORMAL_ARRAY ); //glenableclientstate( GL_COLOR_ARRAY ); isgl_blend = glisenabled(gl_blend); glenable(gl_blend); glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); if ( g_isvbosupported ) // 頂点バッファ使用 base = (char *)NULL; glbindbufferarb( GL_ARRAY_BUFFER_ARB, mat->vbo_id ); else base = (char *)mat->vertex_p[0].point; // 頂点配列を設定 offset = (int)((char *)mat->vertex_p[0].point-(char *)mat->vertex_p[0].point); glvertexpointer( 3, GL_FLOAT, sizeof(vertex_notex), base+offset ); // 法線配列を設定 offset = (int)((char *)mat->vertex_p[0].normal-(char *)mat->vertex_p[0].point); glnormalpointer( GL_FLOAT, sizeof(vertex_notex), base+offset ); // 色設定 glcolor4f(mat->color[0],mat->color[1],mat->color[2],mat->color[3]); //offset = (int)((char *)mat->vertex_p[0].color-(char *)mat->vertex_p[0].point); //glcolorpointer(4,gl_float,sizeof(vertex_notex),base+offset); // 描画実行 gldrawarrays( GL_TRIANGLES, 0, mat->datanum ); をデフォルトへ if( isgl_blend == GL_FALSE ) gldisable(gl_blend); if ( g_isvbosupported ) // 頂点バッファ使用 glbindbufferarb( GL_ARRAY_BUFFER_ARB, 0 ); // 頂点バッファ //gldisableclientstate( GL_COLOR_ARRAY ); gldisableclientstate( GL_VERTEX_ARRAY ); gldisableclientstate( GL_NORMAL_ARRAY ); // メタセコは頂点の並びが表面からみて右回り ( 元の設定にもどす ) glfrontface(intfrontface); glpopmatrix(); 関数 mqogetdirectory
15 用途 ファイル名を含むパス文字列からディレクトリのパスのみを抽出する 引数 *path_file ファイル名を含むパス文字列 ( 入力 ) *path_dir ファイル名を除いたパス文字列 ( 出力 ) 戻値 なし 仕様 例: "C:/data/file.bmp" "C:/data/" "data/file.mqo" "data/" void mqogetdirectory(const char *path_file, char *path_dir) char *pstr; int len; pstr = MAX( strrchr(path_file,'\\'), strrchr(path_file,'/') ); len = MAX((int)(pStr-path_file)+1,0); strncpy(path_dir,path_file,len); path_dir[len] = (char)0; 関数 mqosnormal 用途 法線ベクトルを求める 引数 A 3 次元座標上の点 A B 3 次元座標上の点 B C 3 次元座標上の点 C *normal ベクトルBAとベクトルBCの法線ベクトル ( 右ねじ方向 ) 戻値 なし 仕様 メタセコイアにおいて面を構成する頂点の番号は, 表示面から見て時計回りに記述してある. つまり, 頂点 A,B,C があったとき, 求めるべき法線は BA と BC の外積によって求められる void mqosnormal(glpoint3f A, glpoint3f B, glpoint3f C, glpoint3f *normal) double norm; glpoint3f vec0,vec1; // ベクトル BA vec0.x = A.x - B.x; vec0.y = A.y - B.y; vec0.z = A.z - B.z; // ベクトル BC vec1.x = C.x - B.x; vec1.y = C.y - B.y; vec1.z = C.z - B.z; // 法線ベクトル normal->x = vec0.y * vec1.z - vec0.z * vec1.y; normal->y = vec0.z * vec1.x - vec0.x * vec1.z; normal->z = vec0.x * vec1.y - vec0.y * vec1.x; // 正規化 norm = normal->x * normal->x + normal->y * normal->y + normal->z * normal->z; norm = sqrt ( norm ); normal->x /= norm; normal->y /= norm; normal->z /= norm;
16 関数 mqoreadmaterial 用途 マテリアル情報の読み込み 引数 fp ファイルポインタ M マテリアル配列 戻値 なし 仕様 mqocreatemodel(), mqocreatesequence() のサブ関数. void mqoreadmaterial(file *fp, MQO_MATDATA M[]) GLfloat dif, amb, emi, spc; glcolor4f c; char buf[size_str]; char *pstrend, *pstr; int len; int i = 0; while (1) fgets(buf,size_str,fp); if (strstr(buf,"")) break; // 行読み込み pstr = strstr(buf,"col("); // 材質名読み飛ばし sscanf( pstr, "col(%f %f %f %f) dif (%f) amb(%f) emi(%f) spc(%f) power(%f)", &c.r, &c.g, &c.b, &c.a, &dif, &amb, &emi, &spc, &M[i].power ); // 頂点カラー M[i].col = c; // 拡散光 M[i].dif[0] = dif * c.r; M[i].dif[1] = dif * c.g; M[i].dif[2] = dif * c.b; M[i].dif[3] = c.a; // 周囲光 M[i].amb[0] = amb * c.r; M[i].amb[1] = amb * c.g; M[i].amb[2] = amb * c.b; M[i].amb[3] = c.a; // 自己照明 M[i].emi[0] = emi * c.r; M[i].emi[1] = emi * c.g; M[i].emi[2] = emi * c.b; M[i].emi[3] = c.a; // 反射光 M[i].spc[0] = spc * c.r; M[i].spc[1] = spc * c.g; M[i].spc[2] = spc * c.b; M[i].spc[3] = c.a; // tex: 模様マッピング名 if ( (pstr = strstr(buf,"tex("))!= NULL ) M[i].useTex = TRUE; pstrend = strstr(pstr,")")-1; len = pstrend - (pstr+5); strncpy(m[i].texfile,pstr+5,len); M[i].texFile[len] = (char)0; if ( (pstr = strstr(buf,"aplane("))!= NULL )
17 else pstrend = strstr(pstr,")")-1; len = pstrend - (pstr+8); strncpy(m[i].alpfile,pstr+8,len); M[i].alpFile[len] = (char)0; M[i].alpFile[0] = (char)0; else M[i].useTex = FALSE; M[i].texFile[0] = (char)0; M[i].alpFile[0] = (char)0; i++; 関数 mqoreadvertex 用途 頂点情報の読み込み 引数 fp 現在オープンしているメタセコイアファイルのファイルポインタ V 頂点を格納する配列 戻値 なし 仕様 mqoreadobject() のサブ関数 void mqoreadvertex(file *fp, glpoint3f V[]) char buf[size_str]; int i=0; while (1) fgets(buf,size_str,fp); if (strstr(buf,"")) break; sscanf(buf,"%f %f %f",&v[i].x,&v[i].y,&v[i].z); i++; 関数 mqoreadbvertex 用途 バイナリ形式の頂点情報を読み込む 引数 fp 現在オープンしているメタセコイアファイルのファイルポインタ V 頂点を格納する配列 戻値 頂点数 仕様 mqoreadobject() のサブ関数 int mqoreadbvertex(file *fp, glpoint3f V[]) int n_vertex,i; float *wf; int size; char cw[256]; char *pstr; fgets(cw,sizeof(cw),fp); if ( (pstr = strstr(cw,"vector"))!= NULL )
18 sscanf(pstr,"vector %d [%d]",&n_vertex,&size);// 頂点数 データサイズを読み込む else return -1; //MQOファイルのバイナリ頂点データはintel 形式 ( リトルエディアン ) wf = (float *)malloc(size); fread(wf,size,1,fp); for ( i = 0; i < n_vertex; i++ ) V[i].x = wf[i*3+0]; V[i].y = wf[i*3+1]; V[i].z = wf[i*3+2]; #if DEF_IS_LITTLE_ENDIAN #else endianconverter((void *)&V[i].x,sizeof(V[i].x)); endianconverter(&v[i].y,sizeof(v[i].y)); endianconverter(&v[i].z,sizeof(v[i].z)); free(wf); // "" まで読み飛ばし char buf[size_str]; while (1) fgets(buf,size_str,fp); if (strstr(buf,"")) break; return n_vertex; 関数 mqoreadface 用途 面情報の読み込み 引数 fp ファイルポインタ F 面配列 戻値 なし 仕様 mqoreadobject() のサブ関数 void mqoreadface(file *fp, MQO_FACE F[]) char buf[size_str]; char *pstr; int i=0; while (1) fgets(buf,size_str,fp); if (strstr(buf,"")) break; // 面を構成する頂点数 sscanf(buf,"%d",&f[i].n); // 頂点 (V) の読み込み if ( (pstr = strstr(buf,"v("))!= NULL ) switch (F[i].n) case 3: // メタセコは頂点の並びが表面からみて右回り // 読み込み時に並べ替える方法もある けど 表面の設定を //glfrontface で変えるほうがスマート? sscanf(pstr,"v(%d %d %d)",&f[i].v[0],&f[i].v[1],&f[i].v[2]); //sscanf(pstr,"v(%d %d %d)",&f[i].v[2],&f[i].v[1],&f[i].v[0]);
19 case 4: default: break; sscanf(pstr,"v(%d %d %d %d)",&f[i].v[0],&f[i].v[1],&f[i].v[2],&f[i].v[3]); //sscanf(pstr,"v(%d %d %d %d)",&f[i].v[3],&f[i].v[2],&f[i].v[1],&f[i].v[0]); break; break; // マテリアル (M) の読み込み F[i].m = 0; if ( (pstr = strstr(buf,"m("))!= NULL ) sscanf(pstr,"m(%d)",&f[i].m); else // マテリアルが設定されていない面 F[i].m = -1; // UV マップ (UV) の読み込み if ( (pstr = strstr(buf,"uv("))!= NULL ) switch (F[i].n) case 3: // 頂点数 sscanf(pstr,"uv(%f %f %f %f %f %f)", &F[i].uv[0].x, &F[i].uv[0].y, &F[i].uv[1].x, &F[i].uv[1].y, &F[i].uv[2].x, &F[i].uv[2].y ); break; case 4: default: // 頂点数 sscanf(pstr,"uv(%f %f %f %f %f %f %f %f)", &F[i].uv[0].x, &F[i].uv[0].y, &F[i].uv[1].x, &F[i].uv[1].y, &F[i].uv[2].x, &F[i].uv[2].y, &F[i].uv[3].x, &F[i].uv[3].y ); break; break; i++; 関数 mqoreadobject 用途 オブジェクト情報の読み込み 引数 fp ファイルポインタ obj オブジェクト情報 戻値 なし 仕様 この関数で 1 個のオブジェクト情報が読み込まれる. void mqoreadobject(file *fp, MQO_OBJDATA *obj) char buf[size_str]; while (1) fgets(buf,size_str,fp); if (strstr(buf,"")) break;
20 // visible if (strstr(buf,"visible ")) sscanf(buf," visible %d", &obj->visible); // shading if (strstr(buf,"shading ")) sscanf(buf," shading %d", &obj->shading); // facet if (strstr(buf,"facet ")) sscanf(buf," facet %f", &obj->facet); // vertex if (strstr(buf,"vertex ")) sscanf(buf," vertex %d", &obj->n_vertex); obj->v = (glpoint3f*) calloc( obj->n_vertex, sizeof(glpoint3f) ); mqoreadvertex(fp, obj->v); // BVertex if (strstr(buf,"bvertex")) sscanf(buf," BVertex %d", &obj->n_vertex); obj->v = (glpoint3f*) calloc( obj->n_vertex, sizeof(glpoint3f) ); mqoreadbvertex(fp,obj->v); // face if (strstr(buf,"face ")) sscanf(buf," face %d", &obj->n_face); obj->f = (MQO_FACE*) calloc( obj->n_face, sizeof(mqo_face) ); mqoreadface(fp, obj->f); 関数 mqomakearray 用途 頂点配列の作成 引数 mat マテリアル ( この中に頂点データを含む ) matpos 材質番号 F 面 fnum 面数 V 頂点 N 法線 facet スムージング角 mcol 色 scale スケール alpha アルファ 戻値 なし 仕様 頂点配列はすべて三角にするので 四角は三角 x2 に分割 void mqomakearray( MQO_MATERIAL *mat, int matpos, MQO_FACE F[], int fnum,glpoint3f V[], glpoint3f N[], double facet, glcolor4f *mcol, double scale, unsigned char alpha ) int f; int i;
21 int dpos; double s; glpoint3f normal; // 法線ベクトル dpos = 0; mat->color[0] = mcol->r; mat->color[1] = mcol->g; mat->color[2] = mcol->b; mat->color[3] = mcol->a; if ( mat->isusetexture ) for ( f = 0; f < fnum; f++ ) if ( F[f].m!= matpos ) continue; if ( F[f].n == 3 ) mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&normal); // 法線ベクトルを計算 for ( i = 0; i < 3; i++ ) mat->vertex_t[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_t[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_t[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_t[dpos].uv[0] = F[f].uv[i].x; mat->vertex_t[dpos].uv[1] = F[f].uv[i].y; s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y + normal.z*n[f[f].v[i]].z); if ( facet < s ) // スムージング角 <( 頂点法線と面法線の角度 ) のときは面法線を頂点法線とする mat->vertex_t[dpos].normal[0] = normal.x; mat->vertex_t[dpos].normal[1] = normal.y; mat->vertex_t[dpos].normal[2] = normal.z; normal.z*n[f[f].v[i]].z); else dpos++; //4 頂点 ( 四角 ) は3 頂点 ( 三角 )x2に分割 if ( F[f].n == 4 ) mat->vertex_t[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_t[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_t[dpos].normal[2] = N[F[f].v[i]].z; mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&normal); // 法線ベクトルを計算 for ( i = 0; i < 4; i++ ) if ( i == 3 ) continue; mat->vertex_t[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_t[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_t[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_t[dpos].uv[0] = F[f].uv[i].x; mat->vertex_t[dpos].uv[1] = F[f].uv[i].y; s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y + if ( facet < s ) mat->vertex_t[dpos].normal[0] = normal.x; mat->vertex_t[dpos].normal[1] = normal.y; mat->vertex_t[dpos].normal[2] = normal.z; else mat->vertex_t[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_t[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_t[dpos].normal[2] = N[F[f].v[i]].z; dpos++; mqosnormal(v[f[f].v[0]],v[f[f].v[2]],v[f[f].v[3]],&normal); for ( i = 0; i < 4; i++ ) if ( i == 1 ) continue; mat->vertex_t[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_t[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_t[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_t[dpos].uv[0] = F[f].uv[i].x; mat->vertex_t[dpos].uv[1] = F[f].uv[i].y; // 法線ベクトルを計算
22 s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y + normal.z*n[f[f].v[i]].z); if ( facet < s ) mat->vertex_t[dpos].normal[0] = normal.x; mat->vertex_t[dpos].normal[1] = normal.y; mat->vertex_t[dpos].normal[2] = normal.z; else mat->vertex_t[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_t[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_t[dpos].normal[2] = N[F[f].v[i]].z; dpos++; else if ( alpha!= 255 ) mat->color[3] = (double)alpha/(double)255; for ( f = 0; f < fnum; f++ ) if ( F[f].m!= matpos ) continue; if ( F[f].n == 3 ) mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&normal); // 法線ベクトルを計算 for ( i = 0; i < 3; i++ ) mat->vertex_p[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_p[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_p[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y +normal.z*n[f[f].v[i]].z); if ( facet < s ) mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; else mat->vertex_p[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_p[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_p[dpos].normal[2] = N[F[f].v[i]].z; dpos++; //4 頂点 ( 四角 ) は3 頂点 ( 三角 )x2に分割 if ( F[f].n == 4 ) mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&normal); // 法線ベクトルを計算 for ( i = 0; i < 4; i++ ) if ( i == 3 ) continue; mat->vertex_p[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_p[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_p[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y + normal.z*n[f[f].v[i]].z); if ( facet < s ) mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; else mat->vertex_p[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_p[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_p[dpos].normal[2] = N[F[f].v[i]].z;
23 normal.z*n[f[f].v[i]].z); dpos++; mqosnormal(v[f[f].v[0]],v[f[f].v[2]],v[f[f].v[3]],&normal); // 法線ベクトルを計算 for ( i = 0; i < 4; i++ ) if ( i == 1 ) continue; mat->vertex_p[dpos].point[0] = V[F[f].v[i]].x*scale; mat->vertex_p[dpos].point[1] = V[F[f].v[i]].y*scale; mat->vertex_p[dpos].point[2] = V[F[f].v[i]].z*scale; mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; s = acos(normal.x*n[f[f].v[i]].x + normal.y*n[f[f].v[i]].y + if ( facet < s ) mat->vertex_p[dpos].normal[0] = normal.x; mat->vertex_p[dpos].normal[1] = normal.y; mat->vertex_p[dpos].normal[2] = normal.z; else mat->vertex_p[dpos].normal[0] = N[F[f].v[i]].x; mat->vertex_p[dpos].normal[1] = N[F[f].v[i]].y; mat->vertex_p[dpos].normal[2] = N[F[f].v[i]].z; dpos++; 関数 mqovertexnormal 用途 頂点法線の計算 引数 obj オブジェクト情報 戻値 法線配列 仕様 4 頂点の面は三角形に分割して計算戻り値は必ず呼び出し元で解放 (free) すること! glpoint3f * mqovertexnormal(mqo_objdata *obj) int f; int v; int i; double len; glpoint3f fnormal; // 面法線ベクトル MQO_FACE *F; glpoint3f *V; glpoint3f *ret; F = obj->f; V = obj->v; ret = (glpoint3f *)calloc(obj->n_vertex,sizeof(glpoint3f)); // 面の法線を頂点に足し込み for ( f = 0; f < obj->n_face; f++ ) if ( obj->f[f].n == 3 ) mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&fnormal); for ( i = 0; i < 3; i++ ) ret[f[f].v[i]].x += fnormal.x; ret[f[f].v[i]].y += fnormal.y; ret[f[f].v[i]].z += fnormal.z; if ( obj->f[f].n == 4 ) mqosnormal(v[f[f].v[0]],v[f[f].v[1]],v[f[f].v[2]],&fnormal);
24 for ( i = 0; i < 4; i++ ) if ( i == 3 ) continue; ret[f[f].v[i]].x += fnormal.x; ret[f[f].v[i]].y += fnormal.y; ret[f[f].v[i]].z += fnormal.z; mqosnormal(v[f[f].v[0]],v[f[f].v[2]],v[f[f].v[3]],&fnormal); for ( i = 0; i < 4; i++ ) if ( i == 1 ) continue; ret[f[f].v[i]].x += fnormal.x; ret[f[f].v[i]].y += fnormal.y; ret[f[f].v[i]].z += fnormal.z; // 正規化 for ( v = 0; v < obj->n_vertex; v++ ) if ( ret[v].x == 0 && ret[v].y == 0 && ret[v].z == 0 ) // 面に使われてない点 continue; len = sqrt(ret[v].x*ret[v].x + ret[v].y*ret[v].y + ret[v].z*ret[v].z); if ( len!= 0 ) ret[v].x = ret[v].x/len; ret[v].y = ret[v].y/len; ret[v].z = ret[v].z/len; return ret; 関数 mqomakepolygon 用途 ポリゴンの生成 引数 readobj 読み込んだオブジェクト情報 mqoobj MQOオブジェクト N[] 法線配列 M[] マテリアル配列 n_mat マテリアル数 scale スケール alpha アルファ 戻値 なし void mqomakepolygon(mqo_objdata *readobj, MQO_OBJECT *mqoobj, glpoint3f N[], MQO_MATDATA M[], int n_mat, double scale, unsigned char alpha) MQO_INNER_OBJECT MQO_MATERIAL glcolor4f glcolor4f int int MQO_FACE glpoint3f double *setobj; *material; defcol; *pcol; f, m, *mat_vnum; fnum; *F; *V; facet; setobj = &mqoobj->obj[mqoobj->objnum]; strcpy(setobj->objname,readobj->objname); setobj->isvisible = readobj->visible; setobj->isshadingflat = (readobj->shading == 0); F = readobj->f;
25 fnum = readobj->n_face; V = readobj->v; facet = readobj->facet; // face の中でのマテリアル毎の頂点の数 // M=NULL のとき F[].m = 0 が入ってくる if ( M == NULL ) n_mat = 1; mat_vnum = (int *)malloc(sizeof(int)*n_mat); memset(mat_vnum,0,sizeof(int)*n_mat); for ( f = 0; f < fnum; f++ ) if( F[f].m < 0 ) continue; // マテリアルが設定されていない面 if ( F[f].n == 3 ) mat_vnum[f[f].m] += 3; if ( F[f].n == 4 ) //4 頂点 ( 四角 ) は 3 頂点 ( 三角 )x2 に分割 // // // // 4 頂点の平面データは // 3 頂点の平面データ x2 個 mat_vnum[f[f].m] += 3*2; if ( setobj->matnum < F[f].m+1 ) setobj->matnum = F[f].m+1; // マテリアル別に頂点配列を作成する setobj->mat = (MQO_MATERIAL *)malloc(sizeof(mqo_material)*setobj->matnum); memset(setobj->mat,0,sizeof(mqo_material)*setobj->matnum); for ( m = 0; m < setobj->matnum; m++ ) material = &setobj->mat[m]; material->datanum = mat_vnum[m]; material->isvalidmaterialinfo = (M!= NULL); if ( mat_vnum[m] <= 0 ) continue; if ( material->isvalidmaterialinfo ) memcpy(material->dif,m[m].dif,sizeof(material->dif)); memcpy(material->amb,m[m].amb,sizeof(material->amb)); memcpy(material->spc,m[m].spc,sizeof(material->spc)); memcpy(material->emi,m[m].emi,sizeof(material->emi)); material->power = M[m].power; material->isusetexture = M[m].useTex; pcol = &M[m].col; else defcol.r = 1.0; defcol.g = 1.0; defcol.b = 1.0; defcol.a = 1.0; material->isusetexture = 0; pcol = &defcol; if ( material->isusetexture ) material->vertex_t = (VERTEX_TEXUSE *)calloc(material->datanum,sizeof(vertex_texuse)); material->texture_id = M[m].texName; else material->vertex_p = (VERTEX_NOTEX *)calloc(material->datanum,sizeof(vertex_notex)); mqomakearray(material,m,f,fnum,v,n,facet,pcol,scale,alpha); if (g_isvbosupported) if ( material->isusetexture ) glgenbuffersarb( 1, &material->vbo_id ); glbindbufferarb( GL_ARRAY_BUFFER_ARB, material->vbo_id ); glbufferdataarb( GL_ARRAY_BUFFER_ARB, material-
26 >datanum*sizeof(vertex_texuse), material->vertex_t, GL_STATIC_DRAW_ARB ); else glgenbuffersarb( 1, &material->vbo_id ); glbindbufferarb( GL_ARRAY_BUFFER_ARB, material->vbo_id ); glbufferdataarb( GL_ARRAY_BUFFER_ARB, material- >datanum*sizeof(vertex_notex), material->vertex_p, GL_STATIC_DRAW_ARB ); mqoobj->objnum++; if ( MAX_OBJECT <= mqoobj->objnum ) printf("mqo ファイル読み込み : 最大オブジェクト数を超えました [%d]\n",mqoobj->objnum); mqoobj->objnum = MAX_OBJECT-1; free(mat_vnum); 関数 mqomakeobjectsex 用途 オブジェクトのデータからポリゴンモデルを作成する 引数 mqoobj MQOオブジェクト obj オブジェクト配列 n_obj オブジェクトの個数 M マテリアル配列 n_mat マテリアルの個数 scale 拡大率 alpha アルファ 戻値 なし void mqomakeobjectsex( MQO_OBJECT *mqoobj, MQO_OBJDATA obj[], int n_obj, MQO_MATDATA M[],int n_mat, double scale,unsigned char alpha) int i; glpoint3f *N; for (i=0; i<n_obj; i++) N = mqovertexnormal(&obj[i]); mqomakepolygon( &obj[i], mqoobj, N, M,n_mat, scale, alpha); free(n); 関数 mqocreatemodel 用途 MQOファイルからMQOモデルを作成する 引数 filename MQOファイル scale 拡大率 (.0でそのまま) 戻値 MQO_MODEL(MQO モデル ) MQO_MODEL mqocreatemodel(char *filename, double scale)
27 MQO_MODEL ret; ret = mqocreatelist(1); if ( mqocreatelistobject(ret,1-1,filename,scale,(unsigned char)255) < 0 ) mqodeleteobject(ret,1); ret = NULL; return ret; 関数 mqocreatesequenceex 用途 連番のMQOファイルからMQOシーケンスを作成する 引数 format ファイル名の書式 n_file ファイル数 scale 拡大率 (.0でそのまま) fade_inout 0: そのまま正 : フェードイン負 : フェードアウト絶対値は効果をかけるフレーム数 alpha アルファ 戻値 MQO_SEQUENCE(MQO シーケンス ) 備考 連番はから開始 MQO_SEQUENCE mqocreatesequenceex(const char *format, int n_file, double scale, int fade_inout, unsigned char alpha) MQO_SEQUENCE retseq; int iret; int seq; char filename[size_str]; short setalpha; short calalpha; int frames; retseq.n_frame = 0; if ( format == NULL ) return retseq; calalpha = alpha; frames = abs(fade_inout); frames = MAX(frames,n_file); setalpha = (fade_inout<=0)?alpha:0; retseq.model = mqocreatelist(n_file); for ( seq = 0; seq < frames; seq++ ) if ( seq < n_file ) sprintf(filename,format,seq); if ( (fade_inout!= 0) && ((frames-1) == seq) ) setalpha = (fade_inout<0)?0:calalpha; iret = mqocreatelistobject(retseq.model,seq,filename,scale,(unsigned char)setalpha); if ( iret == - 1 ) seq--; mqoclearobject(retseq.model,seq,n_file-seq); break; if ( fade_inout!= 0 ) if ( fade_inout<0 ) if ( (n_file-seq) <= (-1*fade_inout) ) setalpha -= (calalpha/(-1*fade_inout)); if ( setalpha < 0 ) setalpha = 0; else setalpha += (calalpha/fade_inout);
28 retseq.n_frame = seq; return retseq; if ( calalpha < setalpha ) setalpha = calalpha; 関数 mqocreatesequence 用途 連番のMQOファイルからMQOシーケンスを作成する 引数 format ファイル名のフォーマット n_file ファイル数 scale 拡大率 (.0でそのまま) 戻値 MQO_SEQUENCE(MQO シーケンス ) 備考 連番はから開始 MQO_SEQUENCE mqocreatesequence(const char *format, int n_file, double scale) return mqocreatesequenceex(format, n_file, scale, 0, (unsigned char)255); 関数 mqocallmodel 用途 MQOモデルをOpenGLの画面上に呼び出す 引数 model MQOモデル 戻値 なし void mqocallmodel(mqo_model model) mqocalllistobject(model, 0); 関数 mqocallsequence 用途 MQOシーケンスをOpenGLの画面に呼び出す 引数 seq MQOシーケンス i フレーム番号 戻値 なし 仕様 MQO シーケンスの中から指定したフレーム番号のモデルを呼び出す void mqocallsequence(mqo_sequence seq, int i) if ( i>=0 && i<seq.n_frame ) mqocalllistobject(seq.model,i); 関数 mqoclearobject 用途 MQOオブジェクトのクリア 引数 object MQOオブジェクト配列
29 from num 削除開始番号 (~) 削除する個数 戻値 なし void mqoclearobject( MQO_OBJECT object[], int from, int num ) int loop, o, m; MQO_INNER_OBJECT *obj; MQO_MATERIAL *mat; if ( object == NULL ) return; for ( loop = from; loop < from + num; loop++ ) for ( o = 0; o < (object+from)->objnum; o++ ) obj = &(object+loop)->obj[o]; for ( m = 0; m < obj->matnum; m++ ) mat = &obj->mat[m]; if ( mat->datanum <= 0 ) continue; if ( g_isvbosupported ) // 頂点バッファの削除 gldeletebuffersarb( 1, &mat->vbo_id ); // 頂点配列の削除 if ( mat->isusetexture ) if ( mat->vertex_t!= NULL ) free(mat->vertex_t); mat->vertex_t = NULL; else if ( mat->vertex_p!= NULL ) free(mat->vertex_p); mat->vertex_p = NULL; if ( obj->mat!= NULL ) free(obj->mat); obj->mat = NULL; obj->matnum = 0; 関数 mqodeleteobject 用途 MQOオブジェクトを削除する 引数 object MQOオブジェクト配列 num 削除する個数 戻値 なし void mqodeleteobject(mqo_object object[], int num) mqoclearobject(object,0,num); free(object);
30 関数 mqodeletemodel 用途 MQOモデルを削除する 引数 model MQOモデル 戻値 なし 備考 削除処理を行った変数を再利用する可能性がある場合はこの関数の実行後に NULL を代入しておくこと void mqodeletemodel(mqo_model model) mqodeleteobject(model,1); 関数 mqodeletesequence 用途 MQOシーケンスを削除する 引数 seq MQOシーケンス 備考 削除処理を行った変数を再利用する可能性がある場合はこの関数の実行後に NULL を代入しておくこと void mqodeletesequence(mqo_sequence seq) mqodeleteobject( seq.model, seq.n_frame );
(4) モデルの消去 mqodeletemodel( model ); (5) 終了処理 ( プログラム終了時にやってください ) mqocleanup(); 3. 使い方 (2) 連番ファイルを読み込んで表示する場合 (1) 初期化 (ARToolKit の場合,argInit() の後に使用 )
GLMetaseq.h の中身 0810960080 渡部修平 メタセコイアで作成した 3D モデルを OpenGL で表示させるためには, 工学ナビ (http://kougaku-navi.net/artoolkit.html) が公開している C/C++ 用のライブラリ GLMetaseq があります 作成しているプログラムのプロジェクトに GLMetaseq.h と GLMetaseq.c
ファイル入出力
C プログラミング Ⅱ の基礎 とは ファイルへデータを書き込んだり ( 出力 ), ファイルからデータを読み込んだり ( 入力 ) する C 言語では キーボードからの入力 画面への出力と同じようなコードで 処理を実現できる プログラム 入力 出力 ファイル 出力 入力 2 入出力の基本 ストリーム プログラム上で様々な装置への入出力を行う機構様々な入出力装置を統一的な方法で扱うことができる ハードディスクなどではファイルデータによって入出力が行われる
Microsoft PowerPoint - CproNt02.ppt [互換モード]
第 2 章 C プログラムの書き方 CPro:02-01 概要 C プログラムの構成要素は関数 ( プログラム = 関数の集まり ) 関数は, ヘッダと本体からなる 使用する関数は, プログラムの先頭 ( 厳密には, 使用場所より前 ) で型宣言 ( プロトタイプ宣言 ) する 関数は仮引数を用いることができる ( なくてもよい ) 関数には戻り値がある ( なくてもよい void 型 ) コメント
Microsoft Word - Cプログラミング演習(10)
第 10 回 (6/25) 3. ファイルとその応用 (3) ファイルの更新 シーケンシャルファイルの更新 シーケンシャルファイルでは, 各レコードが可変長で連続して格納されており, その中の特定のレコードを変更することができない そこで一般的には, マスタファイルからデータを取り出し, 更新処理を行ったあとに新マスタファイルに書き込む 注 ) マスタファイル : 主ファイル, 基本ファイルと呼ばれるファイルで内容は比較的固定的であり,
02: 変数と標準入出力
C プログラミング入門 基幹 2 ( 月 4) 11: 動的メモリ確保 Linux にログインし 以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/cpr1/ 2014-06-22 1 まとめ : ポインタを使った処理 内容 説明 呼び出し元の変数を書き換える第 9 回 文字列を渡す 配列を渡す 第 10 回 ファイルポインタ
Taro-ファイル処理(公開版).jtd
ファイル処理 0. 目次 1. はじめに 2. ファイル内容の表示 3. ファイル内容の複写 3. 1 文字単位 3. 2 行単位 4. 書式付き入出力 5. 文字配列への入出力 6. 課題 6. 1 課題 1 ( ファイル圧縮 復元 ) - 1 - 1. はじめに ファイル処理プログラムの形は次のようになる #include main() { FILE *fp1,*fp2; ファイルポインタの宣言
コンピュータグラフィックスS 演習資料
コンピュータグラフィックス S 演習資料 第 4 回シェーディング マッピング 九州工業大学情報工学部システム創成情報工学科講義担当 : 尾下真樹 1. 演習準備 今回の演習も 前回までの演習で作成したプログラムに続けて変更を行う まずは シェーディングの演習のため 描画処理で 回転する一つの四角すいを描画するように変更する 画面をクリア ( ピクセルデータと Z バッファの両方をクリア ) glclear(
02: 変数と標準入出力
C プログラミング入門 総機 1 ( 月 1) 11: 動的メモリ確保 Linux にログインし 以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/cpr1/ 2015-06-22 1 まとめ : ポインタを使った処理 内容 説明 呼び出し元の変数を書き換える第 9 回 文字列を渡す 配列を渡す 第 10 回 ファイルポインタ
memo
数理情報工学演習第一 C プログラミング演習 ( 第 5 回 ) 2015/05/11 DEPARTMENT OF MATHEMATICAL INFORMATICS 1 今日の内容 : プロトタイプ宣言 ヘッダーファイル, プログラムの分割 課題 : 疎行列 2 プロトタイプ宣言 3 C 言語では, 関数や変数は使用する前 ( ソースの上のほう ) に定義されている必要がある. double sub(int
プログラミング基礎
C プログラミング Ⅱ 演習 2-1(a) BMI による判定 文字列, 身長 height(double 型 ), 体重 weight (double 型 ) をメンバとする構造体 Data を定義し, それぞれのメンバの値をキーボードから入力した後, BMI を計算するプログラムを作成しなさい BMI の計算は関数化すること ( ) [ ] [ ] [ ] BMI = 体重 kg 身長 m 身長
02: 変数と標準入出力
C プログラミング入門 基幹 7 ( 水 5) 1 10: ファイル入出力 Linux にログインし 以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/teachers/w48369 2/CPR1/ 2016-06-15 今日の内容 2 標準ライブラリ関数によりファイルの出力を行う画像ファイルの生成を例題として 配列の作成を復習する 文字列の扱いを復習する
char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く
変数 入出力 演算子ここまでに C 言語プログラミングの様子を知ってもらうため printf 文 変数 scanf 文 if 文を使った簡単なプログラムを紹介した 今回は変数の詳細について習い それに併せて使い方が増える入出力処理の方法を習う また 演算子についての復習と供に新しい演算子を紹介する 変数の宣言プログラムでデータを取り扱う場合には対象となるデータを保存する必要がでてくる このデータを保存する場所のことを
PowerPoint Presentation
ファイルの入出力 芝浦工業大学情報工学科 青木義満 今回の講義内容 ファイル入出力 ファイルからのデータ読込み ファイルと配列 2 1 ファイルへのデータ書き込み ( 復習 ) ソースファイル名 :fileio1.c データをファイルに書き込み #include int main(void) { ファイルポインタ宣言 int student_id = 100; char name[
PowerPoint Presentation
工学部 6 7 8 9 10 組 ( 奇数学籍番号 ) 担当 : 長谷川英之 情報処理演習 第 7 回 2010 年 11 月 18 日 1 今回のテーマ 1: ポインタ 変数に値を代入 = 記憶プログラムの記憶領域として使用されるものがメモリ ( パソコンの仕様書における 512 MB RAM などの記述はこのメモリの量 ) RAM は多数のコンデンサの集合体 : 電荷がたまっている (1)/ いない
画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう
第 14 回 応用 情報処理演習 ( テキスト : 第 10 章 ) 画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう 特定色の画素の検出 ( テキスト 134 ページ ) 画像データが保存されているファイルを読み込んで, 特定色の画素の位置を検出するプログラムを作成しなさい 元画像生成画像 ( 結果の画像 )
Microsoft Word - no15.docx
7. ファイルいままでは プログラムを実行したとき その結果を画面で確認していました 簡単なものならそれでもいいのですか 複雑な結果は画面で見るだけでなく ファイルに保存できればよいでしょう ここでは このファイルについて説明します 使う関数のプロトタイプは次のとおりです FILE *fopen(const char *filename, const char *mode); ファイルを読み書きできるようにする
PowerPoint プレゼンテーション
複雑系科学演習 1 コンピュータグラフィックス 担当畔上秀幸情報科学研究科複雑系科学専攻 今日の話題 STL ファイルを読み込んで表示する. STL データをどのようなデータ構造に格納しているか? 配列を用いる方法 構造体を用いる方法 読み込んだデータをどのように使うか? lesson8_1.c の説明 solid NOTITLE facet normal 00e+00 000e+00 1.000000e+00
PowerPoint プレゼンテーション
講座準備 講座資料は次の URL から DL 可能 https://goo.gl/jnrfth 1 ポインタ講座 2017/01/06,09 fumi 2 はじめに ポインタはC 言語において理解が難しいとされる そのポインタを理解することを目的とする 講座は1 日で行うので 詳しいことは調べること 3 はじめに みなさん復習はしましたか? 4 & 演算子 & 演算子を使うと 変数のアドレスが得られる
バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科
バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科 ポインタ変数の扱い方 1 ポインタ変数の宣言 int *p; double *q; 2 ポインタ変数へのアドレスの代入 int *p; と宣言した時,p がポインタ変数 int x; と普通に宣言した変数に対して, p = &x; は x のアドレスのポインタ変数 p への代入 ポインタ変数の扱い方 3 間接参照 (
スライド 1
Graphics with Processing 2007-11 シェーディングとテクスチャマッピング http://vilab.org 塩澤秀和 1 11.1 シェーディング シェーディング シェーディングとは Shading= 陰影づけ 光の反射 材質のモデル ( 前回 ) ポリゴンの陰影計算モデル = シェーディングモデル シェーディングモデル フラットシェーディング ポリゴンを単一色で描画
Microsoft PowerPoint - prog04.ppt
プログラミング言語 2 第 04 回 (2007 年 05 月 14 日 ) 今日の配布物 片面の用紙 1 枚 今日の課題が書かれています 本日の出欠を兼ねています 1 今日やること http://www.tnlab.ice.uec.ac.jp/~s-okubo/class/language/ にアクセスすると 教材があります 2007 年 05 月 14 日分と書いてある部分が 本日の教材です 本日の内容
PowerPoint プレゼンテーション
プログラマー勉強会 1 回 basic.h 補足 [ 修飾子 ] const 付けた変数は初期化以外で値を設定することができなくなる 定数宣言に使う unsigned 付けた変数は符号がなくなり 正の値しか設定できない [ 条件コンパイル ] #ifdef M ここ以前に M がマクロとして定義されていれば ここ以下をコンパイルする #ifndef M ここ以前に M というマクロが定義されていなければ
AquesTalk Win Manual
AquesTalk Win マニュアル 株式会社アクエスト http://www.a-quest.com/ 1. 概要 本文書は 規則音声合成ライブラリ AquesTalk をアプリケーションに組み込んで使用するためのプログラミングに関して 方法および注意点を示したものです AquesTalk には 2 種類のライブラリがあります 音声データをメモリ上に生成するものと サウンドデバイスに出力する 2
Microsoft PowerPoint - 14th.ppt [互換モード]
工学部 6 7 8 9 10 組 ( 奇数学籍番号 ) 担当 : 長谷川英之 情報処理演習 第 14 回 2011 年 1 月 20 日 1 今日のテーマ ファイル入出力 ですが, キーボード入力などもおさらいします 2 標準入力 キーボードで入力 : 標準入力という例 )scanf( %d,&i) 前回までの講義でファイルからデータを読み込む場合に使用した関数 : fscanf 例 )fscanf(fin,
情報処理演習 B8クラス
予定スケジュール ( 全 15 回 ) 1 1. 終了 プログラミング言語の基礎 2. 終了 演算と型 3. 終了 プログラムの流れの分岐 (if 文,switch 文など ) 4. 終了 プログラムの流れの繰返し (do, while, for 文など ) 5. 終了 中間レポート1 6. 終了 配列 7. 終了 関数 8. 終了 文字列 ( 文字列の配列, 文字列の操作 ) 9. 終了 ポインタ
AquesTalk プログラミングガイド
AquesTalk プログラミングガイド ( 株 ) アクエスト 1. 概要 本文書は 規則音声合成ライブラリ AquesTalk をアプリケーションに組み込んで使用するためのプログラミングに関して 方法および注意点を示したものです AquesTalk には 2 種類のライブラリがあります 音声データをメモリ上に生成するものと サウンドデバイスに出力する 2 種類があります 使用するアプリケーションに応じて選択してください
PowerPoint Presentation
8-1 8. テクスチャマッピング 8.1. テクスチャマッピングの原理 狭義には, 図のように, 与えられた画像を物体に貼り付ける方法. マッピングには投影法, 極座標変換, パラメータマッピングなどがある (1 年 コンピュータ グラフィックス ). 広義にはバンプマッピングなども含まれる. t y s z x 8-2 8.2. テクスチャマッピングの設定方法 全体の流れ 1) 原図ビットマップデータを内部形式に変換
AquesTalk for WinCE プログラミングガイド
AquesTalk for WinCE プログラミングガイド ( 株 ) アクエスト 1. 概要 本文書は 規則音声合成ライブラリ AquesTalk for WinCE ( 以下 AquesTalk) をアプリケーションに組み込んで使用するためのプログラミングに関して 方法および注意点を示したものです AquesTalk には 2 種類のライブラリがあります 音声データをメモリ上に生成するものと
Microsoft PowerPoint - 5Chap15.ppt
第 15 章文字列処理 今日のポイント 15.1 文字列処理の基本 strcpy strcat strlen strchr などの使い方をマスターする strcpy はなんて読むの? 普通はストリングコピー C のキーワードの読み方に悩んだら下記サイトを参考 ( 前回紹介とは別サイト ) http://www.okakogi.go.jp/people/miwa/program/c_lang/c_furoku.html
Microsoft PowerPoint - info_eng3_05ppt.pptx
インタラクティブシステム構築法 第 5 回 OpenGL と GLUT の使い方 (3) 埼玉大学情報システム工学科小林貴訓 シェーディング 光源の設定を有効にする glenable(gl_lighting); // 光源の設定を有効にする glenable(gl_light0); //0 番目の光源を有効にする (8 個まで設定可能 ) 光源の位置 GLfloat light0pos[] = {
Microsoft PowerPoint - 09.pptx
情報処理 Ⅱ 第 9 回 2014 年 12 月 22 日 ( 月 ) 関数とは なぜ関数 関数の分類 自作関数 : 自分で定義する. ユーザ関数 ユーザ定義関数 などともいう. 本日のテーマ ライブラリ関数 : 出来合いのもの.printf など. なぜ関数を定義するのか? 処理を共通化 ( 一般化 ) する プログラムの見通しをよくする 機能分割 ( モジュール化, 再利用 ) 責任 ( あるいは不具合の発生源
Microsoft Word - Cプログラミング演習(12)
第 12 回 (7/9) 4. いくつかのトピック (5)main 関数の引数を利用したファイル処理 main 関数は, 起動する環境から引数を受け取ることができる 例えば 次に示すように,main 関数に引数を用いたプログラムを作成する 01 /* sample */ 02 /* main 関数の引数 */ 03 #include 04 05 main(int argc, char
スライド 1
Graphics with Processing 2008-12 モデリング http://vilab.org 塩澤秀和 1 12.1 3D モデリング モデリング 3Dモデルを作り上げること オブジェクト座標系で基本図形やポリゴンを組み合わせる テクスチャ x テクスチャ z y 2 12.2 オブジェクトの関数例 複雑なオブジェクトは, 大きさ 1 を目安としてモデリングし, 関数にしておくと利用しやすい
ARToolKit プログラムの仕組み 1: ヘッダファイルのインクルード 2: Main 関数 3: Main Loop 関数 4: マウス入力処理関数 5: キーボード入力処理関数 6: 終了処理関数 3: Main Loop 関数 1カメラ画像の取得 2カメラ画像の描画 3マーカの検出と認識
ARToolKit プログラムの仕組み 1: ヘッダファイルのインクルード 2: Main 関数 3: Main Loop 関数 4: マウス入力処理関数 5: キーボード入力処理関数 6: 終了処理関数 3: Main Loop 関数 1カメラ画像の取得 2カメラ画像の描画 3マーカの検出と認識 4 次の画像のキャプチャ指示 5マーカの信頼度の比較 6マーカの位置 姿勢の計算 7バッファの内容を画面に表示
1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1
1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1 文字が 0( 零 ) 10 進数 : 先頭 1 文字が 0( 零 ) 以外の数字 1.1 プログラム
演算増幅器
スペースインベーダーもどき 1000 行プログラムの参考として スペースインベーダーもどきのプログラムを配布する いくつか習って いないものもあるので 補足の説明を加えていく 文字列の描画 文字の描画は glutbitmapcharacter() を用いる これは以下のようにして利用する int i; char *str = "Display String"; glcolor3f(0.0, 0.0,
1 1. Program 1 OpenCV (OpenCV Sample001) 1 /* 2 - > - > - >VC++ 3 ( ) 4 C:\opencv\build\include 5 ( ) 6 C:\opencv\build\x86\vc10\lib 7 - > - > - > - >
1 1. Program 1 OpenCV (OpenCV Sample001) 1 /* 2 - > - > - >VC++ 3 ( ) 4 C:\opencv\build\include 5 ( ) 6 C:\opencv\build\x86\vc10\lib 7 - > - > - > - > 8 (240 O p e n C V ) 9 opencv_core240d.lib 10 opencv_imgproc240d.lib
RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用
RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用体型のローカル変数を文字列操作関数で操作する場合の注意事項 (RXC#013) 配列型構造体または共用体の配列型メンバから読み出した値を動的初期化に用いる場合の注意事項
Java講座
~ 第 1 回 ~ 情報科学部コンピュータ科学科 2 年竹中優 プログラムを書く上で Hello world 基礎事項 演算子 構文 2 コメントアウト (//, /* */, /** */) をしよう! インデントをしよう! 変数などにはわかりやすい名前をつけよう! 要するに 他人が見て理解しやすいコードを書こうということです 3 1. Eclipse を起動 2. ファイル 新規 javaプロジェクト
Taro-ポインタ変数Ⅰ(公開版).j
0. 目次 1. ポインタ変数と変数 2. ポインタ変数と配列 3. ポインタ変数と構造体 4. ポインタ変数と線形リスト 5. 問題 問題 1 問題 2-1 - 1. ポインタ変数と変数 ポインタ変数には 記憶領域の番地が格納されている 通常の変数にはデータが格納されている 宣言 int *a; float *b; char *c; 意味ポインタ変数 aは 整数型データが保存されている番地を格納している
新・明解C言語 実践編
第 1 章 見 21 1-1 見えないエラー 見 List 1-1 "max2x1.h" a, b max2 List 1-1 chap01/max2x1.h max2 "max2x1.h" #define max2(a, b) ((a) > (b)? (a) : (b)) max2 List 1-2 List 1-2 chap01/max2x1test.c max2 #include
問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =
問 1 配列の宣言整数型配列 data1 にデータが初期設定されている この配列 data1 のデータを下図のように 整数型配列 data2 に代入しなさい また data2 の内容を printf( "data2[0] = %d\n", data2[0] ); printf( "data2[5] = %d\n", data2[5] ); を用いて出力しなさい 実行結果 data2[0] = 76
AquesTalk2 Win マニュアル&ライセンス規定
AQUEST Corp. http://www.a-quest.com/ AquesTalk2 Win 版 Manual & Licence 規定 1. 概要 本文書は 規則音声合成ライブラリ AquesTalk2 Win 版をアプリケーションに組み込んで使用するためのプログラミングに関しての方法および注意点および ライセンスに関して示したものです AquesTalk2 は AquesTalk の後継として開発されました
C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ
C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ 今回のプログラミングの課題 次のステップによって 徐々に難易度の高いプログラムを作成する ( 参照用の番号は よくわかる C 言語 のページ番号 ) 1. キーボード入力された整数 10 個の中から最大のものを答える 2. 整数を要素とする配列 (p.57-59) に初期値を与えておき
PowerPoint プレゼンテーション
プログラミング初級 第 7 回 2017 年 5 月 29 日 配列 ( 復習 )~ 文字列 1 配列とは 2 配列 : 複数の変数をグループとしてまとめて扱うもの 配列 変数 int data[10]; 整数型の配列 同種のデータ型を連続して確保したものを配列とよぶ = 整数がそれぞれにひとつずつ入る箱を 10 個用意したようなもの int data; 整数型の変数 = 整数がひとつ入る dataという名前の箱を用意したようなもの
JavaプログラミングⅠ
Java プログラミング Ⅰ 3 回目変数 今日の講義で学ぶ内容 変数とは 変数の使い方 キーボード入力の仕方 変 数 変 数 一時的に値を記憶させておく機能です 変数は 型 ( データ型ともいいます ) と識別子をもちます 2 型 変数に記憶できる値の種類です型は 値の種類に応じて次の 8 種類があり これを基本型といいます 基本型値の種類値の範囲または例 boolean 真偽値 true または
第1回 プログラミング演習3 センサーアプリケーション
C プログラミング - ポインタなんて恐くない! - 藤田悟 [email protected] 目標 C 言語プログラムとメモリ ポインタの関係を深く理解する C 言語プログラムは メモリを素のまま利用できます これが原因のエラーが多く発生します メモリマップをよく頭にいれて ポインタの動きを理解できれば C 言語もこわくありません 1. ポインタ入門編 ディレクトリの作成と移動 mkdir
Fair Curve and Surface Design System Using Tangent Control
情報工学 2016 年度後期第 6 回 [11 月 16 日 ] 静岡大学工学研究科機械工学専攻ロボット 計測情報講座創造科学技術大学院情報科学専攻 三浦憲二郎 講義アウトライン [11 月 16 日 ] ビジュアル情報処理 3 モデリング 3.3 曲線 曲面 OpenGL 色の取り扱い シェーディング 照明モデルと照光処理 拡散光 鏡面光 環境光 ビジュアル情報処理 3-3 曲線 曲面 3-3-1
