利用SDL绘制点阵字
看sdlpal源碼的時候,想了解下游戲界面上那些像素字是如何繪制顯示的,于是就去了解了下點陣字。雖然有SDL_ttf這個庫,你只需要找個字體文件,然后調用庫提供的API就可以在屏幕上顯示字體了。但是如果游戲只是顯示下簡單的像素字的話,加個SDL_ttf庫就顯得臃腫了。不管怎樣,多深入了解下又不是壞事,你還是可以使用更簡單方便的字體庫來顯示字體。
關于點陣字的一些介紹就不細講了,網上一搜一大把。我只講下用SDL繪制點陣字的過程。首先,我們要有在屏幕上顯示的漢字字模(拿1616的點陣字來說的話,字模就是一個16行2列的一個二維數組,里邊存放著十六進制數,這些十六進制數描述了這個1616矩陣中每個點是0還是1。具體是怎樣的,看后面的代碼),這個搜一下在線點陣字體生成器就有了。這里繪制一下“廖望塔”三個字,下面這張圖就是16*16的字體點陣了:
白點代表1,藍點代表0。所以它的十六進制數組是(上面的圖和下面的數組是不對應的,因為不是同一個地方生成的,把途中的點用對應的十六進制描述會對應不上…不過都差不多,懶得統一了):
有了這個數組,先不急著用SDL在屏幕上繪制,可以簡單的在終端打印出來看看效果。上代碼,很簡單:
#include <stdio.h>// 記得加上上面那個數組,這里就不重復貼了int main(int argc, char* argv[]) {// 第一層循環控制行數for (int i = 0; i < sizeof(wangtal) / sizeof(wangtal[0]); i++) {// 第二層循環控制列數for (int j = 0; j < sizeof(wangtal[0]) / sizeof(wangtal[0][0]); j++) {// 每個十六進制數有8位,遍歷這8位哪些是0,哪些是1for (int k = 0; k < 8; k++) {// wangtal[i][j]是第i行第j列的十六進制數,將其對(0x80>>k)進行8次的與運算,就可以得知當前位是0還是1if (wangtal[i][j] & (0x80 >> k)) {// 為1打印一個 * 號和一個空格printf("%c ", '*');} else {// 為0打印兩個空格printf("%c ", ' ');}}}printf("\n");}return 0; }編譯運行后的效果:
接下來就用SDL在屏幕上繪制,這就需要初始化SDL,創建一個window和一個renderer,然后根據數組,在一個surface中填充顏色,再把該surface轉成textrue,最后copy到renderer中就可以顯示了。比上面的復雜一點,不過也難不到哪去。上代碼:
#include <stdio.h> #include "wtlDisplay.h" // 該頭文件是我寫的用來初始化SDL的,這里就不給出了,不清楚的可以看下SDL的官方教程// 記得貼上開頭給的數組static SDL_Surface* gpSurface = NULL; static SDL_Texture* gpTexture = NULL;void Startup(void); void Shutdown(void); void wtlText_DrawChar(unsigned char color, int x, int y, int size);int main(int argc, char* argv[]) {SDL_bool quit = SDL_FALSE;SDL_Event event;wtlDisplay_Init();Startup();wtlText_DrawChar(0xFF, 60, 80, 9);SDL_Renderer* renderer = wtlDisplay_GetRenderer();gpTexture = SDL_CreateTextureFromSurface(renderer, gpSurface);while (!quit) {while (SDL_PollEvent(&event)) {if (event.type == SDL_QUIT) {quit = SDL_TRUE;}}//SDL_RenderClear(renderer);//SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);SDL_RenderCopy(renderer, gpTexture, NULL, NULL);SDL_RenderPresent(renderer);}wtlDisplay_Quit();Shutdown();return 0; }void Startup(void){if (NULL == gpSurface) {gpSurface = SDL_CreateRGBSurface(0, 640, 320, 32, 0, 0, 0, 0);}//printf("gpSurface pitch:%d\n", gpSurface->pitch);/*if (NULL == gpTexture) {gpTexture = SDL_CreateTexture(wtlDisplay_GetRenderer(),SDL_PIXELFORMAT_ARGB8888,SDL_TEXTUREACCESS_STREAMING,640, 320);}*/ }void Shutdown(void){if (gpSurface) {SDL_FreeSurface(gpSurface);gpSurface = NULL;}if (gpTexture) {SDL_DestroyTexture(gpTexture);gpTexture = NULL;} }// 要點就是這個函數了,寫的不是通用的,只是用來演示繪制“廖望塔”的... // color就是字體顏色了,不過有點問題,可能是SDL_FillRect或SDL_CreateTextureFromSurface改變了顏色信息,導致顏色不是我們填的那樣 // x,y就是在屏幕中的位置了,size為每個點填充多少個像素。如果每個點填充一個像素,這樣是看不到繪制出來字體的,太小了 void wtlText_DrawChar(unsigned char color, int x, int y, int size){SDL_Rect _stRect = {x, y, size, size};// 第一層循環控制行數for (int i = 0; i < sizeof(wangtal) / sizeof(wangtal[0]); i++) {// 第二層循環控制列數for (int j = 0; j < sizeof(wangtal[0]) / sizeof(wangtal[0][0]); j++) {// 每個十六進制數有8位,遍歷這8位哪些是0,哪些是1for (int k = 0; k < 8; k++) {if (wangtal[i][j] & (0x80 >> k)) {// 為1,則在gpSurface的_stRect區域填充color顏色SDL_FillRect(gpSurface, &_stRect, (Uint32)color);}// x軸位置偏移,以便進行下一個點的繪制_stRect.x += size;}}// 繪制完一行后,y軸坐標向下偏移_stRect.y += size;// x軸坐標回到初始值_stRect.x = x;} }效果圖:
一般不會手動去寫字模信息,而是從點陣字庫中讀取字模信息,這樣會方便點。內容就是這樣,不要介意代碼寫的難看…清楚內容就行了?!? )
總結
以上是生活随笔為你收集整理的利用SDL绘制点阵字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux qt 字体哪个好,QT的的字
- 下一篇: 人脸识别准确概率计算——超详细