2013-12-02 1 views
-1

У меня проблема при попытке загрузить изображение с помощью библиотек GDAL и реализует его (изображение) в OpenGL Control. Проблема заключается в цвете, как вы можете видеть на picture.Загрузить изображение с библиотеками GDAL (VC++)

И это функция для генерации текстуры с картинки:

GLuint COpenGLControl::ReadGDALData(CString filename) 
{ 
BYTE* tempReturn; 
GLuint texture; 

GDALDataset *poDataset; 
GDALAllRegister(); 
poDataset = (GDALDataset *) GDALOpen((const char *)(CStringA)filename, GA_ReadOnly); 

int Height = poDataset->GetRasterXSize(), Width = poDataset->GetRasterYSize(); 
LONG LineBytes = (Width*8+31)/32*4; 
BYTE * pData = (BYTE *)new char[ LineBytes * Height * 3]; 

if (poDataset == NULL) 
{ 
    AfxMessageBox("Couldn't open selected file!"); 
    return NULL; 
} 

nBands = poDataset->GetRasterCount(); 

GDALRasterBand **poBand; 
poBand = new GDALRasterBand *[nBands]; 

if (poBand == NULL) 
{ 
    AfxMessageBox("Couldn't open the bands!", MB_ICONWARNING); 
    return NULL; 
} 

for (int i=0; i<nBands; i++) 
{ 
    poBand[i] = poDataset->GetRasterBand(i+1); 
    if (poBand[i] == NULL) 
    { 
     AfxMessageBox("Couldn't open selected bands", MB_ICONWARNING); 
     return NULL; 
    } 
} 

int BandChoice = 2; 

nXsize = poBand[BandChoice]->GetXSize(); 
nYsize = poBand[BandChoice]->GetYSize(); 

if (BandChoice == 1) 
{ 
    poBandBlock_Gray = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsize*nYsize)); 
    poBand[BandChoice]->RasterIO(GF_Read, 0, 0, nXsize, nYsize, poBandBlock_Gray, nXsize, nYsize, poBand[BandChoice]->GetRasterDataType(), 0, 0); 
} 
else 
{ 
    int nXsize_R, nXsize_G, nXsize_B; 
    int nYsize_R, nYsize_G, nYsize_B; 

    int BandChoiceR = 0; 
    int BandChoiceG = 1; 
    int BandChoiceB = 2; 

    nXsize_R = poBand[BandChoiceR]->GetXSize(); 
    nXsize_G = poBand[BandChoiceG]->GetXSize(); 
    nXsize_B = poBand[BandChoiceB]->GetXSize(); 
    nYsize_R = poBand[BandChoiceR]->GetYSize(); 
    nYsize_G = poBand[BandChoiceG]->GetYSize(); 
    nYsize_B = poBand[BandChoiceB]->GetYSize(); 

    nXsize = nXsize_R; 
    nYsize = nYsize_R; 

    poBandBlock_R = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsize_R*nYsize_R)); 
    poBandBlock_G = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsize_G*nYsize_G)); 
    poBandBlock_B = (BYTE*)CPLMalloc(sizeof(BYTE)*(nXsize_B*nYsize_B)); 

    poBand[BandChoiceR]->RasterIO(GF_Read, 0, 0, nXsize_R, nYsize_R, poBandBlock_R, nXsize_R, nYsize_R, poBand[BandChoiceR]->GetRasterDataType(), 0, 0); 
    poBand[BandChoiceG]->RasterIO(GF_Read, 0, 0, nXsize_G, nYsize_G, poBandBlock_G, nXsize_G, nYsize_G, poBand[BandChoiceG]->GetRasterDataType(), 0, 0); 
    poBand[BandChoiceB]->RasterIO(GF_Read, 0, 0, nXsize_B, nYsize_B, poBandBlock_B, nXsize_B, nYsize_B, poBand[BandChoiceB]->GetRasterDataType(), 0, 0); 

    delete poDataset; 
} 

if (BandChoice == 1) 
{ 
    for (int i=0; i < Height; i++) 
    { 
     for (int j=0; j < Width; j++) 
     { 
      pData[(Height-i-1) * LineBytes + j] = poBandBlock_Gray[i*Width + j]; 
     } 
    } 

    CPLFree(poBandBlock_Gray); 
} 
else 
{ 
    int j2 ; 
    for (int i=0; i<Height; i++) 
    { 
     for (int j=0, j2=0; j < Width, j2 < 3 * Width; j++, j2+=3) 
     { 
      pData[(Height-i-1)*LineBytes + j2+2] = poBandBlock_R[i*Width + j]; 
      pData[(Height-i-1)*LineBytes + j2+1] = poBandBlock_G[i*Width + j]; 
      pData[(Height-i-1)*LineBytes + j2] = poBandBlock_B[i*Width + j]; 
     } 
    } 

    CPLFree(poBandBlock_B); 
    CPLFree(poBandBlock_R); 
    CPLFree(poBandBlock_G); 
} 

// allocate a texture name 
glGenTextures(1, &texture); 

// select our current texture 
glBindTexture(GL_TEXTURE_2D, texture); 

// select modulate to mix texture with color for shading 
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

// when texture area is small, bilinear filter the closest mipmap 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
       GL_LINEAR_MIPMAP_NEAREST); 
// when texture area is large, bilinear filter the first mipmap 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

// if wrap is true, the texture wraps over at the edges (repeat) 
//  ... false, the texture ends at the edges (clamp) 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, FALSE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, FALSE); 

// build our texture mipmaps 
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData); 

// free buffer 
free(pData); 

return texture; 
} 

Это функция Draw:

void COpenGLControl::OnDraw(CDC *pDC) 
{ 
// TODO: Camera controls 
wglMakeCurrent(hdc,hrc); 

// Set color to use when clearing the background. 
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glClearDepth(1.0f); 

// Turn on backface culling 
glFrontFace(GL_CCW); 
glCullFace(GL_FRONT_AND_BACK); 

// Turn on depth testing 
glEnable(GL_DEPTH_TEST); 
glDepthFunc(GL_LEQUAL); 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear all objects 

glEnable(GL_TEXTURE_2D); // enable texture for 2 dimensions 

glPushMatrix(); 

if (filename.IsEmpty() == false) 
{ 
    imgData = ReadGDALData(filename); 
    glBindTexture(GL_TEXTURE_2D, imgData); 
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear all objects 

    glLoadIdentity(); 
    gluLookAt  (0,0,1,0,0,0,0,1,0); 
    glTranslatef (m_fPosX, m_fPosY, 0.0f); 
    glScalef  (m_fZoom,m_fZoom,1.0); 

    glBegin(GL_QUADS); // apply loaded texture to viewport 
     glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); 
     glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); 
     glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0); 
     glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0); 
    glEnd(); 
} 

glPopMatrix(); 

glDisable(GL_TEXTURE_2D); 

glFlush(); 

// Swap buffers 
SwapBuffers(hdc); 

wglMakeCurrent(NULL, NULL); 
} 

ответ

0

Проблема не столько в цвете, но (из того, что Я могу сказать из примера), как ваши данные упакованы. Посмотрите, в каком порядке байтов заказывается/заполняется строка/цвет, который ожидает ваш буфер OpenGL, и в вашем загрузчике GDAL то, что он предоставляет. Просто догадка здесь, но похоже, что ваш OpenGL ожидает 4-го (альфа-компонента) в ваших структурах RGB, но ваш код GDAL этого не дает. Кроме того, ваш GDAL-загрузчик выравнивается на 32-битных границах, кажется, проверьте, требуют ли ваши вызовы текстуры OpenGL. Вы копировали/вставляли загрузчик GDAL из образца, где кто-то использует его для рисования с помощью BitBlt()? Это выглядит так.