Domanda

I am new to openGL and am working on a volume rendering project. So the project needs to read frames from a file at first and then constructs the 2D textures. In the sample code, the programmer uses the CFile.read() function to do this. However, I am working on my MacPro, it seems that we can only use CFile under Windows. So please tell me what can I do to successfully read the image data.

P.S.: The sample code is 3D texture based while my code is 2D texture based. So there may be some differences. However, you should only focus on the functions which read the image data here rather than the statements that generate the textures.

The sample code:

bool CRawDataProcessor::ReadFile( LPCTSTR lpDataFile_i, int nWidth_i, int nHeight_i, int nSlices_i )
{
    CFile Medfile;
    if( !Medfile.Open( lpDataFile_i ,CFile::modeRead ))
    {
        return false;
    }

    // File has only image data. The dimension of the data should be known.
    m_uImageCount = nSlices_i;
    m_uImageWidth = nWidth_i;
    m_uImageHeight = nHeight_i;

    // Holds the luminance buffer.
    char* chBuffer = new char[ m_uImageWidth*m_uImageHeight*m_uImageCount ];
    if( !chBuffer )
    {
        return false;
    }
    // Holds the RGBA buffer.
    char* pRGBABuffer = new char[ m_uImageWidth*m_uImageHeight*m_uImageCount*4 ];
    if( !pRGBABuffer )
    {
        return false;
    }

    Medfile.Read( chBuffer, m_uImageWidth*m_uImageHeight*m_uImageCount );

    // Convert the data to RGBA data.
    // Here we are simply putting the same value to R, G, B and A channels.
    // Usually for raw data, the alpha value will be constructed by a threshold value  given by the user.

    for( int nIndx = 0; nIndx < m_uImageWidth*m_uImageHeight*m_uImageCount; ++nIndx )
    {
        pRGBABuffer[nIndx*4] = chBuffer[nIndx];
        pRGBABuffer[nIndx*4+1] = chBuffer[nIndx];
        pRGBABuffer[nIndx*4+2] = chBuffer[nIndx];
        pRGBABuffer[nIndx*4+3] = chBuffer[nIndx];
    }

    // If this function is getting called again for another data file.
    // Deleting and creating texture is not a good idea, 
    // we can use the glTexSubImage3D for better performance for such scenario.
    // I am not using that now :-)
    if( 0 != m_nTexId )
    {
        glDeleteTextures( 1, (GLuint*)&m_nTexId );
    }
    glGenTextures( 1, (GLuint*)&m_nTexId );

    glBindTexture( GL_TEXTURE_3D, m_nTexId );
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
    glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
    glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
    glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER );
    glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

    glTexImage3D( GL_TEXTURE_3D, 0, GL_RGBA, m_uImageWidth, m_uImageHeight, m_uImageCount, 0,
                  GL_RGBA, GL_UNSIGNED_BYTE, pRGBABuffer );
    glBindTexture( GL_TEXTURE_3D, 0 );

    delete[] chBuffer;
    delete[] pRGBABuffer;
    return true;
}

I tried to use fstream here, but it doesn't work. My code:

bool InitTextures2D( const char* filePath )
{
    std::fstream myFile;
    myFile.open( filePath, std::ios::out | std::ios::binary );

    m_uImageCount = 109;
    m_uImageWidth = 256;
    m_uImageHeight = 256;

    // Holds the texuture IDs.
    m_puTextureIDs = new int[m_uImageCount];

    // Holds the luminance buffer.
    char* chBuffer = new char[256 * 256];
    glGenTextures( m_uImageCount, (GLuint*)m_puTextureIDs );

    // Read each frames and construct the texture.
    for( int nIndx = 0; nIndx < m_uImageCount; ++nIndx )
    {
        // Read the frame.
        myFile.read(chBuffer, m_uImageWidth*m_uImageHeight);

        // Set the properties of the texture.
        glBindTexture( GL_TEXTURE_2D, m_puTextureIDs[nIndx] );
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

        glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, m_uImageWidth, m_uImageHeight, 0,
                      GL_LUMINANCE, GL_UNSIGNED_BYTE,(GLvoid *) chBuffer );
        glBindTexture( GL_TEXTURE_2D, 0 );
    }

    delete[] chBuffer;
    return true;
}
È stato utile?

Soluzione

You open the file for writing: "std::ios::out" and then read from it.. that won't work.

Change:

myFile.open(filePath, std::ios::out | std::ios::binary);

to

myFile.open(filePath, std::ios::in | std::ios::binary);

Note that if you executed the code you wrote previously it opened the file for writing. Which truncated the file and it is likely 0 bytes long now.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top