关于C语言的图形编程

简介:

老是被同学们问一些关于C语言初学时的图形编程问题,感觉有点代表性,这里统一做个回答。

一家之言哈,欢迎拍砖。

问题:

1、为什么VC下找不到BGI文件?

2、我按照书上写的把程序输入,编译时发现找不到graphics.h文件

3、VC是不是不支持图形开发啊?

4、... ...

问这类问题的同学还很多,总的来说,我觉得这些同学应该属于初学C语言,对于语言、操作系统、平台的概念还不清楚,因此会问这类问题。

首先,纠正一点,C语言就是C语言,是负责编制程序实现计算的,真正的C语言,是不带任何平台相关特点的,而图形、声音,是平台相关,因为不是每个计算平台都有图形界面,因此,最原始的C,甚至是C++语言,是不带任何图形开发接口的。

就我本人而言,也犯过类似的迷糊,最开始我们在Apple II计算机上开发,由于其Basic语言是和计算机绑定在一起的,硬件也有图形开发接口,使用汇编语言也能直接开发,因为,我就想当然地认为,计算机一定可以绘图的。

后来学习了计算机图形学,才发现不是这么一回事,图形终端,是单独的一门大学问,和计算机基本上是割裂的,在以前大中小型机的时代,一台计算机可以带字符终端,如电传打字机,也可以带图形终端,不过,有图形终端的一般叫图形工作站,呵呵,很拉风的。

记得90年我在石油物探局玩了一次Sun Sparc 490图形工作站,我当时都迷了,90年,人家音频、视频接口就是标配,XWindows比我们现在的XP什么的好看多了,按钮全是圆弧带阴影的,硬件实现实三维计算。记得当年是瞒着巴统进来的,一台120万美金,确实是好东东,20年前的配置,到现在都不见得落后多少。

呵呵,说远了,主要是请大家清楚一点,计算机里面还是可以细分的,图形系统是图形系统,计算机是计算机,我们大家一般都是从微型计算机PC开始学习编程的,再加上现在Windows系统这么流行,可能有点想当然,以为图形显示卡是一台计算机的标配,呵呵,不一定的。

好,话说回来,大家可能还有个误区,以为C语言,C++语言,以及Java这些东东,是PC机的语言,其实也不是的,计算机硬件是硬件,软件是软件,C和C++都有自己的标准协会,Java有Sun公司在维护,因此,这些语言的产生和发展,其实和PC平台没有太多关系。

最起码,C就是为Unix而生的,而Unix一般是大中小型机的标准操作系统,Windows最开始提供的是Pascal格式的api,大家查查Win32API,很多很古老的函数接口,前面都要有PASCAL修饰,表示这个接口符合PASCAL标准。甚至,目前我们用的匈牙利命名法,其实是Pascal的命名法,发明者是个匈牙利人,应该是Windows api的主要制定者之一。

因此,大家可以想象,C和C++语言的基本库,本来就不可能绑定任何一个平台,一定只会利用各个平台共有的特点来完成设计,而图形系统,大家可以想象,各个平台都不一样,很难有个通用的库,所以,真实的C语言里面,其实是不带图形啊,声音啊这类库的,这些都是各个硬件、操作系统软件开发商,自行提供的。

VC是个特例,VC准确的讲,应该不是一门C和C++的教学型语言,它更像Windows平台定制的一个实用性C和C++语言。因此,他天生就有对Windows的集成性,自然支持Win32API中关于GUI的图形函数,因此,VC是可以绘图的。只要你有一个窗口,就可以再窗口DC上绘图。如果使用DirectX的话,甚至可以利用虚拟的表面,直接访问显存,实现高速绘图,开发游戏。

不过这里还得倒回去说一点,最开始PC平台使用DOS操作系统,是没有C语言的,当时有家公司叫做Borland,看中这个市场,推出了TurboC系列语言,后来又发展到Borland C++系列,大家不要跟我说不知道啊,Delphi知道不?

当时DOS平台一般都有图形卡,但卡的类型很多,而DOS显然又没有Windows这样,提供统一的api接口访问,因此,需要进行图形绘制的厂商,一般需要自己根据各个卡型开发自己的驱动程序,以前有段时间,台湾的游戏很流行,很多游戏一上来就让玩家选择显卡,如EGA、VGA等等,就是在选择驱动程序。

驱动程序其实不复杂,就是封装各个图形卡的差异性,对上提供统一的api接口供上层函数调用,驱动一般都是汇编和C语言开发的。目前有很多工作岗位,招嵌入式开发工程师,主要就是写驱动。看见没,嵌入式由于没有Windows这个统一的界面,也需要写驱动。

这里就要夸夸比尔盖茨了,他的Windows系统其实意义重大,不仅仅起到了图形界面操作系统的用途,它实际上整合了PC平台的驱动标准,各个硬件厂商以后只要给Windows写驱动就好了,不需要针对每个应用分别写驱动,如AutoCAD的驱动和游戏的驱动显然就不是一码事,这样硬件厂商节约很多人力,自然说好。

软件厂商呢,只要针对Windows平台开发,就自然而然支持所有符合Windows规范的硬件,也无需自己每种硬件都采购一套,分别写驱动,这节约了大量的人力和无力,因此,Windows最成功的,我认为还不是这个图形界面,它整合了驱动标准,为业界节约了大量的成本,这是它的成功之处,值得称道。

好了,说了这么多,再回到Borland,由于它做TurboC的时代,还是DOS操作系统,没有Windows这么方便,但是PC平台的C语言,要是不支持图形绘制,市场会大打折扣,大家不买啊,因此,他必须让他的C语言支持图形,但是,图形卡有很多啊,因此,他就开发出自己的图形驱动标准,叫做BGI,这是一种文件格式,一般安装一套TurboC,里面会带一堆这个文件,就是针对各个不同显卡的驱动。

而上层的程序,使用graphics.h这个头文件,调用标准BGI的api调用,即可实现图形开发,至于针对各个不同的图形卡,api中有查询接口,告诉你选择哪个BGI而已。

OK,问上面问题的同学们明白没?

不过话说回来,DOS毕竟是淘汰的东东,目前已经是Windows的世界,最起码Linux的市场都比DOS大,因此,建议同学们自学C语言,还是看看书的出版年代,问问题的同学显然对着一本TurboC的书在看,这很麻烦,学出来的东西一来不好做实验,二来也没有市场,现在估计没有哪家公司还在使用TurboC开发。建议大家还是从VC学起吧。

VC下大家就不用问了,Windows是图形操作系统,一定有图形函数的,查查Win32API函数库,看看MFC,都能找到一堆。

这里简单提示几点:

1、Windows下,一切都是窗口,我们看到的一个软件界面,如VC,如IE,是无数个窗口构成的,甚至Dialog上每个按钮,都是窗口。

2、Windows下,只要是窗口,就一定有句柄,Handle,这是每个窗口的灵魂,任何针对窗口的操作,几乎都是从Handle开始的。

3、一般说来,窗口分两类,可显示的和不可显示的,大多数是可显示的。只要可显示,就可以利用GetWindowDC,从Handle获得DC。

4、DC到手,天下我有。呵呵,拿到DC,大家就想怎么画就怎么画了。可以设定画笔,刷子,字体,可以用画点,画线的函数,可以填充,裁剪,等等,GUI图形虽然效率偏低,做高速游戏动画可能不够,不过,就大家目前做的图形试验,写个物理教学题材的软件,做个化学实验软件等等,足够了。

OK,大家还有问题吗?

本文转自 tonyxiaohome 51CTO博客,原文链接:http://blog.51cto.com/tonyxiaohome/198793 ,如需转载请自行联系原作者

相关文章
|
11月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
528 8
|
12月前
|
C语言 开发者
C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧
本文深入探讨了C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧,并通过案例分析展示了其应用,展望了未来的发展趋势,旨在帮助读者提升程序质量和开发效率。
597 5
|
12月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
370 4
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
1824 12
ly~
|
存储 缓存 算法
如何使用 C 语言实现高效的图形渲染?
使用 C 语言实现高效图形渲染可从选择图形库、优化数据结构与算法及利用硬件加速等方面着手。推荐使用 OpenGL 或 SDL 进行图形绘制。OpenGL 功能强大,支持 2D 和 3D 图形,需熟悉其绘图流程;SDL 则提供简单易用的接口。优化方面,合理选择数据结构如数组、哈希表等,使用高效算法如 LOD 可提升渲染速度。利用 GPU 加速和多线程渲染亦能显著提高效率。此外,纹理映射和管理也是关键,适当加载和缓存纹理,减少不必要的绘制操作如视口裁剪和背面剔除,均可增强渲染性能。
ly~
396 5
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
消息中间件 Unix Linux
C语言 多进程编程(五)消息队列
本文介绍了Linux系统中多进程通信之消息队列的使用方法。首先通过`ftok()`函数生成消息队列的唯一ID,然后使用`msgget()`创建消息队列,并通过`msgctl()`进行操作,如删除队列。接着,通过`msgsnd()`函数发送消息到消息队列,使用`msgrcv()`函数从队列中接收消息。文章提供了详细的函数原型、参数说明及示例代码,帮助读者理解和应用消息队列进行进程间通信。
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
消息中间件 Unix Linux
C语言 多进程编程(二)管道
本文详细介绍了Linux下的进程间通信(IPC),重点讨论了管道通信机制。首先,文章概述了进程间通信的基本概念及重要性,并列举了几种常见的IPC方式。接着深入探讨了管道通信,包括无名管道(匿名管道)和有名管道(命名管道)。无名管道主要用于父子进程间的单向通信,有名管道则可用于任意进程间的通信。文中提供了丰富的示例代码,展示了如何使用`pipe()`和`mkfifo()`函数创建管道,并通过实例演示了如何利用管道进行进程间的消息传递。此外,还分析了管道的特点、优缺点以及如何通过`errno`判断管道是否存在,帮助读者更好地理解和应用管道通信技术。