记录一下,备忘
1.SDL2 画点参考
http://blog.csdn.net/korekara88730/article/details/70880061
2.24位bmp图片格式参考
http://wojiaolongyinong.iteye.com/blog/1896092
选择 24位bmp 的原因是 这种图片格式最简单
资源:
第一个图用于测试,第二个图片是自己用 画图板调试时用的,只有4x2大小,方便观察格式内容,开发过程中便于调试
开发过程中遇到的问题:
1.bmp 文件数据的组织排列形式(小端)
2.文件读取时的逻辑错误。最终用一个自己手绘的 4x2的小图,参照 hex 16进制编辑器 (sublime ,notepad++ 都有插件可以用,vitual studio 可以监视内存),最后解决读取时错误的内存偏移
代码:
main.cpp mp3.h mp3.cpp Application.h Application.cpp
mp3.h mp3.cpp
定义了 24位bmp 的 类,并实现了一个 读取bmp 文件的函数
Applicatoin.h Application.cpp 使用 SDL2库, 逐点绘制 24位bmp 图像
1.main.cpp
#include
#include "Application.h"
#include "mp3.h"
miaomp3::The24BitBmp bitmap;
int main()
{
//miaomp3::testmp3("res/login.mp3");
miaomp3::testmp3("res/laoshi.bmp",bitmap);
//miaomp3::testmp3("res/linshiyin.bmp",bitmap);
//miaomp3::testmp3("res/ceshi.bmp", bitmap);
Application app;
app.initialize(bitmap.width, bitmap.height);
//app.initialize(95,95);
app.mainLoop();
return 0;
}
mp3.h
#ifndef __MP3_H__
#define __MP3_H__
#include
namespace miaomp3
{
/*
addr 地址
bytes 多少字节 (每个字节是8位)
*/
int getDecimal(char* addr, int bytes);
class The24BitBmp
{
public:
~The24BitBmp()
{
delete[] data;
data = nullptr;
}
long fileSize;
long dataOffset;
int width;
int height;
char* data;
int fillZeroPerLine;
int sizePerLine;
unsigned char getRAt(int x, int y);
unsigned char getGAt(int x, int y);
unsigned char getBAt(int x, int y);
char* getAddrAt(int x, int y);
};
void testmp3(std::string filePath, The24BitBmp& bitmap);
}
#endif //__MP3_H__
#include "mp3.h"
#include
namespace miaomp3
{
unsigned char The24BitBmp::getRAt(int x, int y)
{
char* addr = getAddrAt(x, y);
char col = addr[2];
return col;
}
unsigned char The24BitBmp::getGAt(int x, int y)
{
char* addr = getAddrAt(x, y);
char col = addr[1];
return col;
}
unsigned char The24BitBmp::getBAt(int x, int y)
{
char* addr = getAddrAt(x, y);
char col = addr[0];
return col;
}
char* The24BitBmp::getAddrAt(int x, int y)
{
long offset = sizePerLine * y + x * 3;
return this->data + offset;
}
long fileSize(FILE* fp)
{
fseek(fp, 0L, SEEK_END);
long pos = ftell(fp);
fseek(fp,0L,SEEK_SET);
return pos;
}
/*
addr 地址
bytes 多少字节 (每个字节是8位)
*/
int getDecimal(char* addr,int bytes)
{
int ret = 0;
assert(bytes%2 == 0);
for (int index = 0; index < bytes;index++)
{
int base = addr[index];
int pownum = index * 2;
int inc = base * pow(16, pownum);
//printf("base:%d,pownum:%d,inc:%d\n",base,pownum,inc);
ret += inc;
}
return ret;
}
void testmp3(std::string file,The24BitBmp& bitmap)
{
FILE* fp = fopen(file.c_str(), "rb");
if (fp == nullptr) return;
long size = fileSize(fp);
char* fd = new char[size];
for (long index = 0; index < size;index++)
{
fd[index] = 0;
}
fread(fd, size,1, fp);
fclose(fp);
bitmap.dataOffset = getDecimal(fd + 10, 4);
bitmap.fileSize = getDecimal(fd + 2, 4);
bitmap.width = getDecimal(fd + 18, 4);
bitmap.height = getDecimal(fd + 22, 4);
long dataSize = bitmap.fileSize - bitmap.dataOffset;
bitmap.data = new char[dataSize]();
memcpy(bitmap.data, fd + bitmap.dataOffset, dataSize);
int shouldBytesPerLine = bitmap.width * 3;
bitmap.fillZeroPerLine = 0;
if (shouldBytesPerLine %4 != 0)
{
printf("123");
}
bitmap.sizePerLine = shouldBytesPerLine + bitmap.fillZeroPerLine;
delete[] fd;
}
}
#ifndef __APPLICATION_H__
#define __APPLICATION_H__
#include "SDL.h"
#include
class Application
{
public:
Application();
virtual ~Application();
public:
bool initialize(int screenWidth,int screenHeight);
void mainLoop();
void cleanup();
private:
SDL_Window* _pWindow;
SDL_Surface* _pScreenSurface;
SDL_Renderer* _pRenderer;
int _screenWidth, _screenHeight;
private:
void startGame();
void showMainMenu();
void restartGame();
};
#endif //__APPLICATION_H__
#include "Application.h"
#include
#include
#include "mp3.h"
const int SCALE_FACTOR = 1;
//const int SCALE_FACTOR = 200;
Application::Application()
: _pWindow(nullptr)
, _pScreenSurface(nullptr)
, _pRenderer(nullptr)
, _screenWidth(100)
, _screenHeight(100)
{
}
Application::~Application()
{
cleanup();
}
bool Application::initialize(int screenWidth, int screenHeight)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL can not initialized!SDL Error:%s\n", SDL_GetError());
return false;
}
_screenWidth = screenWidth * SCALE_FACTOR;
_screenHeight = screenHeight * SCALE_FACTOR;
_pWindow = SDL_CreateWindow("msdl1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _screenWidth, _screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
//_pWindow = SDL_CreateWindow("msdl1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _screenWidth, _screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN);
if (_pWindow == nullptr)
{
printf("SDL can't create window!SDL Error:%s\n", SDL_GetError());
return false;
}
int w, h;
SDL_GetWindowSize(_pWindow, &w, &h);
printf("Viewport Size: %d,%d\n",w,h);
_pScreenSurface = SDL_GetWindowSurface(_pWindow);
_pRenderer = SDL_CreateRenderer(_pWindow, -1, SDL_RENDERER_ACCELERATED);
if (_pRenderer == nullptr)
{
return false;
}
SDL_FillRect(_pScreenSurface, nullptr, SDL_MapRGBA(_pScreenSurface->format, 0, 0, 0, 0));
return true;
}
void Application::cleanup()
{
SDL_DestroyRenderer(_pRenderer);
SDL_DestroyWindow(_pWindow);
SDL_Quit();
}
void Application::mainLoop()
{
bool quit = false;
SDL_Event evt;
while (!quit)
{
while (SDL_PollEvent(&evt) != 0)
{
if (evt.type == SDL_QUIT){
quit = true;
}
}
{
SDL_SetRenderDrawColor(_pRenderer, (Uint8)255, (Uint8)255, (Uint8)255, 0xff);
SDL_RenderClear(_pRenderer);
SDL_SetRenderDrawColor(_pRenderer, 0x00, 0x00, 0x00, 0xff);
SDL_Rect fillRect = { 0, 0, _screenWidth, _screenHeight };
SDL_RenderFillRect(_pRenderer, &fillRect);
}
for (int row = 0; row < _screenHeight; row++)
{
for (int col = 0; col < _screenWidth; col++)
{
/*
int r = rand() / 100 % 256;
int g = rand() / 100 % 256;
int b = rand() / 100 % 256;
*/
extern miaomp3::The24BitBmp bitmap;
int x = col/SCALE_FACTOR;
int y = row/SCALE_FACTOR;
y = bitmap.height - y - 1;
Uint8 r, g, b;
r = (Uint8)bitmap.getRAt(x, y);
g = (Uint8)bitmap.getGAt(x,y);
b = (Uint8)bitmap.getBAt(x,y);
//printf("(%d,%d):[%d,%d,%d]\n",x,y,r,g,b);
SDL_SetRenderDrawColor(_pRenderer, r, g, b, 0xff);
SDL_RenderDrawPoint(_pRenderer, col, row);
}
}
SDL_RenderPresent(_pRenderer);
}
}
void Application::startGame()
{
}
void Application::showMainMenu()
{
}
void Application::restartGame()
{
}