⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap.cpp

📁 小型的3D游戏引擎
💻 CPP
字号:
#include <fstream>
#include <windows.h>
#include <gl/gl.h>
#include "bitmap.h"
using namespace std;


///////////////////////////////////////////////////////////////////////////////////

GcBitmap::GcBitmap():
bitmapImage(NULL)
{
	// The bitmap has been constructed
}

///////////////////////////////////////////////////////////////////////////////////

GcBitmap::~GcBitmap()
{
	// Free memory
	Destroy();
}

///////////////////////////////////////////////////////////////////////////////////

bool GcBitmap::Load(char *fileName)
{
	
	// Open filename in "read binary" mode
	ifstream file(fileName, ios::in | ios::binary);

	// Check to see if the file has been opened corectly
	if(!file) {
		MessageBox(NULL, "Can't find bitmap file", "Error", MB_OK);
		return false;
	}

	// Read the bitmap file header
	file.read((char*)&bitmapFileHeader, sizeof(BITMAPFILEHEADER));

	// Check to see that this is a bitmap
	if(bitmapFileHeader.bfType != 0x4D42) 
	{
		MessageBox(NULL, "File isn't a bitmap", "Error", MB_OK);
		file.close();
		return false;
	}
		      
	// Read the bitmap information header
	file.read((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));

	// Move file pointer to beginning of bitmap data
	file.seekg(bitmapFileHeader.bfOffBits, ios::beg);

	// Check to make sure that the biSizeImage isn't empty (which it is if it's a Photoshop bitmap)
	if(bitmapInfoHeader.biSizeImage == 0) {
		bitmapInfoHeader.biSizeImage = (int)bitmapInfoHeader.biWidth * bitmapInfoHeader.biHeight * (bitmapInfoHeader.biBitCount / 8);
	}

	// Allocate memmory for the image data
	bitmapImage = new byte[bitmapInfoHeader.biSizeImage];

	// Check memmory allocation
	if(!bitmapImage) 
	{
		MessageBox(NULL, "Failed to allocate memmory for the bitmap", "Error", MB_OK);
		delete [] bitmapImage;
		bitmapImage = NULL;
		file.close();
		return false;
	}

	// Read the bitmap image data
	file.read((char*)bitmapImage, bitmapInfoHeader.biSizeImage);

	// Check to see if this is a BGR bitmap, in that case swap to RGB
	if(bitmapInfoHeader.biBitCount != 8) 
	{
		// Swap the R and B valuse to get RGB from BGR
		for(int i = 0; i < (int)bitmapInfoHeader.biSizeImage; i += 3)
		{
			tempRGB = bitmapImage[i];
			bitmapImage[i] = bitmapImage[i + 2];
			bitmapImage[i + 2] = tempRGB;
		}
	}

	// Close the file
	file.close();

	return true;
}

///////////////////////////////////////////////////////////////////////////////////

bool GcBitmap::Write(char *fileName, uint width, uint height, uint screenBpp)
{
	/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */

	// Open file for writing binary mode
	ofstream file(fileName, ios::out | ios::binary);

	// Check if opened
	if(!file) {
		return false;
	}

	// Define the bitmap file header
	bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
	bitmapFileHeader.bfType = 0x4D42;
	bitmapFileHeader.bfReserved1 = 0;
	bitmapFileHeader.bfReserved2 = 0;
	bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	// Define the bitmap inforamtion header
	bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmapInfoHeader.biPlanes = 1;
	bitmapInfoHeader.biBitCount = 24;
	bitmapInfoHeader.biCompression = BI_RGB;
	bitmapInfoHeader.biSizeImage = width * abs(height) * 3;
	bitmapInfoHeader.biXPelsPerMeter = 0;
	bitmapInfoHeader.biYPelsPerMeter = 0;
	bitmapInfoHeader.biClrUsed = 0;
	bitmapInfoHeader.biClrImportant = 0;
	bitmapInfoHeader.biWidth = width;
	bitmapInfoHeader.biHeight = height;

	// Switch the image data from RGB to BGR
	for(int i = 0; i < (int)bitmapInfoHeader.biSizeImage; i += 3)
	{
		tempRGB = bitmapImage[i];
		bitmapImage[i] = bitmapImage[i + 2];
		bitmapImage[i +2] = tempRGB;
	}

	// Write the bitmap file header
	file.write((char*)&bitmapFileHeader, sizeof(BITMAPFILEHEADER));

	// Write the bitmap info header
	file.write((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));

	// Write the image data
	file.write((char*)bitmapImage, bitmapInfoHeader.biSizeImage);

	// Save the color mode
	colorMode = bitmapInfoHeader.biBitCount / 8;

	// Close the file
	file.close();

	return true;
}

///////////////////////////////////////////////////////////////////////////////////

void GcBitmap::Screenshot(char *fileName, uint winWidth, uint winHeight, uint screenBpp)
{
	/* WARNING! DO NOT USE THIS IF THE BITMAP ARE TO BE USED FURTHER ON */

	// Make sure that there's no memory allocated
	if(bitmapImage != NULL) {
		delete [] bitmapImage;
		bitmapImage = NULL;
	}

	// Allocate memmory for the screenshot
	bitmapImage = new byte[winWidth*winHeight*3];

	// Clear the memmory
	memset(bitmapImage, 0, winWidth * winHeight * 3);

	// Read the image data from the window
	glReadPixels(0, 0, winWidth - 1, winHeight - 1, GL_RGB, GL_UNSIGNED_BYTE, bitmapImage);

	// Write the image data to a file
	Write(fileName, winWidth, winHeight);

	// Free the image memory
	delete [] bitmapImage;
	bitmapImage = NULL;
}

///////////////////////////////////////////////////////////////////////////////////

void GcBitmap::Draw(uint xPos, uint yPos)
{
	// Bind a null texture to "disable texturing
	glBindTexture(GL_TEXTURE_2D, NULL);

	// Set the correct drwaings
	glPixelStorei(GL_UNPACK_ALIGNMENT, colorMode);

	// Set the correct position
	glRasterPos2i(xPos, yPos);

	// Draw the bitmap to the screen
	glDrawPixels(bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 
				 colorMode, GL_UNSIGNED_BYTE, bitmapImage);
				 
}

///////////////////////////////////////////////////////////////////////////////////

void GcBitmap::Destroy()
{ 
	if(bitmapImage != NULL) {
		delete [] bitmapImage; 
		bitmapImage = NULL; 
	} 
}

///////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -