2016-07-25 10 views
0

現在、私は作成したマップを保存するための基本レベルエディタプログラムの機能を改良しています。それは生成されたマップの.bmpイメージを吐き出します。それは私がちょうどCImgと呼ばれるライブラリを介してこれを行います。すべてがうまくいくように見えますが、結果の.bmp画像は色が付いておらず、白黒の異なる色合いで表示されます。私が言ったように、私は基本的にライブラリについては何も知っていないので、ここで何が問題になるかも知れば、助けていただければ幸いです。ここでCImg画像は無色です

セーブ機能です:(TextureCoordのように)

void Map::Save() { 
    Vertex top_left_most, top_right_most, bottom_left_most; 
    int img_w = 0, img_h = 0; 

    std::vector<std::pair<GLuint, GLuint>>::iterator tl = bufferIDs.begin();   //This little block gives the _most variables valid starting vals 
    glBindBuffer(GL_ARRAY_BUFFER, tl->second); 
    glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &top_left_most); 
    top_right_most = bottom_left_most = top_left_most; 


    for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS TOP LEFT MOST TILE ON MAP 
     Vertex current_coord; 
     glBindBuffer(GL_ARRAY_BUFFER, i->second); 
     glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &current_coord); 

     if ((current_coord.x < top_left_most.x && current_coord.y < top_left_most.y) || 
      (current_coord.x == top_left_most.x && current_coord.y < top_left_most.y) || 
      (current_coord.x < top_left_most.x && current_coord.y == top_left_most.y)) { 

      top_left_most = current_coord; 
     } 
    } 

    for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS TOP RIGHT MOST TILE ON MAP 
     Vertex current_coord; 
     glBindBuffer(GL_ARRAY_BUFFER, i->second); 
     glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &current_coord); 

     if ((current_coord.x > top_right_most.x && current_coord.y < top_right_most.y) || 
      (current_coord.x == top_right_most.x && current_coord.y < top_right_most.y) || 
      (current_coord.x > top_right_most.x && current_coord.y == top_right_most.y)) { 

      top_right_most = current_coord; 
     } 
    } 

    for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS BOTTOM LEFT MOST TILE ON MAP 
     Vertex current_coord; 
     glBindBuffer(GL_ARRAY_BUFFER, i->second); 
     glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &current_coord); 

     if ((current_coord.x < bottom_left_most.x && current_coord.y > bottom_left_most.y) || 
      (current_coord.x == bottom_left_most.x && current_coord.y > bottom_left_most.y) || 
      (current_coord.x < bottom_left_most.x && current_coord.y == bottom_left_most.y)) { 

      bottom_left_most = current_coord; 
     } 
    } 

    img_w = (top_right_most.x + 64) - top_left_most.x;  //Calculating image dimensions for the buffer 
    img_h = (bottom_left_most.y + 64) - top_left_most.y; 

    GLuint *image = new GLuint[img_w * img_h];  //Creating the image buffer 

    int int_start_x = 0;  //start_x and y that will be used in buffer pointer positioning computations 
    int int_start_y = 0; 

    //these nested fors fill the buffer 
    for (GLfloat start_y = top_left_most.y; start_y != bottom_left_most.y + 64; start_y += 64) { 

     for (GLfloat start_x = top_left_most.x; start_x != top_right_most.x + 64; start_x += 64) { 

      bool in_map = false; 
      std::vector<std::pair<GLuint, GLuint>>::iterator valid_tile; 
      for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) {   //This for checks to see if tile corresponding to start_x & y is present in map 
       Vertex current_tile_pos; 
       glBindBuffer(GL_ARRAY_BUFFER, i->second); 
       glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &current_tile_pos); 

       if (current_tile_pos.x == start_x && current_tile_pos.y == start_y) { 
        in_map = true; 
        valid_tile = i; 
        break; 
       } 
      } 

      GLuint *imagepos = image;  //Repositioning the pointer into the final image's buffer 
      imagepos += int_start_x + (int_start_y * img_w); 

      if (in_map) {  //if in map, that tile's texture is used to fill the corresponding part of the image buffer 
       GLuint *texture = new GLuint[64 * 64]; 
       glBindTexture(GL_TEXTURE_2D, valid_tile->first); 
       glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); 
       GLuint *texturepos = texture; 

       for (GLuint ypos = 0; ypos != 64; ++ypos) { 
        std::memcpy(imagepos, texturepos, 64 * 4); 
        texturepos += 64; 
        imagepos += img_w; 
       } 

       if (texture) 
        delete[] texture; 
      } 
      else {    //otherwise, a default all-black array is used to fill the corresponding untiled part of the image buffer 
       GLuint *black_buffer = new GLuint[64 * 64]; 
       GLuint *blackpos = black_buffer; 
       GLuint solid_black; 
       char *p = (char *)&solid_black; 
       p[0] = 0; 
       p[1] = 0; 
       p[2] = 0; 
       p[3] = 255; 

       for (GLuint i = 0; i != 64 * 64; ++i) { 
        black_buffer[i] = solid_black; 
       } 

       for (GLuint ypos = 0; ypos != 64; ++ypos) { 
        std::memcpy(imagepos, blackpos, 64 * 4); 
        blackpos += 64; 
        imagepos += img_w; 
       } 

       if (black_buffer) 
        delete[] black_buffer; 

      } 
      int_start_x += 64; 
     } 
     int_start_x = 0; 
     int_start_y += 64; 
    } 

    cimg_library::CImg<GLuint> final_image(image, img_w, img_h); //no color!! 

    final_image.save_bmp("map.bmp"); 

    if (image) 
     delete[] image; 
} 

いくつかの説明が参考になる場合は、Vertexは2 GLfloat秒の簡単なstructで、bufferIDsGLuint秒のstd::pair秒のstd::vectorあり、第1のテクスチャはテクスチャIDを表し、第2のテクスチャはVBO IDを表す。ここで

は、要求されたサンプル画像です:あなたは、カラー画像を期待している場合には、単一チャネル・イメージを作成するため

what the image should look like (this is in monochrome)

Same exact image as above, but created using the reinterpret_cast method

答えて

0

あなたのライン

cimg_library::CImg<GLuint> final_image(image, img_w, img_h); 

が間違っています。 3つのチャンネルを作成するには、最後に3が必要です.1つは赤、1つは緑、もう1つは青です。 CIMGを保存したい

RGBA RGBA RGBA RGBA 
RGBA RGBA RGBA RGBA 

に対し:

はまた、あなたのデータは、すなわちバンドインターリーブ・バイ・ピクセル、4x2のピクセル画像は、次のように保存されることを意味しGLuintに保存されていますバンドインターリーブバイプレーン方法であること:

RRRRRRRR 
GGGGGGGG 
BBBBBBBB 
AAAAAAAA 

このlinkは説明しますCImgメモリバッファのレイアウト。

関連する問題