精华内容
下载资源
问答
  • Zabr是一种开源的一维码和二维码检测工具,该工具检测时适应性很强,如图的示例图片不进行任何图像处理情况下都可以便正确读取条形码或者二维码的信息,适合于工业环境下光照不稳定情况识别条形码和二维码。...

    Zabr是一种开源的一维码和二维码检测工具,该工具检测时适应性很强,如下图的示例图片在不进行任何图像处理情况下都可以便正确读取条形码或者二维码的信息,适合于工业环境下光照不稳定情况下识别条形码和二维码。
    该库是基于C语言开发,可以方便的进行平台间的移植。
    识别条形码和二维码的主要步骤如下:
    1.算法初始化:构造扫描器对象用set_config()进行初始化。
    2.载入图片,转化为灰度图。
    3.图像初始化。
    4.对图像进行扫描。
    5.显示条码读取结果。
    Image::SymbolIterator symbol = imageZbar.symbol_begin();
    symbol->get_type_name()
    symbol->get_data()

    经过试验Zbar具有很强的鲁棒性,可以同时识别多个条形码或二维码,部分检测结果如图所示。
    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    源码价格:20元
    源码获取请点击链接:源码获取方法

    展开全文
  • RTOS环境下多任务编程要点

    千次阅读 2014-04-05 17:39:53
    RTOS环境下多任务编程要点 一. 分析阶段 1. 需求分析,予以文档描述; 2. 一些初始化问题,探究需求分析中的关键点; 3. 解决时序问题,系统中算法的分析; 4. 决定使用RTOS,依赖于时间响应和任务数量;...

    RTOS环境下多任务编程要点

    一.   分析阶段

    1.  需求分析,予以文档描述;

    2.  一些初始化问题,探究需求分析中的关键点;

    3.  解决时序问题,系统中算法的分析;

    4.  决定使用RTOS,依赖于时间响应和任务数量;

    5.  划分任务,确定系统所需的任务和模块;

    6.  系统间通信,消息机制是最优的方法之一;

    7.  共享数据处理,创建独立的模块;

    8.  结论,绘制系统设计图。

    二.   编码实现

    1.  系统组成的基本单元是模块,即单个的C源文件,它封装了数据与程序;

    2.  模块之间交互通过调用函数来实现,没有使用任何全局变量;

    3.  防止竞态发生的手段是信号量;

    4.  非立即获取的数据由回调函数予以处理;

    5.  向任务发送消息的方法封装在“外壳”函数之中;

    6.  所有模块调用的函数原型全部组织在一个头文件之中;

    7.  模块中都有初始化函数,负责任务创建、初始化信号量和队列等,并由main()主函数统一调用。

    三.   防止竞态(以下任务包括ISR)

    1.  竞态只可能发生在全局的资源上(硬件/全局变量/静态变量),而像任务的私有资源(仅被自己访问)和堆栈数据是不可能发生竞态的;

    2.  一个函数被哪个任务调用,它就代表该任务的访问行为,与该函数定义位置无关(回调函数是最让人迷惑的,它定义在A任务中,但它被任务B调用,所以它代表任务B的访问行为);

    3.  凡是被多个任务访问(包括读/写)的资源,必定发生竞态;

    4.  需要保护的共享资源必须确保在使用范围之内都是处于保护状态;

    5.  保护的手段:禁止/启用IRQ、禁止/启用任务调度、信号量。

    四.   线程通信

    方式一 实时操作系统中任务通信的经典方式是:任务阻塞在等待消息上,直到中断服务程序或者其他任务给自己发送消息。如:

        void TaskA(void)

        {

          while (FOREVER)

             {

               OSQPend(p_QData, 0, &err);  /* waiting for events */

            /**** deal with received events ****/

             }     

        }

      当其他任务向自己发送消息时,把该消息封装在“外壳函数”中,这样可以避免使用全局变量,同时增加了安全性:

        void taska_SendPrompt(Int IMsg)

        {

             assert(IMsg >= MIN_VAL && Imsg <= MAX_VAL);

          OSQPost(p_QData, (void *)IMsg);

    }

     

    方式二结合邮箱和信号量可以让任务进行更高级的通信方式,如下代码所示,任务A先创建一信号量,绑定信号量和它希望任务B所做的事情到消息中,再投递该消息到邮箱,然后在信号量上进行等待,当结束等待时说明任务B已经干完该事情,则删除信号量。

        void TaskA(void)

    {

      msg.sem = CreateSemaphore(0);

      msg.func = TaskAFunc;

      PostMBox(mbox, &msg);  /* tell TaskB do something */

      WaitSemaphore(msg.sem);  /* waiting until TaskB done */

      FreeSemaphore(msg.sem);

        }

    任务B首先在邮箱上等待,当接收到消息后调用函数,完成任务A希望它干的事情,再释放信号量通知任务A工作完毕。

    void TaskB(void)

    {

      msg = PendMBox(mbox);

      msg.func(&msg);  /* do something that TaskA desired */

      SignalSemaphore(msg.sem);  /* tell TaskA thing is done */

        }

    五.   线程共享

    1)简单共享,如图1所示,任务A写数据块DataStructure后给任务B发送消息,任务B提取消息并从任务A复制数据块DataStructure到自己的数据区TaskBData中。

    优点:简单,容易实现,适合于慢速通信。

    缺点:①任务B如果响应速度不够快则有可能任务A又改写了数据块而发生错误(Write两次,Read一次);②DataStructure同时被任务A和任务B访问,为防止“竞态”错误需要进行保护。

    图1 简单共享

     

    2)抽象成数据模块,加信号量予以保护,如图2所示。

    优点:简单,安全,模块化,适应于被多个任务共享的数据。

    缺点:①任务可能会在该信号上阻塞很长时间;②任务为了方便操作数据一般会建立自己的副本,这样一来占用更多的数据存储区。

    图2  带信号量的数据模块

     

    3)回调函数,如图3所示,任务A把自己的回调函数传递给任务B的消息队列中,任务B从队列中提取并调用该函数,此时回调函数即可以访问任务B的数据,又可以访问任务A的数据,给编程带来极大的自由度。

    优点:自由灵活,如任务A和任务C对任务B中的数据进行不同的运算,只需要修改任务对应的回调函数即可,特别适应于任务中数据被多个其他任务使用且运算方式不同的场合。

    缺点:①较为复杂,需要清晰了解回调函数的数据流才能正确使用;②回调函数定义在任务A但被任务B使用,它就代表任务B的行为,这样一来TaskAData就被任务A和任务B(通过TaskACallback)共享,为避免“竞态”带来错误,需要对TaskAData进行保护(参见上述三),同理,TaskCData也需要进行保护。

    图3 回调函数

     

    4)生产者与消费者队列,如图4所示,任务A把“生产”的数据存入RingBuffer中,再将该数据的指针传递给任务B的消息队列中,任务B提取该数据的指针后从RingBuffer复制数据到TaskBData中。

    优点:简单可靠,适应于尺寸相同且“生产”速率恒定的场合。

    缺点:①对数据尺寸有限制,必须是相同大小的数据才能建立RingBuffer(循环缓冲区);②“生产“速率必须恒定且RingBuffer的大小设置合理,才能确保不会发生“溢出”错误。

    图4 生产者与消费者队列

     

    5)动态生成消息,如图5所示,任务A动态生成(常见为malloc())消息msg,将该消息指针传递到任务B的消息队列中,任务B提取并处理该消息后,释放(常见为free())该消息所占用的内存。

    优点:适用于多任务之间进行自由通信,消息类型和大小都不受限制。

    缺点:①较复杂,消息类型可能会非常多,需要较好她组织;②因为动态分配和释放内存,需要细心设计,小心内存泄露;③动态分配内存时间不可控,对于实时性要求特别高的任务需要考虑这个限制。

    图5 动态生成消息

    展开全文
  • GCC编译器简明教程(LinuxC语言开发环境的搭建)

    万次阅读 多人点赞 2018-09-13 21:49:59
    GCC编译器简明教程(LinuxC语言开发环境的搭建) 市面上常见的Linux是发行版本,典型的Linux发行版包含了Linux内核、桌面环境(例如GNOME、KDE、Unity等)和各种常用的必备工具(例如Shell、GCC、VIM、Firefox...

    GCC编译器简明教程(Linux下C语言开发环境的搭建)

    市面上常见的Linux都是发行版本,典型的Linux发行版包含了Linux内核、桌面环境(例如GNOMEKDEUnity等)和各种常用的必备工具(例如ShellGCCVIMFirefox等),国内使用较多的是CentOSUbuntu(乌班图)、DebianRedhat等。

    Linux主要应用于各种服务器(例如网站服务器、数据库服务器、DNS服务器、邮件服务器、路由器、负载均衡集群等),而不是我们常见的个人电脑。Linux是服务器操作系统的绝对霸主,占据了80%以上的份额,在未来的服务器领域,Linux是大势所趋。这其中,又以CentOSUbuntu为主,CentOS占有压倒性的优势。服务器操作系统80%以上的市场份额被Linux占据,而Linux 80%以上的份额又被CentOS占据。本教程以CentOS为例来讲述如何编译C程序。

    服务器上的Linux是不安装图形界面的,只能在控制台模式下使用,以尽量节省服务器资源。而我们在学习过程中使用的Linux是带图形界面的,以满足初学者的需求,降低学习成本。

    Linux下我们仍然可以使用带界面的、傻瓜式的IDE,例如CodeLiteCLion(收费)、Code::BlocksNetbeansEclipse CDT等。微软的Visual Studio也支持Linux了,在Windows下用惯了Visual Studio的用户也可以毫无障碍地迁移到Linux平台。

    但是作为初学者,我建议大家在命令行模式下编译C语言程序,这样能够了解生成一个可执行程序的详细步骤,以及编译命令的各种设置选项,为以后的LinuxC/C++ 开发打好坚实的基础。

    Gedit 编辑器

    Linux下,很多程序员都推崇使用VimEmacs等命令行模式的编辑器,它们功能强大,逼格够高,不管有没有桌面环境都能使用,是LinuxC/C++程序员必备的神器。但是VimEmacs并不容易上手,使用者需要记忆很多命令和快捷键,熟练才能生巧,所以需要一段时间的学习和适应,这会增加初学者的学习成本,所以这里不推荐大家使用。

    CentOS下有一款自带的图形界面编辑器,叫做GeditGedit是一款简单实用的文本编辑器,界面优雅,支持语法高亮,比Vim容易上手,它和Windows下的编辑器没有什么两样。本教程将Gedit作为C语言代码的编辑器。

    如果你使用的是其它的Linux发行版,可能没有默认安装Gedit,这个时候就得自己安装,具体步骤为:

    $ sudo apt-add-repository ppa:ubuntu-on-rails/ppa   #添加ubuntu的软件源

    $ sudo apt-get update   #更新软件列表

    $ sudo apt-get install gedit-gmate   #安装

    首先,在我们自己的用户目录下新建一个名为demo的文件夹。这个文件夹专门用来存放与C语言相关的文件,例如源文件、目标文件、可执行文件等,它专供我们学习使用。

    用户目录有时候也叫home文件夹或者主文件夹,它的路径是/home/username,其中 username 就是我们登录Linux时使用的用户名。Linux 会在 home 目录下为每一个登录的用户创建一个文件夹,专门用来存放该用户使用到的配置文件、文本文档、图片、可执行程序等,以和其他用户区分开来。

    接下来需要创建一个空白的 main.c 源文件。main.c 其实就是一个纯文本文件,并没有任何特殊格式,但是Linux不像 Windows,可以在右键菜单中新建文本文档,Linux 必须使用命令来创建,如下所示:

    $ cd demo  #进入 demo 目录,这是源文件所在的目录

    $ touch main.c  #使用 touch 命令创建一个名为 main.c 的空文件

    $ gedit main.c  #使用 gedit 命令编辑 main.c

    这样就完成了源文件的创建,并能够使用Gedit编辑源文件了。

    Gedit 中输入下面的C语言代码:

    #include <stdio.h>

    int main()

    {

        puts("C语言中文网");

        return 0;

    }

    输入完成后的效果如下图所示:

    http://c.biancheng.net/cpp/uploads/allimg/171008/1-1G00Q10053154.jpg

    Ctrl+S保存文件,就完成了源代码的编辑工作。此时需要关闭Gedit的窗口,$ gedit main.c命令才算执行结束,才能在控制台继续输入其它命令。

    下图演示了在控制台上的实际效果:

    http://c.biancheng.net/cpp/uploads/allimg/171009/1-1G00910510UJ.jpg

    注意,在CentOS下,使用touch命令创建完main.c后,进入demo目录,在右键菜单中也可以使用Gedit 打开main.c,如下图所示:

    http://c.biancheng.net/cpp/uploads/allimg/171008/1-1G00Q104301H.jpg

    GCC 编译器

    Linux下使用最广泛的 C/C++ 编译器是 GCC,大多数的Linux发行版本都默认安装,不管是开发人员还是初学者,一般都将 GCC 作为Linux下首选的编译工具。本教程也毫不犹豫地使用 GCC 来编译C语言程序。GCC 仅仅是一个编译器,没有界面,必须在命令行模式下使用。通过gcc命令就可以将源文件编译成可执行文件。

    1) 生成可执行程序

    最简单的生成可执行文件的写法为:

    $ cd demo  #进入源文件所在的目录

    $ gcc main.c  # gcc 命令后面紧跟源文件名

    打开 demo 目录,会看到多了一个名为 a.out 的文件,这就是最终生成的可执行文件,如下图所示:

    http://c.biancheng.net/cpp/uploads/allimg/171008/1-1G00Q64J2C5.jpg

    这样就一次性完成了编译和链接的全部过程,非常方便。

    注意:不像 WindowsLinux 不以文件后缀来区分可执行文件,Linux 下的可执行文件后缀理论上可以是任意的,这里的.out只是用来表明它是 GCC 的输出文件。不管源文件的名字是什么,GCC 生成的可执行文件的默认名字始终是a.out

    如果不想使用默认的文件名,那么可以通过-o选项来自定义文件名,例如:

    $ gcc main.c -o main.out

    这样生成的可执行程序的名字就是main.out

    因为Linux下可执行文件的后缀仅仅是一种形式上的,所以可执行文件也可以不带后缀,例如:

    $ gcc main.c -o main

    这样生成的可执行程序的名字就是main

    通过-o选项也可以将可执行文件输出到其他目录,并不一定非得在当前目录下,例如:

    $ gcc main.c -o ./out/main.out

    或者

    $ gcc main.c -o out/main.out

    表示将可执行文件输出到当前目录下的out目录,并命名为main.out./表示当前目录,如果不写,默认也是当前目录。

    注意:out 目录必须存在,如果不存在,gcc 命令不会自动创建,而是抛出一个错误。

    2) 运行可执行程序

    上面我们生成了可执行程序,那么该如何运行它呢?很简单,在控制台中输入程序的名字就可以,如下所示:

    $ ./a.out

    ./表示当前目录,整条命令的意思是运行当前目录下的 a.out 程序。如果不写./Linux 会到系统路径下查找 a.out,而系统路径下显然不存在这个程序,所以会运行失败。

    所谓系统路径,就是环境变量指定的路径,我们可以通过修改环境变量添加自己的路径,或者删除某个路径。很多时候,一条Linux命令对应一个可执行程序,如果执行命令时没有指明路径,那么就会到系统路径下查找对应的程序。

    输入完上面的命令,按下回车键,程序就开始执行了,它会将输出结果直接显示在控制台上,如下所示:

    $ cd demo

    $ gcc main.c

    $ ./a.out

    C语言中文网

    $

    下图演示了在控制台上的实际效果:

    http://c.biancheng.net/cpp/uploads/allimg/171009/1-1G00910095aA.jpg

    如果程序在其它目录下,运行程序时还要带上目录的名字,例如:

    $ ./out/main.out

    或者

    $ out/main.out

    这个时候加不加./都一样,Linux 能够识别出out是一个目录,而不是一个命令,它默认会在当前路径下查找该目录,而不是去系统路径下查找,所以不加./也不会出错。

    注意,如果程序没有执行权限,可以使用sudo命令来增加权限,例如:

    $ sudo chmod 777 a.out

    完整的演示

    为了让读者有一个更加全面的认识,我们不妨将上面两部分的内容连接起来,完整的演示一下从编辑源文件到运行可执行程序的全过程:

    $ cd demo  #进入源文件所在目录

    $ touch main.c  #新建空白的源文件

    $ gedit main.c  #编辑源文件

    $ gcc main.c  #生成可执行程序

    $ ./a.out  #运行可执行程序

    C语言中文网

    $   #继续等待输入其它命令

    下图是在控制台上的实际效果:

    http://c.biancheng.net/cpp/uploads/allimg/171009/1-1G009111F9448.jpg

    分步骤编译

    上面讲解的是通过gcc命令一次性完成编译和链接的整个过程,这样最方便,大家在学习C语言的过程中一般都这么做。实际上,gcc命令也可以将编译和链接分开,每次只完成一项任务。

    1) 编译(Compile

    将源文件编译成目标文件需要使用-c选项,例如:

    gcc -c main.c

    就将 main.c 编译为 main.o。打开 demo 目录,就会看到 main.o

    http://c.biancheng.net/cpp/uploads/allimg/171009/1-1G009130633I6.jpg

    对于微软编译器(内嵌在 Visual C++ 或者 Visual Studio 中),目标文件的后缀为.obj;对于 GCC 编译器,目标文件的后缀为.o

    一个源文件会生成一个目标文件,多个源文件会生成多个目标文件,源文件数目和目标文件数目是一样的。通常情况下,默认的目标文件名字和源文件名字是一样的。

    如果希望自定义目标文件的名字,那么可以使用-o选项,例如:

    gcc -c main.c -o a.o

    这样生成的目标文件的名字就是 a.o

    2) 链接(Link

    gcc命令后面紧跟目标文件的名字,就可以将目标文件链接成为可执行文件,例如:

    gcc main.o

    就将 main.o 链接为 a.out。打开 demo 目录,就会看到 a.out

    gcc命令后面紧跟源文件名字或者目标文件名字都是可以的,gcc命令能够自动识别到底是源文件还是目标文件:如果是源文件,那么要经过编译和链接两个步骤才能生成可执行文件;如果是目标文件,只需要链接就可以了。

    使用-o选项仍然能够自定义可执行文件的名字,例如:

    gcc main.o -o main.out

    这样生成的可执行文件的名字就是 main.out

    下面是一个完整的演示:

    $ cd demo

    $ gcc -c main.c

    $ gcc main.o

    $ ./a.out

    C语言中文网

    在控制台上的真实效果为:

    http://c.biancheng.net/cpp/uploads/allimg/171009/1-1G009131435196.jpg

    展开全文
  • MFC初始化OpenGL编程环境   1:新建一个MFC的工程,单文档的工程。 2:工程建好之后,可以先编译运行一下。下面就是要把View的窗口初始化为OpenGL的编程环境。当然以下所有的操作...

    在MFC下初始化OpenGL编程环境  

     1:新建一个MFC的工程,单文档的工程。


    2:工程建好之后,可以先编译运行一下。下面就是要把View的窗口初始化为OpenGL的编程环境。当然以下所有的操作都是在View类中进行的。
    先在Project->Settings->Link中,加上opengl32.lib glu32.lib glut.lib glaux.lib,然后在View.h的类定义中加上如下引用。这个大家都知道。

    #include <gl\gl.h>

    #include <gl\glu.h>   

    #include <gl\glut.h>

    #include <gl\glaux.h>

    3:在PreCreateWindow(CREATESTRUCT& cs)这个函数中可以修改一下窗口的风格,比如说窗口的名称背景什么的,当然也可以不修改,如果想修改的话,需要对WNDCLASSEX和CREATESTRUCT这两个结构比较熟悉。在这里,我不进行修改。采用默认的风格。


    4:下面开始正题,首先要让窗口支持OpenGL,那就必须要对PIXELFORMATDESCRIPTOR这个结构有所了解,先在View类中新建一个函数SetupPixFormat(CDC *pDC),公有私有无所谓,如下:
    BOOL CTestGLInitialView::SetupPixFormat(CDC *pDC) //我建立的工程名叫TestGLInitial
    {
    static PIXELFORMATDESCRIPTOR pfd = //定义像素格式
    {
       sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
       1,         // 版本号
       PFD_DRAW_TO_WINDOW |    // 格式支持窗口
       PFD_SUPPORT_OPENGL |    // 格式必须支持OpenGL
       PFD_DOUBLEBUFFER,     // 必须支持双缓冲
       PFD_TYPE_RGBA,      // 申请 RGBA 格式
       24,         // 24位色彩深度,即1.67千万的真彩色
       0, 0, 0, 0, 0, 0,     // 忽略的色彩位
       0,         // 无Alpha缓存
       0,         // 忽略Shift Bit
       0,         // 无累加缓存
       0, 0, 0, 0,       // 忽略聚集位
       32,         // 32位 Z-缓存 (深度缓存)
       0,         // 无蒙板缓存
       0,         // 无辅助缓存
       PFD_MAIN_PLANE,      // 主绘图层
       0,         // Reserved
       0, 0, 0        // 忽略层遮罩
    };

    int nIndex = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd); //选择刚刚定义的像素格式
    if( nIndex == 0 ) return FALSE;

    return SetPixelFormat(pDC->GetSafeHdc(), nIndex, &pfd);   //设置像素格式
    }
    这个函数的主要目的就是设置窗口的像素格式,使之支持OpenGL,明白这点就行了。在创建窗口的时候,调用这个函数。


    5:刚刚那个函数是用来在创建窗口是调用的,在创建窗口时,还需要对OpenGL的环境做一些初始化,再定义一个函数InitialGL(),公有私有也无所谓,反正是自己调用的,如下:
    BOOL CTestGLInitialView::InitialGL()
    {
    glShadeModel(GL_SMOOTH);           // 启用阴影平滑
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       // 黑色背景
    glClearDepth(1.0f);                            // 设置深度缓存
    glEnable(GL_DEPTH_TEST);             // 启用深度测试
    glDepthFunc(GL_LEQUAL);              // 所作深度测试的类型
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // 告诉系统对透视进行修正
    return TRUE;                                      // 初始化 OK
    }
    这里的代码我都是抄的NeHe教程上面的代码。


    6:现在可以捕获WM_CREATE消息了。 但是,还要先定义一个CClientDC*的成员,这个成员指向View窗口自己,是用来传递给SetupPixFormat(CDC *pDC)函数的,没别的意思。
    现在,来捕获WM_CREATE消息,写上如下代码:
    int CTestGLInitialView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CView::OnCreate(lpCreateStruct) == -1)
       return -1;

    // TODO: Add your specialized creation code here
    m_pDC = new CClientDC(this);
    SetupPixFormat(m_pDC);

    HGLRC hrc = wglCreateContext(m_pDC->GetSafeHdc());
    wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);

    InitialGL();
    return 0;
    }
    当然,当窗口关闭的时候,还应该要释放一些资源。捕获WM_DESTROY消息,写下如下代码:
    void CTestGLInitialView::OnDestroy() 
    {
    CView::OnDestroy();

    // TODO: Add your message handler code here
    HGLRC hrc = wglGetCurrentContext();
    wglMakeCurrent(NULL, 0);
    wglDeleteContext(hrc);
    delete m_pDC;
    }
    现在可以编译一下了,没有错误。


    7:现在,OpenGL的环境已经初始化差不多了。可以开始做图了,先定义一个作图的函数DrawScene(),写上如下的代码:
    BOOL CTestGLInitialView::DrawScene()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除屏幕和深度缓存
    glLoadIdentity();            // 重置当前的模型观察矩阵
    SwapBuffers(m_pDC->GetSafeHdc());        // 交换缓冲区
    return TRUE;
    }
    然后,要在OnDraw中,调用这个函数:
    void CTestGLInitialView::OnDraw(CDC* pDC)
    {
    CTestGLInitialDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    DrawScene();
    }


    8:运行一下,黑色的背景出来了。


    9:这时,可以修改DrawScene()这个作图函数,作图。画出NeHe第3课的那个三角形和正方形来。写代码如下:
    BOOL CTestGLInitialView::DrawScene()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除屏幕和深度缓存
    glLoadIdentity();            // 重置当前的模型观察矩阵

    glTranslatef(-1.5f,0.0f,-6.0f);       // 左移 1.5 单位,并移入屏幕 6.0
    glBegin(GL_TRIANGLES);         // 绘制三角形
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3f( 0.0f, 1.0f, 0.0f);       // 上顶点
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(-1.0f,-1.0f, 0.0f);       // 左下
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 0.0f);       // 右下
    glEnd();            // 三角形绘制结束

    glTranslatef(3.0f,0.0f,0.0f);       // 右移3单位
    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);          // 绘制正方形
    glVertex3f(-1.0f, 1.0f, 0.0f);       // 左上
    glVertex3f( 1.0f, 1.0f, 0.0f);       // 右上
    glVertex3f( 1.0f,-1.0f, 0.0f);       // 左下
    glVertex3f(-1.0f,-1.0f, 0.0f);       // 右下
       glEnd();

    SwapBuffers(m_pDC->GetSafeHdc());        // 交换缓冲区
    return TRUE;
    }
        运行一下,发现图形没有出现,这个怎么回事呢。原来是因为还没有定义投影方式和视口。即用正交投影还是透视投影。定义投影,还要捕获WM_SIZE消息。写如下代码:
    void CTestGLInitialView::OnSize(UINT nType, int cx, int cy) 
    {
    CView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    if (0 == cy)         // 防止被零除
    {
       cy = 1;          // 将Height设为1
    }

    glViewport(0, 0, cx, cy);      // 重置当前的视口
    glMatrixMode(GL_PROJECTION);     // 选择投影矩阵
    glLoadIdentity();        // 重置投影矩阵

    // 设置视口的大小
    gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f);
    glMatrixMode(GL_MODELVIEW);      // 选择模型观察矩阵
       glLoadIdentity();        // 重置模型观察矩阵
    }
        再运行一下,图形已经出来了。以后,就可以在DrawScene()写任何画图的代码了,当窗口重绘的时候,都可以自动适应。如果要做一段可以运动的3D图画,可以再捕获WM_TIMER消息,通过在OnCreate的时候定义一个时钟,再配合一些变量,就可以做简单的动画了。

    在MFC下初始化OpenGL编程环境 - 追寻 - 鸿蒙

    展开全文
  • Windows环境下Unicode编程总结 UNICODE环境设置安装Visual Studio时,选择VC++时需要加入unicode选项,保证相关的库文件可以拷贝到system32。 UNICODE编译设置:C/C++, Preprocessor difinitions 去除_MBCS...
  • VC++6.0环境下调试c语言代码的方法和步骤_附图

    万次阅读 多人点赞 2018-08-13 11:55:12
    1.C语言程序四步开发步骤 (1)编辑。可以用任何一种编辑软件将纸上编写好的C语言程序输入计算机,并将C语言源程序文件*.c以纯文本文件形式保存计算机的磁盘上(不设置字体、字号等)。
  • 什么是适应

    千次阅读 2018-06-23 04:30:19
    【智慧就是适应,是一种最高级形式的适应。动作是认识的源泉,是主客体相互作用的中介。图式即认知结构。同化是主体将环境中的信息纳入并整合到已有的认知结构的过程。同化表明主体改...
  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。 1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。 ...
  • Knewton适应性学习

    千次阅读 2018-06-21 10:40:29
    Knewton适应性学习 构造全球最强大的教育推荐... (原文:Ateaching method premised on the idea that the curriculum should adapt to eachuser.) 基础层次上,适应性学习的定义看起来很简单。但是更深入的...
  • 不得不说,codeproject是个好东西,昨天就一直查这个png按钮怎么用,很多人都在说这个老外写的GdipButton,可惜家里的网登不上,老外的网站不了。后来又找了个pngbutton,发现不能适应我按钮的大小,就又费劲找到...
  • Windows 环境下的OpenGL

    千次阅读 2012-04-25 11:51:04
    Windows NT的OpenGL除了具有基本的OpenGL函数外,还支持其他四类函数: 相应函数 具体说明 OpenGL实用库 43个函数,每个函数以glu开头。 OpenGL辅助库 31个函数,每个函数以aux开头。 ...
  • 系统环境变量对所有系统用户有效,用户环境变量仅仅对当前的用户有效。 文章转载自http://leonhongchina.blog.163.com/blog/static/180294117201132611320112/ 修改用户环境变量 用户环境变量通常被存储...
  • LinuxC语言开发环境的搭建

    千次阅读 2019-09-26 20:38:58
    等命令行模式的编辑器,它们功能强大,逼格够高,不管有没有桌面环境都能使用,是 LinuxC/C++ 程序员必备的神器。但是 Vim 和 Emacs 并不容易上手,使用者需要记忆很多命令和快捷键,熟练才能生巧,所以需要一段时间...
  • 本篇介绍Android/Ndk环境下FFmpeg的编译及使用, FFmpeg自带了H264、AAC、MP3的解码器,但却没有(或没有好的)相应的编码器。相应的编码器需要使用第三方库。推荐使用的第三方库为x264(H264编码) 、FDK_AAC(AAC...
  • 灾难环境下的Mobile应用构建及部署

    千次阅读 2008-05-20 19:04:00
    灾难环境下的Mobile应用构建及部署写这个题目绝对不是为了哗众取宠。看题目大家都会知道这篇文章的源头哪里,的确地震之后,我一直有一种无力感。IT系统无法快速切换到灾难状态,于是,很多的信息管理又再次回到...
  • 强化学习环境搭建

    千次阅读 2019-04-30 17:16:40
    强化学习环境搭建强化学习简介环境安装Anaconda安装安装DockerDocker介绍Docker安装Open...1.2.智能体的状态执行了一个动作后进入一个状态 1.3.环境会根据智能体的动作给予相应的奖惩 1.4.智能体根据环境给予...
  • eclipse如何配置android模拟器环境

    万次阅读 2012-11-02 23:39:46
    配置Android开发环境之前,首先需要了解Android开发对操作系统的要求。Android开发可以使用Windows XP、Windows Vista、Mac OS、Linux等操作系统,本书以Windows XP为例进行讲解。Android开发所需软件的版本及其下载...
  • VC++对话框适应不同分辨率

    千次阅读 2013-12-22 17:13:29
    关于对话框适应不同分辨率问题,主要分如下几步: 1.利用GetSystemMetrics(SM_CXSCREEN)函数获得当前屏幕的宽度和高度cx,xy。 2.分别判断分辨率大于或等于1024*768和分辨率只等于800*600的两种情况就分别做如下...
  • 搭建环境之前需要下载下面几个文件包: 一、安装Java运行环境JRE(没这个Eclipse运行不起来)和JDK  官网下载 http://www.oracle.com/technetwork/java/javase/downloads/index.html,  先装JRE,再装JDK
  • Ubuntu设置环境变量

    千次阅读 2013-03-28 15:18:41
    /etc/profile : 登录时,操作系统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。 /etc /environment : 登录时操作系统使用的第二个文件, 系统读取你...
  • 20款知名PHP集成环境推荐与优缺点分析、php环境大全推荐(PHP环境搭建包)、PHP环境搭建、PHP集成环境搭建,最好用的20个php环境搭建工具推荐
  • knewton适应性学习白皮书(1)

    千次阅读 2012-12-17 23:29:46
    原文地址:... Knewton适应性学习 ...适应性学习:一个以课程应该适应每一个用户的思想为前提的教学方法。 (原文:Ateaching method premised on the idea that t
  • 引言 ---- 银行的数字化监视监控系统是目前比较有市场及应用前景的开发项目,基于不同的MPEG采集卡与硬件外围设备开发的监视监控系统国内外有比较成型的技术。为了满足实时监视、实时采集压缩、随时回放、压缩...
  • 最近,问的比较多的问题居然是jdk的问题,对于新手来说这确实有点难度,毕竟一个人经常上网浏览新闻和观看视频的人,一子开始一门编程语言的环境搭建。这中间需要一个慢慢适应的过程。回想当初我这个阶段也很...
  • 远程全方位环境监测无人机系统

    千次阅读 2019-08-01 01:52:00
    随着我国城市化、工业化进程的迅速推进,人民生活水平的快速提高,国家与社会开始越来越关注周边环境的保护。当前,我国多地区面临大气环境质量改善巨大压力。国务院也相继印发了《打赢蓝天保卫战三年行动计划》《水...
  • 第十章《跟忧虑说再见》一、忧虑是健康的大敌1、焦虑和烦躁不安的人,多半不能适应现实的世界,而跟周围的环境隔断了所有的关系,缩到了自己的梦想世界,以此解决他所忧虑的问题。 2、最使你轻松愉快的是,健全的...
  • 今天突然想玩一玩苹果的Mac OS系统,由于没钱买苹果机,只好通过虚拟机来装一个玩玩,说干就干,开始走起。...由于苹果的操作系统不管是镜像格式,还是引导方法上,与windows和linux系统存在...
  • knewton适应性学习白皮书(2)

    千次阅读 2012-12-18 12:12:52
    5. 大数据和适应性结构 大数据的概念被用来描述数量巨大的卷,速度,和通过各种各样的技术平台产生的各种各样的数据,其中很多包含连续的或者普遍存在的数据集。大数据特别指那些特别大的,复杂的,难以用传统的...
  • 调测工具VcTester攻略--搭建运行环境

    千次阅读 2010-03-10 14:04:00
    调测工具VcTester攻略之搭建运行环境作者:网际游民,成稿于2010年1月 关于VcTester工具VcTester由ezTester公司推出,是业界众多VC调测辅助工具中功能最强悍的一款,为准确起见,我还是加上“之一”后缀,尽管...
  • 但是exe文件没有安装jre的电脑上不运行,如果要求客户再去安装jre 设置环境变量 就不雅了。我们需要将jre打包。 这几步操作网上介绍的插件和方法很多,但有的好用有的不好用,而且有的还需要注册。经过尝试比较...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 164,585
精华内容 65,834
关键字:

在任何环境下都能适应