2017-07-07 28 views
1

配列の(配列の)動的配列を作成しようとしています。しかし何らかの理由でデータが破損する。私はOpenGLアプリケーションでテクスチャを生成するためにデータを使用しています。(配列の)配列の動的配列を作成するにはどうすればよいですか?

次のコードは正常に動作します:

unsigned char imageData[64][64][3]; 
    for (int i = 0; i < 64; i++) 
    { 
     for (int j = 0; j < 64; j++) 
     { 
      unsigned char r = 0, g = 0, b = 0; 
      if (i < 32) 
      { 
       if (j < 32) 
        r = 255; 
       else 
        b = 255; 
      } 
      else 
      { 
       if (j < 32) 
        g = 255; 
      } 
      imageData[i][j][0] = r; 
      imageData[i][j][1] = g; 
      imageData[i][j][2] = b; 
     } 
     std::cout << std::endl; 
    } 

    glTexImage2D(target, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); 

問題は、私は(だけでなく、64 * 64)任意のサイズのテクスチャを作成できるようにしたいです。だから私は、このしようとしている:

unsigned char*** imageData = new unsigned char**[64](); 
for (int i = 0; i < 64; i++) 
{ 
    imageData[i] = new unsigned char*[64](); 
    for (int j = 0; j < 64; j++) 
    { 
     imageData[i][j] = new unsigned char[3](); 
     unsigned char r = 0, g = 0, b = 0; 
     if (i < 32) 
     { 
      if (j < 32) 
       r = 255; 
      else 
       b = 255; 
     } 
     else 
     { 
      if (j < 32) 
       g = 255; 
     } 
     imageData[i][j][0] = r; 
     imageData[i][j][1] = g; 
     imageData[i][j][2] = b; 
    } 
    std::cout << std::endl; 
} 

glTexImage2D(target, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); 

をしかし、それは動作しない、画像がすべてのように、私は私が間違って(配列の)配列の配列を作成してい仮定めちゃくちゃますか?私は間違って何をしていますか?

また、私はベクトルを代わりに使用する必要があります。しかし、どのようにベクトルデータのベクトルのベクトルを(void *)にキャストできますか?

+0

あなたは何を意味するのですか?何が正確に起こるか? – PYA

+1

unsigned char * imageData = new unsigned char [width * height * 3]; – nullqube

+0

@pyjg:私の編集を参照してください。色が期待通りに表示されません。それをよりよく表現する方法がわからない、スクリーンショットをアップロードできますか? – gromit190

答えて

3

あるこの行は、複数のバグが含まれています

unsigned char* pixel = &(imageData[(y * height) + x]); 

xに高さを掛け、yを追加する必要があります。また、各ピクセルが実際には3バイトであるという事実もあります。コード内でこのバグにつながったいくつかの問題(他の人につながる)

  • std::vectorも使用する必要があります。 std::vector::dataに電話をかけて、基礎となるデータへのポインタを取得して、C APIとのインタフェースをとることができます。
  • ピクセルを表すクラスが必要です。これは正しくオフセットを処理し、物事の名前を与え、コードを明確にします。
  • 多次元配列を使用して1次元の配列にエンコードしている場合は、索引付けを行うアクセス関数を慎重に記述して、別々にテストできるようにする必要があります。

(末尾の箇条書きリスト...ああ)。

struct Pixel { 
    unsigned char red; 
    unsigned char blue; 
    unsigned char green; 
}; 

struct TwoDimPixelArray { 
    TwoDimArray(int width, int height) 
     : m_width(width), m_height(height) 
    { 
     m_vector.resize(m_width * m_height); 
    } 

    Pixel& get(int x, int y) { 
     return m_vector[x*height + y]; 
    } 

    Pixel* data() { return m_vector.data(); }  

private: 
    int m_width; 
    int m_height; 
    std::vector<Pixel> m_vector; 
} 

int width = 64; 
int height = 64; 

TwoDimPixelArray imageData(width, height); 

for (int x = 0; x != width ; ++ x) { 
    for (int y = 0; y != height ; ++y) {  
     auto& pixel = imageData.get(x, y); 

     // ... pixel.red = something, pixel.blue = something, etc 
    } 
} 

glTexImage2D(target, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData.data()); 
+1

重要な点は、このデザインがOOデザインであり、データホルダーが適切なクラスに置き換えられていることです。何でもできる配列の配列とは異なります。私のupvoteをしてください。 – Aziuth

+0

それは(y * WIDTH)+ xでした。各行は1行のピクセルで、WIDTHと同じです(各行は正確にWIDTHの長さです)。 – nullqube

+0

@nullqube私は、行の主要なフォームと列の主要なフォームのどちらに格納するかによって異なります。私はあなたの数式が、私のように一貫した結果をもたらすが、元の質問のものではないことに同意する。 –

0

OpenGLで動作させるには、連続したメモリを使用する必要があります。 私のソリューションは、それがテストされていないのですが、私ははsizeof(char型)と仮定すると確信して異なるインデックスシステム

unsigned char* imageData = new unsigned char[width*height*3]; 
unsigned char r, g, b; 
const unsigned int row_size_bytes = width * 3; 

for(unsigned int x = 0; x < width; x++) { 
    unsigned int current_row_offset_bytes = x * 3; 
    for(unsigned int y = 0; y < height; y++) { 
     unsigned int one_dim_offset = y * row_size_bytes + current_row_offset_bytes 
     unsigned char* pixel = &(imageData[one_dim_offset]); 
     pixel[0] = r; 
     pixel[1] = g; 
     pixel[2] = b; 
    } 
} 

Unfortunnatelyで、前回の回答に触発された1

関連する問題