私は最近、より単純な画像形式の低レベルの動作を理解するために、純粋なCでビットビットパーサーのビットに取り組んでいます。これまでのところ、ビットマップファイルに関するウィキペディアの記事を使用して、私は(少なくとも私が思うに)情報を正しく解析することができました-少なくとも、そのほとんど。
問題は、そこから何をすべきかよくわからないことです。3.1コンテキストで作業しているので、まだ迷っていますが、より多くの最新機能にアクセスできます。私はGLFWを使用してウィンドウを設定していますが、解析/低レベルの詳細に焦点を合わせているため、これまでのところ実際には何もレンダリングされていません。
私は実際のコード例を見ないように一生懸命努力しているので、OpenGL /GLFWとISOC標準ライブラリだけを使用して、ビットマップのレンダリングの背後にあるプロセスを誰かが説明してくれると便利です。
いくつかのシェーダーを配置していて、問題なくロードできますが、必要なのは、の寸法(幅、高さ)に一致する[非表示]クワッドをレンダリングすることだと思います。画像自体を作成し、ピクセルデータをOpenGLに渡します。ただし、主な問題は、シェーダーが次のように設定されていることです。
バーテックスシェーダー
#version 150
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 Position;
layout(location = 1) in vec2 UV_In;
out vec2 UV;
void main()
{
gl_Position = vec4( Position, 0.0f, 1.0f );
UV = UV_In;
}
フラグメントシェーダー
#version 150
#extension GL_ARB_separate_shader_objects : enable
in vec2 UV;
out vec3 Output;
uniform sampler2D TheSampler;
void main()
{
Output = texture2D( TheSampler, UV ).rgb;
}
また、シェーダーに必要な実際のUV座標を取得する方法がわかりません。頂点を生成し、それらを配列に格納し、UV座標の線に沿って何かを呼び出す必要があると思いますが、glVertexAttribPointer(...)
これを取得するために画像からどのデータを使用する必要があるかわかりません。関数内ですでに解析されているかどうかに関係なく。行/列の方法で内側/外側のforループ(外側はxを表し、内側はyを表す)を使用して画像をクロールする必要があると思います。それでも、私はこれについていくらか混乱していると感じており、これが私が必要としているものであるかどうかはわかりません。
いずれにせよ、これを行う方法についてのアドバイスをいただければ幸いです。
画像を解析するための実際のコード(HEADER_LENGTH
= 54バイト):
GLuint Image_LoadBmp( const char* fname, image_bmp_t* data )
{
uint8_t header[ HEADER_LENGTH ];
FILE* f = fopen( fname, "rb" );
if ( !f )
{
printf( "ERROR: file \"%s\" could not be opened [likely] due to incorrect path. :/ \n", fname );
return 0; // return false
}
data->filename = strdup( fname ); // TODO: write a wrapper for strdup which exits program on NULL returns
const size_t num_bytes_read = fread( ( void* )header, sizeof( uint8_t ), HEADER_LENGTH, f );
if ( num_bytes_read != HEADER_LENGTH )
{
printf( "ERROR: file \"%s\" could not be opened due to header size being " _SIZE_T_SPECIFIER " bytes; "\
"this is an invalid format. \n", fname, num_bytes_read );
return 0;
}
if ( header[ 0 ] != *( uint8_t* )"B" || header[ 1 ] != *( uint8_t* )"M" )
{
printf( "ERROR: file \"%s\" does NOT have a valid signature \n", fname );
return 0;
}
data->image_size = *( uint32_t* )&( header[ 0x22 ] );
data->header_size = ( uint32_t )( header[ 0x0E ] );
data->width = ( uint32_t )( header[ 0x12 ] );
data->height = ( uint32_t )( header[ 0x16 ] );
data->pixel_data_pos = ( uint32_t )( header[ 0x0A ] );
data->compression_method = ( uint8_t )( header[ 0x1E ] );
data->bpp = ( uint8_t )( header[ 0x1C ] );
// TODO (maybe): add support for other compression methods
if ( data->compression_method != CM_RGB )
{
puts( "ERROR: file \"%s\" does NOT have a supported compression method for this parser; \n" \
"\t Currently, the compression methods supported are: \n" \
"\t - BI_RGB \n\n"
);
return 0;
}
return 1;
}
また、現在の画像から収集された画像情報によるデバッグ出力は次のようになります。
Info for "assets/sprites/nave/nave0001.bmp" {
Size = 3612 Header Size = 40
Width = 27 Height = 43
Pixel Array Address = 54 Compression Method = 0
Bits Per Pixel = 24
}