日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用SDL绘制点阵字

發布時間:2023/12/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用SDL绘制点阵字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

看sdlpal源碼的時候,想了解下游戲界面上那些像素字是如何繪制顯示的,于是就去了解了下點陣字。雖然有SDL_ttf這個庫,你只需要找個字體文件,然后調用庫提供的API就可以在屏幕上顯示字體了。但是如果游戲只是顯示下簡單的像素字的話,加個SDL_ttf庫就顯得臃腫了。不管怎樣,多深入了解下又不是壞事,你還是可以使用更簡單方便的字體庫來顯示字體。
關于點陣字的一些介紹就不細講了,網上一搜一大把。我只講下用SDL繪制點陣字的過程。首先,我們要有在屏幕上顯示的漢字字模(拿1616的點陣字來說的話,字模就是一個16行2列的一個二維數組,里邊存放著十六進制數,這些十六進制數描述了這個1616矩陣中每個點是0還是1。具體是怎樣的,看后面的代碼),這個搜一下在線點陣字體生成器就有了。這里繪制一下“廖望塔”三個字,下面這張圖就是16*16的字體點陣了:

白點代表1,藍點代表0。所以它的十六進制數組是(上面的圖和下面的數組是不對應的,因為不是同一個地方生成的,把途中的點用對應的十六進制描述會對應不上…不過都差不多,懶得統一了):

// 這里直接把三個字的字模寫在一個16行6列的數組里了,也可以單獨用3個16* 6的數組存放 const unsigned char wangtal[][6] = {// 十六進制下,2位為一個字節,二進制下8位為一個字節.所以16個點需要兩個2位十六進制表示//  廖   | 望 | 塔{0x00, 0x80, 0x10, 0x04, 0x21, 0x10},{0x3F, 0xFC, 0x0A, 0x7E, 0x21, 0x10},{0x20, 0x00, 0xFF, 0x44, 0x27, 0xFC},{0x3F, 0x78, 0x20, 0x7C, 0x21, 0x10},{0x29, 0x48, 0x20, 0x44, 0x20, 0x40},{0x25, 0x28, 0x26, 0x7C, 0xF8, 0xA0},{0x29, 0xC8, 0x38, 0x44, 0x21, 0x10},{0x23, 0x60, 0x20, 0x8C, 0x22, 0x0E},{0x2C, 0x5E, 0x00, 0x00, 0x2D, 0xF4},{0x31, 0x84, 0x3F, 0xF8, 0x20, 0x08},{0x26, 0x40, 0x01, 0x00, 0x23, 0xFC},{0x21, 0x90, 0x1F, 0xF0, 0x3A, 0x08},{0x46, 0x20, 0x01, 0x00, 0xE2, 0x08},{0x40, 0xC0, 0x01, 0x04, 0x42, 0x08},{0x83, 0x00, 0xFF, 0xFE, 0x03, 0xf8},{0x0C, 0x00, 0x00, 0x00, 0x02, 0x08} };

有了這個數組,先不急著用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绘制点阵字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。