Texture Coordinates problem

Started by
1 comment, last by Great_White 17 years, 5 months ago
Hi I'am writing an image class for loading some graphics files. But I came across a strange problem. When reading bitmap file's pixel data (from last scan line to first) the texture coordinates are reversed. Here is my code for bimap loading:

bool Image::LoadBMP(string filename)
{
	// Declare bitmap info & file headers
	BITMAPFILEHEADER  bfh;
	BITMAPINFOHEADER  bih;

	// Open the bitmap file
	ifstream bmp_file(filename.c_str(), ios::binary);

	// Check the filename
	if(!bmp_file)
	{	
		bmp_file.close();		
		MessageBox(0, "Unable to load TGA File!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	// Read the file header
	if(!bmp_file.read( reinterpret_cast<char*>(&bfh), sizeof(BITMAPFILEHEADER)))
	{
		bmp_file.close();
		MessageBox(0, "Unable to read BMP File Header!", "Read Error", MB_OK | MB_ICONERROR);
		return false;
	}

	// Check the bmp format
	if( memcmp(&bfh.bfType, "BM", 2 ) )
	{
		bmp_file.close();
		MessageBox(0, "BMP type not match !", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	// Read the info header
	if( !bmp_file.read(reinterpret_cast<char*>(&bih), sizeof(BITMAPINFOHEADER) ))
	{
		bmp_file.close();
		MessageBox(0, "Unable to read BMP info header!", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	// Write bit per pixel, bmp width and height
	this->m_iBpp	= bih.biBitCount;
	
	// Check the height value to ensure it is positive
	// Since, if height < 0 , bitmap is top-down.  
	this->m_iHeight = bih.biHeight<0 ? -bih.biHeight<0 : bih.biHeight;
	this->m_iWidth	= bih.biWidth;
	this->m_iStride = this->m_iWidth * this->m_iBpp/8;
	
	// Set format and internal format 
	if(m_iBpp == 24)
	{
			SetFormat(GL_RGB);
			SetInternalFormat(GL_RGB8);
	}
	else if(m_iBpp==32)
	{
			SetFormat(GL_RGBA);
			SetInternalFormat(GL_RGBA8);
	}
	else if(m_iBpp==8)
	{
			SetFormat(GL_RGB);
			SetInternalFormat(GL_RGB8);
	}

	// Calculate the padding at the end of the bitmap
	int padding = (4 - ( m_iStride % 4 ))%4;
			
	// Handle each Bmp (8, 24 & 32 channels) seperately
	switch(m_iBpp)
	{
		
		case 8:
		{
			
			// Allocate enough memory for palette index data
			try
			{
	   
				m_pData = new BYTE[m_iStride* m_iHeight*3];
			}
			catch (bad_alloc &ba)
			{
				MessageBox(0, "Allocation failed for Bitmap Image !", "Error", MB_OK | MB_ICONERROR);
				return false;
			}
						
			// Calculate palette size
			int palette_size = 1 << m_iBpp;
						
			// Create a palette for 8 bit bmp image
			RGBQUAD *pPalette = new RGBQUAD[palette_size*3];
			bmp_file.read ( (char*)pPalette, sizeof(RGBQUAD)*(palette_size*3)); 

			// Set the file pointer to from the beginning of the file to the beginning of the palette indices
			bmp_file.seekg( bfh.bfOffBits, ios::beg);
			
			// Create an palette index array
			BYTE *pIndices = new BYTE[m_iStride*m_iHeight];
						
			// Start reading indices to palette index array
			// Note here that we start reading from the last row since bitmaps are bottom-up
			for( int j=0;j<m_iHeight;j++)
			{
				bmp_file.read( (char*)(pIndices+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}
								
			// Close the file stream
			bmp_file.close();
			
			// Copy pixels from palette to real data buffer 
			for(int y=0; y<m_iHeight; y++)
			{
				for(int x=0; x<m_iWidth; x++)
				{
					m_pData[(y*m_iWidth+x)*3+0]=pPalette[pIndices[y*m_iWidth+x]].rgbRed;    // R 
					m_pData[(y*m_iWidth+x)*3+1]=pPalette[pIndices[y*m_iWidth+x]].rgbGreen;  // G
					m_pData[(y*m_iWidth+x)*3+2]=pPalette[pIndices[y*m_iWidth+x]].rgbBlue;   // B
				}
			}
			
			// Delete index array & palette 		
			delete []pPalette;
			delete []pIndices;
			
			//Quit						
			break;

		}
		
		case 24 :
		{
			// Allocate enough memory for pixel data
			try
			{
	   
				m_pData = new BYTE[m_iStride* m_iHeight];
			}
			catch (bad_alloc &ba)
			{
				MessageBox(0, "Allocation failed for Bitmap Image !", "Error", MB_OK | MB_ICONERROR);
				return false;
			}
						
			// Set the file pointer to from the beginning of the file to the beginning of the pixel data
			bmp_file.seekg( bfh.bfOffBits, ios::beg);
			
			// Start Reading the the pixel data
			// Note here that we start reading from the last row since bitmaps are bottom-up
			/*
			for( int j=m_iHeight-1; j>=0; j--)
			{
				bmp_file.read( (char*)(m_pData+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}
			*/
			
			for( int j=0;j<m_iHeight; j++)
			{
				bmp_file.read( (char*)(m_pData+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}
			
			
			// Close the file
			bmp_file.close();

			// Correct the order of BGR to RBG
			// Note : Instead of using a temp value for swapping we are using XOR'ing
			// Since binary operations are faster
			for (int i = 0; i < m_iStride*m_iHeight; i += 3)
			{
				/*
				BYTE tempRGB = m_pData;
				m_pData  = m_pData ;
				m_pData  = tempRGB;
				*/</span>

				m_pData<span style="font-weight:bold;"> ^= m_pData[i+<span class="cpp-number">2</span>] ^= m_pData<span style="font-weight:bold;"> ^= m_pData[i+<span class="cpp-number">2</span>];
			}

			<span class="cpp-keyword">break</span>;
		}

		<span class="cpp-keyword">case</span> <span class="cpp-number">32</span>:
		{
			
			<span class="cpp-comment">// Allocate enough memory for pixel data</span>
			<span class="cpp-keyword">try</span>
			{
	   
				m_pData = <span class="cpp-keyword">new</span> BYTE[m_iStride* m_iHeight];
			}
			<span class="cpp-keyword">catch</span> (bad_alloc &amp;ba)
			{
				MessageBox(<span class="cpp-number">0</span>, <span class="cpp-literal">"Allocation failed for Bitmap Image !"</span>, <span class="cpp-literal">"Error"</span>, MB_OK | MB_ICONERROR);
				<span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;
			}
			
			<span class="cpp-comment">// Set the file pointer to from the beginning of the file to the beginning of the pixel data</span>
			bmp_file.seekg( bfh.bfOffBits, ios::beg);
			
			<span class="cpp-comment">// Start Reading the the pixel data</span>
			<span class="cpp-comment">// Note here that we start reading from the last row since bitmaps are bottom-up</span>
			<span class="cpp-keyword">for</span>( <span class="cpp-keyword">int</span> j=<span class="cpp-number">0</span>;j&lt;m_iHeight;j++)
			{
				bmp_file.read( (<span class="cpp-keyword">char</span>*)(m_pData+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}
			
			<span class="cpp-comment">// Close the file</span>
			bmp_file.close();

			<span class="cpp-comment">// Correct the order of BGR to RBG</span>
			<span class="cpp-comment">// Note : Instead of using a temp value for swapping we are using XOR'ing</span>
			<span class="cpp-comment">// Since binary operations are faster</span>
			<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-number">0</span>; i &lt; m_iStride*m_iHeight; i += <span class="cpp-number">4</span>)
			{
				<span class="cpp-comment">/*
				BYTE tempRGB = m_pData<span style="font-weight:bold;">;
				m_pData  = m_pData ;
				m_pData  = tempRGB;
				*/</span>
				m_pData<span style="font-weight:bold;"> ^= m_pData[i+<span class="cpp-number">2</span>] ^= m_pData<span style="font-weight:bold;"> ^= m_pData[i+<span class="cpp-number">2</span>];
			}

			<span class="cpp-keyword">break</span>;
								
		}

		<span class="cpp-keyword">default</span>:
		{	
			MessageBox(<span class="cpp-number">0</span>, <span class="cpp-literal">"Unknown BMP Format"</span>, <span class="cpp-literal">"Error"</span>, MB_OK | MB_ICONERROR);
			<span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;
			<span class="cpp-keyword">break</span>;
		}
	 }


	<span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;


}


</pre></div><!–ENDSCRIPT–> 

In the following block of the code I try to read the bitmap from the last row since bitmaps are bottom-up:

<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre>
<span class="cpp-comment">// Start Reading the the pixel data</span>
			<span class="cpp-comment">// Note here that we start reading from the last row since bitmaps are bottom-up</span>
			<span class="cpp-comment">/*
			for( int j=m_iHeight-1; j&gt;=0; j–)
			{
				bmp_file.read( (char*)(m_pData+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}
			*/</span>
			
			<span class="cpp-keyword">for</span>( <span class="cpp-keyword">int</span> j=<span class="cpp-number">0</span>;j&lt;m_iHeight; j++)
			{
				bmp_file.read( (<span class="cpp-keyword">char</span>*)(m_pData+j*m_iStride), m_iStride);
				bmp_file.seekg( padding, ios::cur);
			}


</pre></div><!–ENDSCRIPT–>

But the Texture coordinates are reversed. Any idea about this issue?
"A human being is a part of a whole, called by us,universe, a part limited in time and space. He experiences himself, his thoughts and feelings as something separated from the rest... a kind of optical delusion of his consciousness. This delusion is a kind of prison for us, restricting us to our personal desires and to affection for a few persons nearest to us. Our task must be to free ourselves from this prison by widening our circle of compassion to embrace all living creatures and the whole of nature in its beauty."A. Einstein
Advertisement
Images in OpenGL are expected to be passed bottom up, so you don't have to flip the bitmaps cause they are already in the orientation OpenGL expects. If you flip it, texture coordinates must be flipped accordingly or the texturing will be wrong.
Ooh I didnt know that thank you for your answer.
"A human being is a part of a whole, called by us,universe, a part limited in time and space. He experiences himself, his thoughts and feelings as something separated from the rest... a kind of optical delusion of his consciousness. This delusion is a kind of prison for us, restricting us to our personal desires and to affection for a few persons nearest to us. Our task must be to free ourselves from this prison by widening our circle of compassion to embrace all living creatures and the whole of nature in its beauty."A. Einstein

This topic is closed to new replies.

Advertisement