最近我正在研究使用OpenGL的计算机图形,但是我有一个问题是,如果我可以完全没有OpenGL,DireCX,等等。换句话说,我可以自己画一个三角形吗?不仅指定顶点,然后运行正确的功能。
从技术上讲,是的,您可以自己绘制一个三角形,而无需外部库。当然,为了做到这一点,您会发现自己复制了整个渲染管道。编写一个既可产生正确效果又高效且通用的渲染器远非一件容易的事。尽管如此,这可能是为了教育目的而言,这可能是一件有价值的事情,但是我仍然建议继续学习如何使用OpenGL(或您认为值得完成任务的任何其他图书馆/框架),而不是花几个小时来尝试找出为什么您的自制渲染器会产生这个小伪像。
当然可以。您可以要求操作系统的窗口管理器让您访问窗口的像素,并直接为窗口窗格内部的像素上色。
这是一些C代码,在窗口Xresxyres中绘制25000(NPTS)随机黑色像素,用'gcc -lx11 -o x1 x1.c'编译,用'./x1&'执行
//----- x1.c simple xwindows example -----
#include <X11/Xlib.h> // must precede most other headers!
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
void update_screen();
int XRES=500;
int YRES=500;
int NPTS=25000;
//Need this array if we're plotting all at once using XDrawPoints
//XPoint pts[NPTS];
Display *dsp;
Window win;
GC gc;
int main(){
dsp = XOpenDisplay( NULL );
if( !dsp ){ return 1; }
int screen = DefaultScreen(dsp);
unsigned int white = WhitePixel(dsp,screen);
unsigned int black = BlackPixel(dsp,screen);
win = XCreateSimpleWindow(dsp,
DefaultRootWindow(dsp),
0, 0, // origin
XRES, YRES, // size
0, black, // border width/clr
white); // backgrd clr
Atom wmDelete=XInternAtom(dsp, "WM_DELETE_WINDOW", True);
XSetWMProtocols(dsp, win, &wmDelete, 1);
gc = XCreateGC(dsp, win,
0, // mask of values
NULL); // array of values
XSetForeground(dsp, gc, black);
XEvent evt;
long eventMask = StructureNotifyMask;
eventMask |= ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask;
XSelectInput(dsp, win, eventMask);
KeyCode keyQ;
keyQ = XKeysymToKeycode(dsp, XStringToKeysym("Q"));
XMapWindow(dsp, win);
// wait until window appears
do { XNextEvent(dsp,&evt); } while (evt.type != MapNotify);
srand(time(0)); // only 1 sec resolution so use once per run
update_screen();
int loop = 1;
while (loop) {
// for repeated fine seeding use:
// struct timeval ti
// gettimeofday(&ti,NULL);
// srand((ti.tv_sec * 1000) + (ti.tv_usec / 1000));
XNextEvent(dsp, &evt);
switch (evt.type) {
case (ButtonRelease) :
update_screen();
break;
case (KeyRelease) :
if (evt.xkey.keycode == keyQ) loop = 0;
else update_screen();
break;
case (ConfigureNotify) :
// Check if window has been resized
if (evt.xconfigure.width != XRES || evt.xconfigure.height != YRES)
{
XRES = evt.xconfigure.width;
YRES = evt.xconfigure.height;
update_screen();
}
break;
case (ClientMessage) :
if (evt.xclient.data.l[0] == wmDelete) loop = 0;
break;
default :
break;
}
}
XDestroyWindow(dsp, win);
XCloseDisplay(dsp);
return 0;
}
void update_screen()
{
XClearWindow(dsp, win);
XDrawLine(dsp, win, gc, 0, YRES/2, XRES-1, YRES/2); //from-to
XDrawLine(dsp, win, gc, XRES/2, 0, XRES/2, YRES-1); //from-to
long i;
for (i=0; i<NPTS; i++) {
XDrawPoint(dsp, win, gc, rand()%XRES, rand()%YRES);
//pts[i].x = rand()%XRES;
//pts[i].y = rand()%YRES;
}
//XClearWindow(dsp,win);
//XDrawPoints(dsp, win, gc, pts, NPTS, CoordModeOrigin);
return;
}
最后,绘制三角形只是在许多像素中涂色。使用当前屏幕,可能是一百万像素。
,但是标准的C 练习是用字符绘制三角形,例如
*
***
*****
*******
当然,您的控制台的分辨率可能相当有限,但是基本算法可能几乎相同。请开始,然后从上面的简单示例开始。然后,为了使自己更难,让用户输入3点x,y
并将其用作角点。由于是文本,因此您要使用x
和y
值的少量测试,但这只是详细信息。