主题:[原创]OpenGL入门学习——写给想用计算机画图的朋友
eastcowboy
[专家分:25370] 发布于 2006-07-30 14:09:00
说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧?
但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。
[color=0000FF]本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物。[/color]
OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。
[color=FF0000]1、与C语言紧密结合[/color]。
OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,[color=0000FF]使用OpenGL作图甚至比TC更加简单[/color]。
[color=FF0000]2、强大的可移植性[/color]。
微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL的基本命令都做到了硬件无关,甚至是平台无关。
[color=FF0000]3、高性能的图形渲染[/color]。
OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。
总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。
OpenGL官方网站(英文)
[color=0000FF]http://www.opengl.org[/color]
下面我将对Windows下的OpenGL编程进行简单介绍。
=====================未完,请勿跟帖=====================
回复列表 (共70个回复)
51 楼
conqest [专家分:0] 发布于 2007-05-05 10:55:00
请问楼主,为什么不能正确显示出图形
此程序是用Bresenham算法来画直线,我把组成直线的点储存在一个线性链表中,画点的时候调用这个链表。
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <conio.h>
#include <time.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//定义链表节点
typedef struct LNode{
GLshort x;要画的点的横坐标
GLshort y;要画的点的竖坐标
struct LNode* next;
}LNode, *LinkList;
LinkList L,p;
//链表初始化
int CreateList_L()
{
L=(LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}
//Bresenham算法
void Bresenham_Line(GLshort x1,GLshort y1,GLshort x2,GLshort y2)
{
int j;
GLshort x,y,dx,dy,dk;
dx=x2-x1;
dy=y2-y1;
dk=2*dy-dx;
x=x1;
y=y1;
for(j=0;j<=dx;j++)
{
p=(LinkList)malloc(sizeof(LNode));//将要画的点坐标用链表储存
p->x=x;
p->y=y;
p->next=L->next;
L->next=p; //此上五句等价drawpixel(x,y);
x=x+1;
dk=dk+2*dy;
if(dk>=0)
{
y=y+1;
dk=dk-2*dx;
}
}
}
void myDisplay(void)
{
LinkList q;
q=L->next;
glClear(GL_COLOR_BUFFER_BIT);
gluOrtho2D(-200,200,-200,200);
glBegin(GL_POINTS);
while(q!=NULL)
{
glVertex2s(q->x,q->y);
q=q->next;
}
glEnd();
glFlush();
}
int main(int argc, char *argv[])
{
GLshort a,b,c,d;
LinkList t;
CreateList_L();
scanf("%d%d%d%d",&a,&b,&c,&d);
Bresenham_Line(a,b,c,d);
t=L->next;
while(t!=NULL)
{
printf("%d %d\n",t->x,t->y);
t=t->next;
}//此上六行为显示Bresenham画直线算法的正确性将所要画的点的坐标打印出来
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
gluOrtho2D(-200,200,-200,200);//定义像素间距为 1
glutCreateWindow("画直线");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
谢谢。。。。
52 楼
eastcowboy [专家分:25370] 发布于 2007-05-05 23:30:00
恕我直言,这样的问题,我是不会答复的——至少我不会直接答复。
“为什么不能正确显示图形”,什么才叫正确呢?程序要求用户给出若干输入,这些输入是起什么作用?整个程序又有什么功能?这些都不讲清楚,我实在是不愿意阅读如此枯燥的程序代码。抱歉了。
53 楼
conqest [专家分:0] 发布于 2007-05-06 00:29:00
非常抱歉,是我的错。我是新手,编程不成功因此烦躁,未能全面考虑你的感受!那个问题我已修改,加了一些注释。但愿写得清楚!希望您能在闲暇时间看一下,指点迷津。
54 楼
eastcowboy [专家分:25370] 发布于 2007-05-06 09:48:00
这下清楚多了。我感觉你的Bresenham算法有些问题,似乎只能绘制斜率在[0, 1]之间的直线?并且,输入的两个点的坐标,必须满足x1 < x2才能正确绘制。
在图形绘制方面,程序在display函数中直接使用了gluOrtho2D(-200,200,-200,200);,这是不对的。
gluOrtho2D的功能并不是像它字面意思那样,把坐标系设置为多少多少,它的实际功效是在当前矩阵上乘以一个新的矩阵。如果当前矩阵是单位矩阵,那么确实可以达到正确设置坐标系的效果,如果当前矩阵不是单位矩阵,则效果可能就不是你所想像的那样了。由于display这个函数会被反复调用,在第二次和以后各次中,当前矩阵已经不是单位矩阵了,所以不能得到预期效果。为了保证每次使用gluOrtho2D前,当前矩阵是单位矩阵,可以在gluOrtho2D函数调用以前,使用glLoadIdentity函数来将当前矩阵复位。
另外,习惯上是把“透视矩阵”作为当前矩阵来执行gluOrtho2D操作,而用“模型视图矩阵”作为当前矩阵来执行glRotatef等操作。因此在使用gluOrtho2D前,应该选择“透视矩阵”来作为当前矩阵,使用gluOrtho2D后,重新选择“模型视图矩阵”作为当前矩阵。
因此,程序中gluOrtho2D一句可以用以下五句替换:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-200,200,-200,200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
55 楼
conqest [专家分:0] 发布于 2007-05-06 15:51:00
太high了!
我这个直线算法确实如你所说有局限,因为我是新手,我只想试试这种想法对不对!
听你的解释我了解了很多知识!也知道自己知识太短浅!而且你很快就给我回复!非常感谢您!!!
56 楼
open-minded [专家分:30] 发布于 2007-05-08 20:49:00
相当的好,谢谢了。
想问一下,我们用的是vc 6.0可以用吗。
57 楼
eastcowboy [专家分:25370] 发布于 2007-05-09 00:19:00
VC6.0基本上是可以的,——虽然VC6.0的bug众多,但其中很多都只在使用C++时出现。只使用C语言的话,问题不大。但为什么一定要用6.0呢?不必这样吧。就像TC,太过老旧总会被淘汰的。
58 楼
open-minded [专家分:30] 发布于 2007-05-11 09:43:00
感谢感谢。
59 楼
ivyran [专家分:0] 发布于 2007-05-14 13:31:00
太感谢了。。。
60 楼
happyfafa [专家分:0] 发布于 2007-06-15 12:15:00
这么好的帖子加精是应该的。楼主是个好人,我强烈支持
我来回复