0%

版本说明

  • Mac OS X : 10.12.6
  • GLFW : 3.2.1
  • GLEW : 2.1.0

工具准备

  1. 下载安装 Xcode

  2. 安装 Command Line Tool

    1
    $ xcode-select --install 
  3. 下载安装 GUI 版的 CMake

简述

  • OpenGL:(英语:Open Graphics Library)是用于渲染2D3D 矢量图形的跨语言、跨平台(由 Khronos组织 制定并维护)的**规范(Specification)**。
  • GLFW:是一个专门针对 OpenGLC 语言库,提供了渲染物体所需的最低限度的接口。其允许用户创建 OpenGL 上下文,定义窗口参数以及处理用户输入,把物体渲染到屏幕所需的必要功能。(注意:OpenGL 并不规定窗口创建和管理的部分,这一部分完全交由 GLFW 来实现;还有其他类似的:GLUTSDL 等)。
  • GLEW:由于 OpenGL 只是一种 标准/规范,并且是由驱动制造上在驱动中予以实现。OpenGL 的大多数函数在编译时(compile-time)是未知状态的,需要在运行时(run-time)来请求。GLEW 的工作就是获取所需的函数的地址,并储存在函数指针中供使用。(还有其他类似的:GLAD)。
  • GLAD:是一个开源的库,功能跟 GLEW 类似。GLAD 使用了一个在线服务(在这里能够告诉 GLAD 需要定义的 OpenGL 版本,并且根据这个版本加载所有相关的 OpenGL 函数)。
  • SOIL:大多数图形学处理的任务都需要读取图片到内存当中。当前存在着各种各样的图片格式,例如 jpeg, bmp, png 等等;SOIL 提供了将图片加载到内存当中的功能,避免了因繁杂的图片格式读取问题。
  • GLM:提供了大量的矩阵变换,向量变换以及各种针对矩阵和向量的计算操作。

GLFW编译安装

  1. 下载GLFW源码,并解压。

  2. 打开CMake,选择 源代码目录目标文件目录

  3. 点击**Configure(设置)**按钮,让CMake读取设置和源代码,然后选择工程的生成器 Unix Makefiles

  4. CMake会显示可选的编译选项用来配置最终生成的库。这里使用默认设置,并再次点击Configure(设置)按钮保存设置。

  5. 保存之后,点击Generate(生成)按钮,生成的工程文件会在 Build 文件夹中。

  6. 打开终端,cd 进入 Build目录

    1
    $ cd GLFW_Build
  7. 执行 make 命令进行编译安装库文件。

    1
    $ make

  8. 执行 make install 命令进行安装,一般会安装到 /usr/local/include/usr/local/lib 中。

    1
    $ make instll

  9. 查看一下 /usr/local/include

    • 安装前:
    • 安装后:
  10. 查看一下 /usr/local/lib

    • 安装前:
    • 安装后:

至此,Mac OS X 下的 GLFW 环境已经配置好了

GLEW 编译安装

阅读全文 »

OpenGL

  • OpenGL:(英语:Open Graphics Library)是用于渲染2D3D 矢量图形的跨语言、跨平台(由 Khronos组织 制定并维护)的**规范(Specification)**。

图片来源于 www.opengl.org/

OpenGL 规范严格规定了每个函数该如何执行以及输出值;至于具体每个函数内部是如何实现的,将由编写 OpenGL 库的人(通常是显卡的生产商)自行决定。

立即渲染模式(Immediate mode)

早期的 OpenGL3.2 版本以前)使用立即渲染模式(即固定渲染管线),但其大多数功能都被库隐藏起来,很少能控制 OpenGL 如何进行计算的自由。

核心模式(Core-profile)

当使用 OpenGL3.3 版本开始)的核心模式时,OpenGL 迫使开发者使用现代的函数;当开发者试图使用一个已废弃的函数时,OpenGL 会抛出一个错误并终止绘图。

状态机(State Machine)

OpenGL 自身是一个巨大的状态机:一系列的变量描述 OpenGL 此刻应当如何运行;OpenGL 的状态通常被称为 OpenGL **上下文(Context)**。

阅读全文 »

变量的不同类型,决定了其生命周期及其作用域。

extern

extern 可以用来修饰变量,也可以用来修饰函数。

  1. 对于函数来说,既可以是声明一个外部函数,也可以是定义一个函数;如:
  • 例子一:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // test.c    
        
    #include <stdio.h>    
        
    void test()    
    {    
       printf("我是来自源文件test.c中的test函数!");    



    //main.c    
        
    #include <stdio.h>    
        
    extern void test();  //声明一个外部函数test    
        
    int main()    
    {    
           test();   //调用test.c中的函数test    
        
           return 0;    
    }    
  • 例子二:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // test.c    
        
    #include <stdio.h>    
        
    extern void test()  //定义一个函数    
    {    
          printf("我是来自源文件test.c中的test函数");    
    }  


    // main.c  
      
    #include <stdio.h>    
        
    extern void test();  //声明一个外部函数test    
        
    int main()    
    {    
           test();   //调用test.c中的函数test    
        
           return 0;    
    }  
  1. 对于变量来说,只能用来声明变量,而**不**可以定义变量;如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //test.c    
        
    #include <stdio.h>    
        
    int a;  //定义一个变量a    
        
    void test ()    
    {    
           printf("a = %d",a);    



    //main.c    
        
    #include <stdio.h>    
        
    extern int a;   //声明一个外部变量a ,这里不是定义变量    
    extern void test();   //声明一个外部函数test    
        
    int main()    
    {    
          a = 10;    
          test();    
        
          return 0;    

static

static 可以用来修饰变量,也可以用来修饰函数。

  1. 对于函数来说,可以定义一个内部函数;如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    //test.c    
        
    #include <stdio.h>    
        
    static void test()    //定义一个内部函数    
    {    
          printf("我是test.c中的内部函数,其他文件无法访问。");    
    }


    //main.c    
        
    #include <stdio.h>    
        
    extern void test();   //声明一个外部函数test,以便main.c文件可以访问    
        
    int main()    
    {    
            test();    //这里调用外部函数test    
        
            return 0;    

这里编译是没有错误,运行时就会报错,因为main中的test()函数找不到定义。

阅读全文 »

拿硬币问题

  • 问题:16个硬币,A和B轮流拿走一些,每次拿走的个数只能是124中的一个数。谁最后拿硬币谁输。请问:A或B有无策略保证自己赢?

  • 解答:B可以保证自己赢。

    1
    2
    3
    4
    5
    6
    1. 如果A拿 1 个,则B拿 2 个;
    2. 如果A拿 2 个,则B拿 1 个;
    3. 如果A拿 4 个,则B拿 2 个。
    4. 这样每次AB加起来都是 3 或者 6 ,所以最后会剩下 1 个或 4 个。
    5. 如果是 1 个则A直接输了;
    6. 如果剩下 4 个,A全拿则输了,如果不全拿,B继续采取上面的策略,最后还是剩下 1 个,还是A输。

分蛋糕问题

  • 问题:请把一盒蛋糕切成8份,分给8个人,但蛋糕盒里还必须留有一份。
  • 解答:把切成的8份蛋糕先拿出7份分给7人,剩下的1份连蛋糕盒一起分给第8个人。

火车运煤问题

  • 问题:你是山西的一个煤老板,你在矿区开采了有 3000 吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大,每一公里需要耗一吨煤。请问,怎么运送才能运最多的煤到集市?

  • 解答: 。

    1
    2
    3
    4
    1. 装 1000 吨煤,走 250 公里,扔下 500 吨煤,回矿山;
    2. 装 1000 吨煤,走到 250 公里处,拿起 250 吨煤继续向前到 500 公里处,扔下 500 吨煤,回矿山。此时火车上还有 250 吨,再加上在 250 公里处还有 250 吨煤,所以,火车是可以回矿山的;
    3. 装上最后 1000 吨煤,走到 500 公里处,装上那里的 500 吨煤,然后一直走到目的;
    4. 由此,最多可以运送 500 吨煤到市场(当然,火车也回不去了,因为那矿山没有煤了)。

箱子开锁问题

  • 问题:A、B两人分别在两座岛上。B生病了,A有B所需要的药。C有一艘小船和一个可以上锁的箱子。C愿意在A和B之间运东西,但东西只能放在箱子里。只要箱子没被上锁,C都会偷走箱子里的东西,不管箱子里有什么。如果A和B各自有一把锁和只能开自己那把锁的钥匙,A应该如何把东西安全递交给B?

  • 解答:

    1
    2
    3
    4
    1. A 把药放进箱子,用自己的锁把箱子锁上;
    2. B 拿到箱子后,再在箱子上加一把自己的锁;
    3. 箱子运回 A 后,A 取下自己的锁;
    4. 箱子再运到 B 手中时,B 取下自己的锁,获得药物。

吃药片问题

  • 问题:某种药方要求非常严格,你每天需要同时服用A、B两种药片各颗,不能多也不能少。这种药非常贵,你不希望有任何一点的浪费。一天,你打开装药片A的药瓶,倒出一粒药片放在手心;然后打开另一个药瓶,但不小心倒出了两粒药片。现在,你手心上有颗药片A,颗药片B,并且你无法区别哪个是A,哪个是B。你如何才能严格遵循药方服用药片,并且不能有任何的浪费?

  • 解答:

    1
    2
    3
    4
    1. 把手上的三片药各自切成两半,分成两堆摆放;
    2. 再取出一粒药片 A,也把它切成两半,然后在每一堆里加上半片的 A;
    3. 现在,每一堆药片恰好包含两个半片的 A 和两个半片的 B;
    4. 一天服用其中一堆即可。 
阅读全文 »

分金条问题

  • 问题: 你让工人为你工作7天,回报是一根金条,这个金条平分成相连的7段,你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如何给你的工人付费?

  • 解答:切两刀,分为1/72/74/7三段。

    1
    2
    3
    4
    5
    6
    7
    第一天给 1/7;
    第二天给 2/7,要回 1/7;
    第三天给 1/7 ;
    第四天给 4/7 要回 1/7 + 2/7;
    第五天给 1/7;
    第六天给 2/7,要回 1/7;
    第七天给 1/7

飞鸟问题

  • 问题:有一辆火车以每小时 15 公里的速度离开北京直奔广州,同时另一辆火车每小时 20 公里的速度从广州开往北京。如果有一只鸟,以 30 公里每小时的速度和两辆火车同时启动,从北京出发,碰到另一辆车后就向相反的方向返回去飞,就这样依次在两辆火车之间来回地飞,直到两辆火车相遇。请问,这只鸟共飞行了多长的距离?
  • 分析:鸟在火车相遇前一直在飞,所以不论它如何往返,鸟飞的距离就是其速度乘时间,而时间则是用两列火车相遇的时间。设北京到广州的距离为 D,那么火车相遇时间是:D / (15+20),由此可得鸟飞的距离是:30 * 时间 = 30/35 * D。
  • 解答:北京到广州距离的 30/35

药丸问题

  • 问题:你有四个装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的药丸的重量+1。只称量一次,如何判断哪个罐子的药被污染了?
  • 解答: 依次从四个罐子中取出1、2、3、4个药丸,设第一丸子应重为X,称得的重量是10X+tt是几就是第几个罐子污染了。

开关问题

  • 问题:门外三个开关分别对应室内三盏灯,线路良好,在门外控制开关时候不能看到室内灯的情况,现在只允许进门一次,确定开关和灯的对应关系?
  • 解答:设三个开关是1、2、3。打开开关1等半个小时,关上开关1并打开开关2。进房后去摸灯泡,热的是开关1对应的灯泡;亮的是开关2对应的灯泡;不亮不热的是开关3对应的灯泡。

人民币问题

  • 问题:人民币为什么只有12510的面值?
  • 解答:可以用三张以内组成任何面额。
阅读全文 »

安装 Xcode

这个就不用多说了,直接从 App Store 上下载安装。

安装 Homebrew

Homebrew:是 Mac 平台上的一个包管理工具,提供了许多 Mac 下没有的 Linux工具等,
而且安装工具极其简单,一句命令行的事。

  1. 检查是否已安装 Homebrew,只需在终端输入:

    1
    $ brew
  2. 得到如图结果,说明已经安装,否则需要安装。

  3. 安装 Homebrew ,在终端输入:

    1
    $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

编译 iOS 版可用的 FFmpeg库

需要用到的工具:

  1. gas-preprocessor
  2. yasm
  3. FFmpeg-iOS-build-script

下载 gas-preprocessor

gas-preprocessor 就是我们要编译 FFmpeg 的所需脚本文件。

  1. 将其解压后,其内部只有简单的 4 个文件,如下图:

  2. gas-preprocessor.pl 文件复制到 /usr/local/bin/ 目录下,然后为文件开启可执行权限:

    1
    $ chmod 777 /usr/local/bin/gas-preprocessor.pl
阅读全文 »

编译器属性 __attribute__ 用于向编译器描述特殊的标识、检查或优化。

__attribute__ 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。

修饰函数

constructor

使用 constructor 属性修饰函数,使该函数能够在 main() 函数之前执行。

main.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//
// main.m
// Test__attribute__
//
// Created by shenyuanluo on 2017/4/21.
// Copyright © 2017年 shenyuanluo. All rights reserved.
//


#import <Foundation/Foundation.h>

__attribute__((constructor)) void testConstructor()
{
NSLog(@"使用‘constructor’修饰函数,将执行在 ‘main’ 函数之前");
}


int main(int argc, const char * argv[]) {
@autoreleasepool {

NSLog(@"'Main' 函数开始执行");
}
return 0;
}

运行结果:

1
2
3
2017-04-21 20:14:02.640374+0800 Test__attribute__[1575:31682] 使用‘constructor’修饰函数,将执行在 ‘main’ 函数之前
2017-04-21 20:14:02.640589+0800 Test__attribute__[1575:31682] 'Main' 函数开始执行
Program ended with exit code: 0

destructor

阅读全文 »

创建 CSR 文件

CSR证书签名请求(Certificate Signing Request)的缩写。

  1. 打开 钥匙串 ——> 钥匙串访问 ——> 证书助理 ——> 从证书颁发机构请求证书

    创建CSR

  2. 填写相关信息:开发者账号 ——> CSR密钥文件名 ——> 存储本地磁盘

    创建CSR

  3. 选择本地路径保存 CSR 文件

申请推送证书

  1. 登录开发者中心

  2. 选择打开 APP ID相关信息,搜索 Push Notifications 字段

    创建CSR

    创建CSR

    这一步也可以验证推送证书是否已经制作,如下图:

    创建CSR

  3. 选择 Create Cerfificate

    创建CSR

  4. 上传刚刚创建的 CSR 文件

    创建CSR

  5. 创建完成后,下载该证书备用

    创建CSR

  6. 至此,推送证书已经创建成功

    创建CSR

    其中:

    • CertificateSigningRequest.certSigningRequestCSR 文件
    • aps_development.cer测试推送证书
    • aps.cer发布推送证书

提示:测试推送证书发布推送证书 的制作流程一样,这里就不重复说了。

安装推送证书

  1. 双击安装刚刚下载的 aps_development.ceraps.cer 文件

  2. 安装成功后,会在钥匙串生成相关的信息,如:

    创建CSR

导出 p12 文件

  1. 打开钥匙串,找到安装成功的推送证书

  2. 点击前面的 三角号 展开密钥,分别对 cerkey 导出对应的 p12 文件

  3. 扩展后右击 Apple Development Push Services ——> 导出 "Apple Development Push Services 。。。"。 ——> 保存为 apns-dev-cert.p12 文件

    创建CSR

    创建CSR

    创建CSR

  4. 右击对应的 Private Key ——> 导出。。。 ——> 保存为 apns-dev-key.p12 文件

    创建CSR

阅读全文 »

================== 更新【2018-09-10】–- Start ==================

添加阅读排行榜

基于 leancloud 的数据实现在本站文章的阅读排行榜。

Top 页面添加

cd 进入博客根目录,输入 hexo n page top,将会在 source 生成 top 目录,编辑其中自动生成的 index.md 文件,将其中的代码替换如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id="top"></div>
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
<script>AV.initialize("leancloud_appid", "leancloud_appkey");</script>
<script type="text/javascript">
var time=0
var title=""
var url=""
var query = new AV.Query('Counter');
query.notEqualTo('id',0);
query.descending('time');
query.limit(1000);
query.find().then(function (todo) {
for (var i=0;i<1000;i++){
var result=todo[i].attributes;
time=result.time;
title=result.title;
url=result.url;
// var content="<a href='"+"https://shenyuanluo.github.io"+url+"'>"+title+"</a>"+"<br>"+"<font color='#fff'>"+"阅读次数:"+time+"</font>"+"<br><br>";
var content="<p>"+"<font color='#1C1C1C'>"+"【阅读量: "+time+" 】"+"</font>"+"<a href='"+"https://shenyuanluo.github.io"+url+"'>"+title+"</a>"+"</p>";
document.getElementById("top").innerHTML+=content
}
}, function (error) {
console.log("error");
});
</script>

并将其中的 leancloud_appid**、leancloud_appkey** 和 https://shenyuanluo.github.io 替换为自己对应的即可。

菜单显示设置

  1. 菜单显示

    编辑主题配置文件 _config.yml,搜索 menu: 字段,添加 top 字段。

  2. 图标设置:

    编辑主题配置文件 _config.yml,搜索 menu_icons: 字段,添加 top: signal。其中 signal 是对应的图标,可以自行到 Font Awesome 搜索自己喜欢的图标,并替换相应的名称即可。

  3. 语言适配

    编辑hexo/theme/你的主题/languages/zh-Hans.yml 文件,添加 top 对应的中文:
    top:阅读排行

================== 更新【2018-09-10】–- End ==================

阅读全文 »

上一篇博文已经介绍了在 Mac 平台下搭建 Github+Hexo 博客的流程。本文来介绍一些常用的对 Hexo+Next 博客的基础设置。

  1. 注意配置文件选择:
    站点配置文件:是安装的 hexo 博客目录,如 ~/userName.github.io 目录下的 _config.yml 文件。
    主题配置文件:是选定的主题,如 themes/next 目录下的 _config.yml 文件。
  2. 配置文件 yml 的注释是 #
  3. 如果没有特殊说明,本文提到的 bash 命令均是在站点根目录下执行,如:~/userName.github.io/

头像设置

  1. 编辑主题配置文件 _config.yml, 搜索字段 avatar,设置头像图片文件连接
    a. 完整互联网地址:https://yoursite.com/avatar.png
    b. 站内地址: 将头像图片放置在 ~/userName.github.io/source/images/ 目录下,设置为:avatar: /images/avatar.png (如 images 目录不存在,则需新建)

    头像

    头像设置

设定站点创立时间

  1. 编辑站点配置文件 _config.yml,新增字段 since

    1
    $ since: 2017

Next主题的Scheme设置

  1. 编辑主题配置文件 _config.yml, 搜索字段 scheme,将需用启用的 scheme 前面注释 # 去除即可。(有三种:MuseMistPisces系统默认使用 Muse)

    Scheme设置

Next 主题侧边栏设置

  1. 编辑主题配置文件 _config.yml,搜索字段 sidebar,如图:

    Sidebar设置

    a. 设置侧栏的位置,修改 sidebar.position 的值,支持的选项有:

    • left : 靠左放置

    • right : 靠右放置

      注意:此配置只适用于 SchemePisces,在 MistMuse 下无效。

    b. 设置侧栏显示的时机,修改 sidebar.display 的值,支持的选项有:

    • post : 默认行为,在文章页面(拥有目录列表)时显示
    • always : 在所有页面中都显示
    • hide : 在所有页面中都隐藏(可以手动展开)
    • remove : 完全移除
阅读全文 »