计算机图形学:我自己绘制一个三角形

时间:2017-03-10 08:36:29

标签: c++ opengl graphics

最近我用OpenGL学习计算机图形学,但我有一个问题是如果我可以在没有OpenGL,DirecX等的情况下完全绘制一些东西。 换句话说,我可以自己绘制一个三角形吗?不只是指定顶点,而是运行正确的函数。

3 个答案:

答案 0 :(得分:0)

从技术上讲,是的,您可以自己绘制三角形,而无需外部库。当然,为了做到这一点,你会发现自己复制了整个渲染管道。编写既能产生正确结果又高效又通用的渲染器远非易事。尽管如此,这对于教育目的来说可能是一件有价值的事情,但我仍然建议继续学习如何使用OpenGL(或任何其他您认为值得完成的任何其他库/框架),而不是花费数小时和数小时来尝试找出你的自制渲染器为什么会产生这个小小的人工制品。

答案 1 :(得分:-1)

当然可以。您可以要求操作系统的窗口管理器让您访问窗口的像素,并直接为窗口内的像素着色。

这是some C code在窗口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;
}

答案 2 :(得分:-1)

最后,绘制三角形只是意味着在很多像素中着色。使用当前屏幕,可能是一百万像素。

但标准的C ++练习是用字符绘制一个三角形,例如

     *
    ***
   *****
  *******

当然,您的控制台可能具有相当有限的分辨率,但基本算法可能几乎相同。快点,从上面的简单示例开始。然后,为了让自己更难,让用户输入3分x,y并将其用作角点。由于它是文字,因此您需要使用xy的较小值进行测试,但这仅仅是详细信息。