X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
| Revision | 145 (tree) |
|---|---|
| Time | 2016-08-27 22:16:49 |
| Author | |
OpenGLでの対応テクスチャを追加、偽装PNG対応。
| @@ -578,31 +578,14 @@ | ||
| 578 | 578 | #endif |
| 579 | 579 | } |
| 580 | 580 | |
| 581 | -//! @brief テクスチャを読み込む | |
| 581 | +//! @brief テクスチャフォーマットを拡張子で判定 | |
| 582 | 582 | //! @param filename ファイル名 |
| 583 | -//! @param texturefont テクスチャフォントフラグ | |
| 584 | -//! @param BlackTransparent 黒を透過する | |
| 585 | -//! @return 成功:テクスチャ認識番号(0以上) 失敗:-1 | |
| 586 | -int D3DGraphics::LoadTexture(char* filename, bool texturefont, bool BlackTransparent) | |
| 583 | +//! @param nowformat 現在の判別値 | |
| 584 | +//! @return 新たな判別値 | |
| 585 | +int D3DGraphics::CheckFileExtension(char* filename, int nowformat) | |
| 587 | 586 | { |
| 588 | - int id = -1; | |
| 589 | 587 | char filename2[MAX_PATH]; |
| 590 | - int format = 0; | |
| 591 | 588 | |
| 592 | -#ifdef ENABLE_DEBUGLOG | |
| 593 | - //ログに出力 | |
| 594 | - OutputLog.WriteLog(LOG_LOAD, "テクスチャ", filename); | |
| 595 | -#endif | |
| 596 | - | |
| 597 | - //空いている認識番号を探す | |
| 598 | - for(int i=0; i<MAX_TEXTURE; i++){ | |
| 599 | - if( ptextures[i].useflag == false ){ | |
| 600 | - id = i; | |
| 601 | - break; | |
| 602 | - } | |
| 603 | - } | |
| 604 | - if( id == -1 ){ return -1; } | |
| 605 | - | |
| 606 | 589 | //ファイル名を小文字へ変換(拡張子判定用) |
| 607 | 590 | for(int i=0; i<strlen(filename); i++){ |
| 608 | 591 | filename2[i] = (char)tolower(filename[i]); |
| @@ -613,24 +596,96 @@ | ||
| 613 | 596 | for(int i=strlen(filename2)-1; i>0; i--){ |
| 614 | 597 | if( filename2[i] == '.' ){ |
| 615 | 598 | if( strcmp(&(filename2[i]), ".bmp") == 0 ){ |
| 616 | - format = 1; | |
| 599 | + return 1; | |
| 617 | 600 | } |
| 618 | 601 | if( strcmp(&(filename2[i]), ".dds") == 0 ){ |
| 619 | - format = 2; | |
| 602 | + return 2; | |
| 620 | 603 | } |
| 621 | 604 | if( strcmp(&(filename2[i]), ".jpeg") == 0 ){ |
| 622 | - format = 3; | |
| 605 | + return 3; | |
| 623 | 606 | } |
| 624 | 607 | if( strcmp(&(filename2[i]), ".jpg") == 0 ){ |
| 625 | - format = 3; | |
| 608 | + return 3; | |
| 626 | 609 | } |
| 610 | + if( strcmp(&(filename2[i]), ".jpe") == 0 ){ | |
| 611 | + return 3; | |
| 612 | + } | |
| 627 | 613 | if( strcmp(&(filename2[i]), ".png") == 0 ){ |
| 628 | - format = 4; | |
| 614 | + return 4; | |
| 629 | 615 | } |
| 616 | + } | |
| 617 | + } | |
| 618 | + | |
| 619 | + return nowformat; | |
| 620 | +} | |
| 621 | + | |
| 622 | +//! @brief テクスチャフォーマットを拡張子で判定 | |
| 623 | +//! @param filename ファイル名 | |
| 624 | +//! @param nowformat 現在の判別値 | |
| 625 | +//! @return 新たな判別値 | |
| 626 | +int D3DGraphics::CheckFileTypeFlag(char* filename, int nowformat) | |
| 627 | +{ | |
| 628 | + FILE *fp; | |
| 629 | + unsigned char header[4]; | |
| 630 | + | |
| 631 | + //ファイルを読み込む | |
| 632 | + fp = fopen(filename, "rb"); | |
| 633 | + if( fp == NULL ){ | |
| 634 | + return false; //ファイルが読めない | |
| 635 | + } | |
| 636 | + | |
| 637 | + //ヘッダーを読む | |
| 638 | + fread(header, 1, 4, fp); | |
| 639 | + | |
| 640 | + //ファイルハンドルを解放 | |
| 641 | + fclose( fp ); | |
| 642 | + | |
| 643 | + if( (header[0x00] == 'B')&&(header[0x01] == 'M') ){ //.bmp | |
| 644 | + return 1; | |
| 645 | + } | |
| 646 | + if( (header[0x00] == 'D')&&(header[0x01] == 'D')&&(header[0x02] == 'S') ){ //.dds | |
| 647 | + return 2; | |
| 648 | + } | |
| 649 | + if( (header[0x00] == 0xFF)&&(header[0x01] == 0xD8) ){ //.jpg | |
| 650 | + return 3; | |
| 651 | + } | |
| 652 | + if( (header[0x00] == 0x89)&&(header[0x01] == 'P')&&(header[0x02] == 'N')&&(header[0x03] == 'G') ){ //.png ※本当は8バイト | |
| 653 | + return 4; | |
| 654 | + } | |
| 655 | + | |
| 656 | + return nowformat; | |
| 657 | +} | |
| 658 | + | |
| 659 | +//! @brief テクスチャを読み込む | |
| 660 | +//! @param filename ファイル名 | |
| 661 | +//! @param texturefont テクスチャフォントフラグ | |
| 662 | +//! @param BlackTransparent 黒を透過する | |
| 663 | +//! @return 成功:テクスチャ認識番号(0以上) 失敗:-1 | |
| 664 | +int D3DGraphics::LoadTexture(char* filename, bool texturefont, bool BlackTransparent) | |
| 665 | +{ | |
| 666 | + int id = -1; | |
| 667 | + int format = 0; | |
| 668 | + | |
| 669 | +#ifdef ENABLE_DEBUGLOG | |
| 670 | + //ログに出力 | |
| 671 | + OutputLog.WriteLog(LOG_LOAD, "テクスチャ", filename); | |
| 672 | +#endif | |
| 673 | + | |
| 674 | + //空いている認識番号を探す | |
| 675 | + for(int i=0; i<MAX_TEXTURE; i++){ | |
| 676 | + if( ptextures[i].useflag == false ){ | |
| 677 | + id = i; | |
| 630 | 678 | break; |
| 631 | 679 | } |
| 632 | 680 | } |
| 681 | + if( id == -1 ){ return -1; } | |
| 633 | 682 | |
| 683 | + //まず拡張子でファイルフォーマットを判定 | |
| 684 | + format = CheckFileExtension(filename, format); | |
| 685 | + | |
| 686 | + //ファイルヘッダーの情報でも確認 | |
| 687 | + format = CheckFileTypeFlag(filename, format); | |
| 688 | + | |
| 634 | 689 | //対応してないフォーマット |
| 635 | 690 | if( format == 0 ){ return -1; } |
| 636 | 691 |
| @@ -760,6 +815,45 @@ | ||
| 760 | 815 | |
| 761 | 816 | unsigned char *data = new unsigned char [width*height*4]; |
| 762 | 817 | |
| 818 | + //各ピクセル4ビットなら、16色パレットモード | |
| 819 | + if( index == 4 ){ | |
| 820 | + unsigned char pixel; | |
| 821 | + unsigned char pixelH; | |
| 822 | + unsigned char pixelL; | |
| 823 | + unsigned char *pallet = new unsigned char [16*4]; | |
| 824 | + fread(pallet, 1, 16*4, fp); | |
| 825 | + | |
| 826 | + for(int h=height-1; h>=0; h--){ | |
| 827 | + for(int w=0; w<(width/2); w++){ | |
| 828 | + fread(&pixel, 1, 1, fp); | |
| 829 | + pixelH = (pixel >> 4)&0x0F; | |
| 830 | + pixelL = pixel&0x0F; | |
| 831 | + | |
| 832 | + data[(h*width+w*2)*4 + 0] = pallet[pixelH*4 + 2]; | |
| 833 | + data[(h*width+w*2)*4 + 1] = pallet[pixelH*4 + 1]; | |
| 834 | + data[(h*width+w*2)*4 + 2] = pallet[pixelH*4 + 0]; | |
| 835 | + data[(h*width+w*2)*4 + 3] = 255; | |
| 836 | + | |
| 837 | + data[(h*width+w*2+1)*4 + 0] = pallet[pixelL*4 + 2]; | |
| 838 | + data[(h*width+w*2+1)*4 + 1] = pallet[pixelL*4 + 1]; | |
| 839 | + data[(h*width+w*2+1)*4 + 2] = pallet[pixelL*4 + 0]; | |
| 840 | + data[(h*width+w*2+1)*4 + 3] = 255; | |
| 841 | + | |
| 842 | + if( BlackTransparent == true ){ | |
| 843 | + //黒ならば透過する | |
| 844 | + if( (data[(h*width+w*2)*4 + 0] == 0)&&(data[(h*width+w*2)*4 + 1] == 0)&&(data[(h*width+w*2)*4 + 2] == 0) ){ | |
| 845 | + data[(h*width+w*2)*4 + 3] = 0; | |
| 846 | + } | |
| 847 | + if( (data[(h*width+w*2+1)*4 + 0] == 0)&&(data[(h*width+w*2+1)*4 + 1] == 0)&&(data[(h*width+w*2+1)*4 + 2] == 0) ){ | |
| 848 | + data[(h*width+w*2+1)*4 + 3] = 0; | |
| 849 | + } | |
| 850 | + } | |
| 851 | + } | |
| 852 | + } | |
| 853 | + | |
| 854 | + delete []pallet; | |
| 855 | + } | |
| 856 | + | |
| 763 | 857 | //各ピクセル8ビットなら、256色パレットモード |
| 764 | 858 | if( index == 8 ){ |
| 765 | 859 | unsigned char pixel; |
| @@ -809,6 +903,28 @@ | ||
| 809 | 903 | } |
| 810 | 904 | } |
| 811 | 905 | |
| 906 | + //各ピクセル32ビットなら、フルカラー | |
| 907 | + if( index == 32 ){ | |
| 908 | + unsigned char pixel[4]; | |
| 909 | + for(int h=height-1; h>=0; h--){ | |
| 910 | + for(int w=0; w<width; w++){ | |
| 911 | + fread(&pixel, 1, 4, fp); | |
| 912 | + | |
| 913 | + data[(h*width+w)*4 + 0] = pixel[2]; | |
| 914 | + data[(h*width+w)*4 + 1] = pixel[1]; | |
| 915 | + data[(h*width+w)*4 + 2] = pixel[0]; | |
| 916 | + data[(h*width+w)*4 + 3] = 255; | |
| 917 | + | |
| 918 | + if( BlackTransparent == true ){ | |
| 919 | + //黒ならば透過する | |
| 920 | + if( (data[(h*width+w)*4 + 0] == 0)&&(data[(h*width+w)*4 + 1] == 0)&&(data[(h*width+w)*4 + 2] == 0) ){ | |
| 921 | + data[(h*width+w)*4 + 3] = 0; | |
| 922 | + } | |
| 923 | + } | |
| 924 | + } | |
| 925 | + } | |
| 926 | + } | |
| 927 | + | |
| 812 | 928 | //ファイルハンドルを解放 |
| 813 | 929 | fclose( fp ); |
| 814 | 930 |
| @@ -834,6 +950,7 @@ | ||
| 834 | 950 | unsigned char header[124+4]; |
| 835 | 951 | unsigned int width, height; |
| 836 | 952 | unsigned int index; |
| 953 | + unsigned int flag; | |
| 837 | 954 | |
| 838 | 955 | //ファイルを読み込む |
| 839 | 956 | fp = fopen(filename, "rb"); |
| @@ -1000,6 +1117,7 @@ | ||
| 1000 | 1117 | png_structp pPng; |
| 1001 | 1118 | png_infop pInfo; |
| 1002 | 1119 | unsigned int width, height; |
| 1120 | + bool pallet; | |
| 1003 | 1121 | |
| 1004 | 1122 | //ファイルを読み込む |
| 1005 | 1123 | fp = fopen(filename, "rb"); |
| @@ -1034,41 +1152,97 @@ | ||
| 1034 | 1152 | return false; //インターレスには対応しない。 |
| 1035 | 1153 | } |
| 1036 | 1154 | |
| 1155 | + //ビット深度判定 | |
| 1156 | + if( png_get_bit_depth(pPng, pInfo) != 8 ){ | |
| 1157 | + png_destroy_read_struct(&pPng, &pInfo, (png_infopp)NULL); | |
| 1158 | + fclose(fp); | |
| 1159 | + return false; //深度が8ビット以外は対応してない。 | |
| 1160 | + } | |
| 1161 | + | |
| 1162 | + //カラータイプ判定 | |
| 1163 | + if( (png_get_color_type(pPng, pInfo) == PNG_COLOR_TYPE_GRAY)||(png_get_color_type(pPng, pInfo) == PNG_COLOR_TYPE_GRAY_ALPHA) ){ | |
| 1164 | + png_destroy_read_struct(&pPng, &pInfo, (png_infopp)NULL); | |
| 1165 | + fclose(fp); | |
| 1166 | + return false; //グレースケールには対応してない・・っと思われるので除外。(未検証) | |
| 1167 | + } | |
| 1168 | + | |
| 1169 | + //カラータイプ取得 | |
| 1170 | + if( png_get_color_type(pPng, pInfo) == PNG_COLOR_TYPE_PALETTE ){ | |
| 1171 | + pallet = true; | |
| 1172 | + } | |
| 1173 | + else{ | |
| 1174 | + pallet = false; | |
| 1175 | + } | |
| 1176 | + | |
| 1177 | + unsigned char *data = new unsigned char [width*height*4]; | |
| 1178 | + | |
| 1037 | 1179 | //アルファチャンネルを初期化 |
| 1038 | 1180 | png_set_add_alpha(pPng, 0xff, PNG_FILLER_AFTER); |
| 1039 | 1181 | |
| 1040 | - // tRNSチャンクがあれば、アルファチャンネルに変換 | |
| 1041 | - if (png_get_valid(pPng, pInfo, PNG_INFO_tRNS)) { | |
| 1042 | - png_set_tRNS_to_alpha(pPng); | |
| 1182 | + if( pallet == false ){ | |
| 1183 | + // tRNSチャンクがあれば、アルファチャンネルに変換 | |
| 1184 | + if (png_get_valid(pPng, pInfo, PNG_INFO_tRNS)) { | |
| 1185 | + png_set_tRNS_to_alpha(pPng); | |
| 1186 | + } | |
| 1187 | + | |
| 1188 | + //1ライン分の作業領域を確保 | |
| 1189 | + png_bytep buf = new png_byte[width*4]; | |
| 1190 | + | |
| 1191 | + for(int h=0; h<height; h++){ | |
| 1192 | + //1ライン分取得 | |
| 1193 | + png_read_row(pPng,buf,NULL); | |
| 1194 | + | |
| 1195 | + for(int w=0; w<width; w++){ | |
| 1196 | + data[(h*width+w)*4 + 0] = buf[w*4 + 0]; | |
| 1197 | + data[(h*width+w)*4 + 1] = buf[w*4 + 1]; | |
| 1198 | + data[(h*width+w)*4 + 2] = buf[w*4 + 2]; | |
| 1199 | + data[(h*width+w)*4 + 3] = buf[w*4 + 3]; | |
| 1200 | + | |
| 1201 | + if( BlackTransparent == true ){ | |
| 1202 | + //黒ならば透過する | |
| 1203 | + if( (data[(h*width+w)*4 + 0] == 0)&&(data[(h*width+w)*4 + 1] == 0)&&(data[(h*width+w)*4 + 2] == 0) ){ | |
| 1204 | + data[(h*width+w)*4 + 3] = 0; | |
| 1205 | + } | |
| 1206 | + } | |
| 1207 | + } | |
| 1208 | + } | |
| 1209 | + | |
| 1210 | + //1ライン分の作業領域を解放 | |
| 1211 | + delete [] buf; | |
| 1043 | 1212 | } |
| 1213 | + else{ | |
| 1214 | + png_colorp palette; | |
| 1215 | + int num; | |
| 1044 | 1216 | |
| 1045 | - unsigned char *data = new unsigned char [width*height*4]; | |
| 1217 | + //パレット取得 | |
| 1218 | + png_get_PLTE(pPng, pInfo, &palette, &num); | |
| 1046 | 1219 | |
| 1047 | - //1ライン分の作業領域を確保 | |
| 1048 | - png_bytep buf = new png_byte[width*4]; | |
| 1220 | + //1ライン分の作業領域を確保 | |
| 1221 | + png_bytep buf = new png_byte[width]; | |
| 1049 | 1222 | |
| 1050 | - for(int h=0; h<height; h++){ | |
| 1051 | - //1ライン分取得 | |
| 1052 | - png_read_row(pPng,buf,NULL); | |
| 1223 | + for(int h=0; h<height; h++){ | |
| 1224 | + //1ライン分取得 | |
| 1225 | + png_read_row(pPng,buf,NULL); | |
| 1053 | 1226 | |
| 1054 | - for(int w=0; w<width; w++){ | |
| 1055 | - data[(h*width+w)*4 + 0] = buf[w*4 + 0]; | |
| 1056 | - data[(h*width+w)*4 + 1] = buf[w*4 + 1]; | |
| 1057 | - data[(h*width+w)*4 + 2] = buf[w*4 + 2]; | |
| 1058 | - data[(h*width+w)*4 + 3] = buf[w*4 + 3]; | |
| 1227 | + for(int w=0; w<width; w++){ | |
| 1228 | + data[(h*width+w)*4 + 0] = palette[ buf[w] ].red; | |
| 1229 | + data[(h*width+w)*4 + 1] = palette[ buf[w] ].green; | |
| 1230 | + data[(h*width+w)*4 + 2] = palette[ buf[w] ].blue; | |
| 1231 | + data[(h*width+w)*4 + 3] = 255; | |
| 1059 | 1232 | |
| 1060 | - if( BlackTransparent == true ){ | |
| 1061 | - //黒ならば透過する | |
| 1062 | - if( (data[(h*width+w)*4 + 0] == 0)&&(data[(h*width+w)*4 + 1] == 0)&&(data[(h*width+w)*4 + 2] == 0) ){ | |
| 1063 | - data[(h*width+w)*4 + 3] = 0; | |
| 1233 | + if( BlackTransparent == true ){ | |
| 1234 | + //黒ならば透過する | |
| 1235 | + if( (data[(h*width+w)*4 + 0] == 0)&&(data[(h*width+w)*4 + 1] == 0)&&(data[(h*width+w)*4 + 2] == 0) ){ | |
| 1236 | + data[(h*width+w)*4 + 3] = 0; | |
| 1237 | + } | |
| 1064 | 1238 | } |
| 1065 | 1239 | } |
| 1066 | 1240 | } |
| 1241 | + | |
| 1242 | + //1ライン分の作業領域を解放 | |
| 1243 | + delete [] buf; | |
| 1067 | 1244 | } |
| 1068 | 1245 | |
| 1069 | - //1ライン分の作業領域を解放 | |
| 1070 | - delete [] buf; | |
| 1071 | - | |
| 1072 | 1246 | //解放 |
| 1073 | 1247 | png_read_end(pPng, NULL); |
| 1074 | 1248 | png_destroy_read_struct(&pPng, &pInfo, (png_infopp)NULL); |
| @@ -232,6 +232,8 @@ | ||
| 232 | 232 | jpeg_decompress_struct cinfo; //!< libjpeg |
| 233 | 233 | jpeg_error_mgr jerr; //!< libjpeg |
| 234 | 234 | |
| 235 | + int CheckFileExtension(char* filename, int nowformat); | |
| 236 | + int CheckFileTypeFlag(char* filename, int nowformat); | |
| 235 | 237 | bool LoadBMPTexture(char* filename, bool BlackTransparent, TEXTUREDATA *ptexture); |
| 236 | 238 | bool LoadDDSTexture(char* filename, bool BlackTransparent, TEXTUREDATA *ptexture); |
| 237 | 239 | bool LoadJPEGTexture(char* filename, bool BlackTransparent, TEXTUREDATA *ptexture); |