㈠ C語言如何畫圖
framebuffer(幀緩沖)。
幀的最低數量為24(人肉眼可見)(低於24則感覺到畫面不流暢)。
顯卡與幀的關系:由cpu調節其數據傳輸速率來輸出其三基色的配比。
三基色:RGB(紅綠藍)。
在沒有桌面和圖形文件的系統界面,可以通過C語言的編程來實現在黑色背景上畫圖!
用下面的代碼,在需要的地方(有注釋)適當修改,就能畫出自己喜歡的圖形!
PS:同樣要編譯運行後才能出效果。
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <stdlib.h>
#define RGB888(r,g,b) ((r & 0xff) <<16 | (g & 0xff) << 8 | (b & 0xff))
#define RGB565(r,g,b) ((r & 0x1f) <<11 | (g & 0x3f) << 5 | (b & 0x1f))
int main()
{
int fd = open("/dev/fb0", O_RDWR);
if(fd < 0){
perror("open err. ");
exit(EXIT_FAILURE);
printf("xres: %d ", info.xres);
printf("yres: %d ", info.yres);
printf("bits_per_pixel: %d ", info.bits_per_pixel);
size_t len = info.xres*info.yres*info.bits_per_pixel >> 3;
unsigned long* addr = NULL;
addr = mmap(NULL, len, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
if(addr == (void*)-1){
perror("mmap err. ");
㈡ 怎麼用C畫圖
在C語言中畫圖,可以使用Turbo C提供的繪圖函數,或者在Visual C++中通過手動添加繪圖函數庫來實現。
在Turbo C中繪圖: 使用line函數:該函數用於繪制一條從點到點的直線。通過指定起點和終點的坐標,可以在屏幕上繪制出直線。 使用lineto函數:該函數從當前游標位置繪制一條直線到指定的點。這允許從當前位置開始繪制直線,而無需指定起點。 使用linerel函數:該函數從當前游標位置繪制一條直線,終點的位置由相對於當前位置的增量dx和dy確定。這提供了基於相對位置的繪圖能力。 使用circle函數:該函數用於繪制一個完整的圓,圓心坐標為,半徑為radius。通過指定圓心和半徑,可以在屏幕上繪制出圓形。 使用arc函數:該函數用於繪制一段圓弧線,圓心坐標為,半徑為radius,從指定角度stangle開始,到指定角度endangle結束。這允許繪制圓的一部分,而不是整個圓。
在Visual C++中繪圖: 由於Visual C++並未內置上述繪圖函數及相關的頭文件,因此需要手動添加。 首先,下載並鏈接包含繪圖函數的頭文件和實現代碼,如DrawingFunctions.h和DrawingFunctions.cpp。 將這兩個文件添加到VC工程中,確保它們被正確編譯和鏈接。 在工程的鏈接器設置中,添加DrawingFunctions.lib作為附加依賴項。 通過這些步驟,就可以在VC中使用與Turbo C類似的繪圖函數來繪制圖形了。
請注意,具體的繪圖函數和用法可能因環境和庫的不同而有所差異。在實際應用中,應根據所選的開發環境和庫文檔進行相應的調整和優化。
㈢ 求一用C語言畫直線的程序
不調用畫圖 API,用C 或 C++ 如何實現畫一條線?
Milo Yip:如何開始用 C++ 寫一個光柵化渲染器?
我嘗試用不同技術實現畫直線的方法(完整源代碼在 miloyip/line),此文簡單介紹個中思路。本文的代碼採用 C 語言、標准庫及極簡的 PNG 編碼函數 svpng(),沒有使用其他 API。
1. Bresenham 演算法
Bresenham直線演算法 [1] 是最簡單的直線光柵化(rasterization)演算法。
Bresenham 直線
如果像上圖,直線的高度小於寬度,那麼 Bresenham 直線演算法會為 軸每個坐標填入一個像素,繪畫每個像素時按斜率判斷 是否需要調整。整個演算法可以避開浮點數運算,只用整數運算實現。以下是一個簡單實現:
// Modified from https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
void bresenham(int x0, int y0, int x1, int y1) {
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = (dx > dy ? dx : -dy) / 2;
while (setpixel(x0, y0), x0 != x1 || y0 != y1) {
int e2 = err;
if (e2 > -dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
為了測試不同角度,我做了一個測試用例:
int main() {
memset(img, 255, sizeof(img));
float cx = w * 0.5f - 0.5f, cy = h * 0.5f - 0.5f;
for (int j = 0; j < 5; j++) {
float r1 = fminf(W, H) * (j + 0.5f) * 0.085f;
float r2 = fminf(W, H) * (j + 1.5f) * 0.085f;
float t = j * PI / 64.0f;
for (int i = 1; i <= 64; i++, t += 2.0f * PI / 64.0f) {
float ct = cosf(t), st = sinf(t);
bresenham((int)(cx + r1 * ct), (int)(cy - r1 * st), (int)(cx + r2 * ct), (int)(cy - r2 * st));
}
}
svpng(fopen("line_bresenham.png", "wb"), W, H, img, 0);
}
完整代碼 line_bresenham.c
渲染結果及中間局部放大:
2. 采樣方法
Bresenham 直線演算法有 3 個問題:
不能控制直線寬度;
坐標為整數;
只能對像素寫入一個顏色,只用單色會有嚴重的鋸齒效果。
在圖形學中,除了以逐個圖元(如直線)方式渲染,我們還可以通過對每個像素進行采樣(sampling),換句話說,我們可對整個圖像逐像素詢問:「這個像素的顏色是什麼?」
用采樣方式畫直線時,我們可以用一個具有面積的形狀去表示「直線」,例如是長方形。但在本文中,我們使用膠囊體(capsule)去表示直線。這樣就能解決上面前兩個問題:(1) 可用膠囊體半徑設置直線的寬度;(2) 坐標可以為浮點數。不過,用最簡單的采樣方式,我們需要在每像素查詢所有圖元是否佔有該像素,效率很低。