这是用户在 2025-4-6 22:39 为 https://app.immersivetranslate.com/html/ 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

CG week5.1.1 2025.03.31 Mon PM 1:04 ・ 54Minutes 3seconds ZHANG YIWEN
CG 第 5.1.1 课 2025.03.31 周一 下午 1:04 · 54 分钟 3 秒 张一文

Attendees 1 00:00 이번 시간에는 과제하는 데 조금 여러분 도움을 줄 수 있도록 이제 glut 관련된 프로그래밍 내용을 조금 더 소개를 한번 해보도록 할게요. 그래서 이번 시간에 우리 공부할 내용은 이제 GLT 콜백 콜백 함수들 여러 가지 종류가 있는데 그중에서 이제 많이 사용되는 콜백 함수들에 대해서 사용 방법에 대해서 한번 학습을 하는 게 목표예요. GLT라는 거는 우리 저기 학기 초반에 많이 설명을 했었죠. 그래서 프로그래밍 인터페이스고
参与人数 1 00:00 这节课我将为大家介绍一些关于作业的帮助,并详细介绍 GLUT 相关的编程内容。我们这节课学习的目标是了解各种 GLUT 回调函数,特别是一些经常使用的回调函数的使用方法。我们在学期初已经多次提到过 GLUT,它是一个编程接口

Attendees 1 00:44 윈도우를 생성하고 제일 크리에이트 윈도우 하면 윈도우 생성한다고 했었죠. 그래서 윈도우를 생성하고 관리하는 역할을 주로 담당을 하고 그다음에 키보드나 마우스와 같은 입출력 장치로부터 전달되는 입력을 처리하는 역할을 해줘요. glut 같은 경우는 하드웨어나 OS 플랫폼에 독립적이라는 장점이 있다고 했죠. 그래서 제 다운로드 받거나 API 관련된 함수 더큐멘테이션을 인터넷으로 검색을 할 수가 있을 거예요. 첫 번째 그래서 윈도우 콜백 함수부터 보면은 이거는 이제 윈도우 콜백 함수는 윈도우와 관련된 콜백 함수들이에요. 윈도우와 관련된 게 뭐가 있을까? 우리 크리에이트 윈도우 하면은 윈도우가 어떻게 돼요? 처음에 없던 윈도우가 만들어지죠. 그래서 처음에 윈도우가 이제 생성될 때 혹은 여러분이 마우스로 윈도우 끝쪽을 잡아가지고 이렇게 사이즈를 줄이거나 늘리거나 할 수 있죠.
与会者 1 00:44 创建窗口,当我们创建窗口时,就会生成窗口。因此,它主要负责创建和管理窗口,然后处理来自键盘和鼠标等输入设备的输入。我们之前提到,GLUT 具有硬件和操作系统平台独立的优点。因此,您可以在互联网上下载或搜索 API 相关函数的文档。首先,看看窗口回调函数,这些是与窗口相关的回调函数。窗口相关的有什么呢?当我们创建窗口时,窗口会发生什么变化?最初不存在的窗口被创建。因此,当窗口最初被创建时,或者您可以用鼠标抓住窗口的边缘并调整其大小时。

Attendees 1 01:46 그럴 때 즉 윈도우와 관련된 어떤 이벤트가 발생됐을 때 호출되는 콜백 함수를 윈도우 콜백 함수라고 하죠. 그래서 콜백 함수는 자동으로 호출된다고 전에 이야기를 했었죠. 그렇기 때문에 우리가 이거를 자동으로 호출하기 위해서는 시스템에 등록을 해줘야 돼요. 시스템에 등록을 해줘야 되는데 윈도우 관련된 이벤트를 처리하는 함수를 등록하기 위해서는 glut 시스템에서 glut 리 쉐잇 펑크라는 함수를 써요. 리쉐이 펑션 이게 이제 glut에서 사용하는 등록 함수예요. 등록 함수. 그럼 여기다가 인자로 넣어줘야 되는 건 뭘까? 인자로 넣어줘야 되는 것은 마우스가 왜 자기 마음대로 안 보이죠?
与会者 1 01:46 那么,当发生与窗口相关的某些事件时,被调用的回调函数称为窗口回调函数。我们之前已经说过,回调函数是自动调用的。因此,为了自动调用它,我们需要在系统中注册。要注册处理窗口相关事件的函数,在 GLUT 系统中使用 GLUT 重新调整函数(glutReshapeFunc)。这是 GLUT 使用的注册函数。那么,要作为参数传入的是什么呢?参数是什么呢?为什么鼠标不会自动显示?

Attendees 1 02:47 바닥에 색깔이 검정색이 있어 가지고 그런 거 같네요. 인자로 넣어줘야 되는 것은 뭘까요? 이제 등록할 함수에 이름을 넣어줘야 돼요. 등록할 함수에 이름을 넣어주는데 아무 함수나 넣어주면 안 되고 프로토타입 여러분 함수의 프로토타입 뭔지 알죠? 리턴 타입은 뭐고 함수의 이름은 상관없어요. 함수의 이름은 상관없고 리턴 타입은 어떤 타입 오이드 타입이고 함수의 이름은 상관없어요. 그다음에 인자는 두 개를 받아야 돼요. 하나는 위드스 그리고 두 번째 인자는 하이트. 여기와 높이를 받을 수 있는 함수를 등록을 시켜줘야 돼요. 그래서 설명을 보면 윈도우가 처음 생성되거나 윈도우의 크기가 변경될 때 시스템에 의해서 자동으로 호출되는 콜백 함수를 등록하는 기능을 해준다. 누가 gut 뉴셰 펑션이 그래서 파라미터로 전달하는 거는 등록할 함수의 이름이라고 했죠. 함수의 이름은 함수에 뭘까요?
与会者 1 02:47 地板上有黑色,看起来是这样。需要传递的参数是什么?现在需要在注册函数中输入函数名。注册函数时输入函数名不能随意,你们知道函数的原型吗?返回类型是什么,函数名无所谓。函数名无关紧要,返回类型是 void 类型,函数名不重要。接下来需要接收两个参数。一个是宽度,第二个参数是高度。需要注册一个可以接收宽度和高度的函数。因此,从说明来看,这是一个在窗口首次创建或窗口大小发生变化时由系统自动调用的回调函数注册功能。是谁的 GLUT 重设函数?传递的参数是要注册函数的名称。那么函数的名称是什么?

Attendees 1 03:51 함수의 시작 주소나 마찬가지예요. 배열의 이름이 배열의 시작 주소와 마찬가지인 것처럼 함수의 이름은 함수의 포인트나 마찬가지다. 그다음에 콜백 함수 등록할 함수의 파라미터는 w는 윈도우에 변경된 너비 h는 윈도우에 변경된 노키 이렇게 등록을 해줘야 돼요. 그래서 이거 한번 볼까요? 우리 초대에서는 어떻게 돼 있나 메인 함수 보면은 glut 초기화하죠. glet 초기화에서 지난번 argc argv가 어떤 의미를 갖고 있다고 얘기를 했었죠. 그래서 이거를 초기화하고 그다음에 glut 이니트 윈도우 사이즈는 뭐 하는 함수 같아요. 이제 생성할 윈도우의 크기를 결정해 주는 거라고 했죠. 여기 위데스하고 하이트는 아마 저녁 변수로 800하고 600이네요. 800바이 600짜리 윈도우를 만들 거고 그다음에 이니트 윈도우 포지션은 0 콤마 0 하면은 여기 좌측 상단에 이제 윈도우를 띄우겠다는 얘기예요. 해줘도 되고 안 해줘도 되겠죠.
与会者 1 03:51 函数名就是函数的起始地址,就像数组名是数组的起始地址一样,函数名就是函数指针。然后,回调函数注册函数的参数 w 是窗口变更的宽度,h 是窗口变更的高度,就是这样注册的。那么让我们来看看?在我们的示例中是怎样的?查看主函数,首先进行 GLUT 初始化。上次我们讨论过 argc 和 argv 具有什么意义。初始化后,接下来是 GLUT 初始化窗口大小的函数。现在是用来确定要创建的窗口大小。这里的宽度和高度大概是变量 800 和 600。将创建一个 800x600 的窗口,然后初始化窗口位置为 0,0,意味着将在左上角显示窗口。可以这样做,也可以不做。

Attendees 1 04:59 그다음에 ju티 디스플레이 모드는 내가 사용할 칼라 버퍼의 타입을 정해준다고 했었죠. 그래서 rgba 버퍼 그다음에 버퍼를 하나 더 쓰고 싶으면은 glut 더블 보시면 되고 지금은 그냥 하나만 쓸게요. 그다음에 여기서 이제 glut 크리에이트 윈도우 요 함수가 뭐였어요? 윈도우를 실제 만드는 함수죠. 그러면 이때 윈도우가 만들어지면서 여기 이제 콜백 함수로 밑에 등록된 함수들 중에서 어떤 함수가 노출이 될까요? 여기 glut 리 쉐이 펑션에 의해서 리 쉐입이라는 함수를 등록을 시켰죠. 리s이라는 함수 이름이에요. 이거 함수의 이름 함수의 프로토타입 원형으로 한번 한번 가보면은 리턴 타입이 뭐예요? 리턴 타입은 보이드죠. 그다음에 인자로 뭘 받아요? w하고 h를 받는 함수예요. 함수의 이름은 리쉐입이라고 해도 되고 그냥 a라고 해도 되고 b라고 해도 돼요. 함수의 이름은 상관없지만 뭘 맞춰줘야 돼요?
接下来,ju 颜色显示模式可以确定我将使用的颜色缓冲区类型。所以是 rgba 缓冲区,如果你想再使用一个缓冲区,可以看看 glut 双缓冲,现在我们就使用一个。然后这里的 glut 创建窗口函数是什么?是实际创建窗口的函数。那么,窗口创建时,这里注册的回调函数中哪个函数会被调用呢?这里通过 glut reshape 函数注册了 reshape 函数。这是函数名字。如果查看这个函数的原型,返回类型是什么?返回类型是 void。然后它接收什么参数?它接收 w 和 h 两个参数。函数名可以是 reshape,也可以是 a 或 b。函数名无所谓,但是要注意什么?

Attendees 1 06:03 함수의 프로토타입을 맞춰줘야 된다는 얘기죠. 함수의 프로토타입이라는 것은 반환형과 인자 리스트를 얘기하는 거예요. 그래서 리턴 타입은 반드시 보이드가 돼야 되고 인자로는 인트의 위드스와 인트의 하이트를 갖는 함수를 어디에다 등록을 시켜줘야 돼요. 리쉐이 벙크에다가 등록을 시켜줘야 된다는 얘기예요. 그래서 여기 이제 리쉐입이라는 함수를 등록을 했어요. 여기다가 선언했고 우리가 등록했고 그다음에 실제 구현을 한번 가볼까요? 구현 어디 있을까? 여기 구현이 이렇게 돼 있네요. 그래서 리쉐이비에서는 뭐 해준다고 했나 뷰 포트 그림 그려진 거를 윈도우에 꽉 채워주게 그려준다고 했었죠. 나중에 다시 설명을 할 거예요. 그다음에 요 위데스와 하이트를 저녁 변수 위드스와 화이트 이때 얼마가 들어갈까 여기 위드스와 화이트에는 800과 600짜리 넣었으니까 800하고 600이 전달이 되겠죠 이거 한번 출력을 해볼까요? 프린트 f 리쉐잇 디즈 콜드 에피트요.
意思是要匹配函数原型。函数原型指的是返回类型和参数列表。所以返回类型必须是 void,参数必须是 int 类型的宽度和高度。要将这个函数注册在哪里?必须注册在 reshape 函数中。所以现在已经注册了 reshape 函数,我们已经声明并注册,接下来让我们看看实际实现。实现在哪里?看,实现是这样的。在 reshape 函数中,它会做什么?将绘制的视口填充整个窗口,稍后我会详细解释。然后这个宽度和高度,晚上变量宽度和高度,这时会传入多少?因为我们在宽度和高度中放入了 800 和 600,所以 800 和 600 会被传递。我们来输出一下,打印 f reshape 这个调用。

Attendees 1 07:18 그다음에 여기다가 괄호 열고 퍼센트 d 금마 퍼센트 d에서 적수 신 뭘 찍어줄까? w하고 h를 한번 찍어볼게요. 정말 이 리쉐이 함수가 이제 호출이 되는지를 볼 거예요. 그래서 프로그램을 시작을 시키면은
接着在这里打开括号,加上百分比 d,金马百分比 d,我们来打印什么?我将打印 w 和 h。我真的要看看这个重塑函数是否被调用。所以当我们启动程序时

Attendees 1 07:59 여기 리쉐이 이즈 콜드 이렇게 돼 있죠? 맨 처음에 800바이 600짜리가 이제 만들어진 거고 이 사이즈가 이제 변경이 돼가지고 이렇게 만들어진 호출이 되는 거예요. 내가 여기 마우스로 끝에를 잡고 이렇게 줄이면 어떻게 될까요? 윈도우의 크기가 변경이 되고 있는 거죠. 윈도우의 크기가 변경이 되고 있으니까 리쉐이 품수가 계속 호출이 되는 거예요. 계속 호출이 돼서 리쉐이 스쿼드 한 다음에 윈도우의 사이즈 이 윈도우의 사이즈는 얼마일까? 어디에 전달이 될까요? w하고 화이트에 전달이 되겠죠.
这里的重塑函数就是这样的,对吧?一开始是 800 乘 600 的大小,现在这个尺寸已经发生了变化,这就是调用的方式。如果我用鼠标抓住边缘并缩小,会发生什么?窗口的大小正在改变。因为窗口的大小在变化,所以重塑函数不断被调用。不断被调用后,重塑后,窗口的大小是多少?它将传递到哪里?w 和 h 将被传递。

Attendees 1 08:36 그래서 이 리쉐이 펑크에 의해서 등록된 함수는 내가 호출하지 않아도 이벤트가 발생하면은 자동으로 호출되는 함수이다라고 이해를 하면 될 것 같아요. 처음 생성될 때랑 이렇게 마우스 트랙으로 사이즈 변경될 때 됐나요? 제 어려운 거 없죠?
这些通过重塑函数注册的函数,即使我不调用,也会在事件发生时自动被调用。我理解得对吗?是在窗口初次创建或者通过鼠标拖拽改变大小时触发吗?我没有理解错吧?

Attendees 1 08:59 두 번째 윈도우 콜백 함수는 윈도우가 처음 생성되거나 크기가 변경될 때 노출되는 함수가 첫 번째 함수였고 두 번째 함수는 이제 윈도우에 뭔가 디스플레이 그림을 그릴 때 자동으로 호출되는 함수예요. 그래서 화면에 그리는 콜백 함수를 시스템에 등록하는 게 바로 glut 디스플레이 펑크라는 함수예요. 얘는 프로토 타입이 어떻게 될까요? 얘는 프로토 타입이 리턴 타입은 보이드예요. 반환형은 보이드고 없다는 얘기죠. 그다음에 함수의 이름은 여러분이 적당히 주면 돼요. 보통 디스플레이라고 주거나 아니면 랜더라고 많이 주겠죠. 함수의 이름은 적당히 주면 되고 그다음에 얘는 인자로 인자로 특별하게 받아들일 게 없어요. 특별하게 받아들일 게 없는 함수를 등록을 할 거예요. 그래서 파라미터는 펑크는 콜백 함수의 이름 혹은 포인트가 되고 콜백 함수의 파라미터는 없다 그런 얘기예요. 그래서 우리 실제 코드에서는 어떻게 등록했나 한번 볼게요.
第一个窗口回调函数是在窗口初次创建或大小改变时被调用,第二个函数是在窗口需要绘制图形时自动调用的函数。所以,这是在系统中注册绘制屏幕的回调函数,也就是 GLUT 显示函数。它的原型是什么?返回类型是 void,意味着没有返回值。函数名可以自己任意起,通常叫"display"或"render"。这个函数不需要特别的参数,所以回调函数的参数是没有的。让我们看看在实际代码中是如何注册的。

Attendees 1 10:11 이거죠. 이거 glut 이거 안 보이나요? 뒤에서 크게 할게요. 그러면 glup 디스플레이 펑크에서 디스플레이라는 함수를 호출했네요. 디스플레이를 등록을 했네요. 디스플레이 함수 가보면은 리턴 타입이 뭐예요? 리턴 타입은 보이드고 함수의 이름은 디스플레이고 인자로는 아무것도 안 봤죠 이런 함수를 등록을 해줘야 된다는 얘기예요. 함수의 이름은 바꿔도 돼요 뭐로 랜더로 바꿔볼게요? 랜더가 보통 이제 그리기 함수니까 그래서 랜더로 이름을 바꾸고 그다음에 여기도 바꿔야겠죠. 랜더로 랜더로 바꿔야 되겠고 그다음에 실제 구현에서도 디스플레이를 랜더 함수로 바꿔야겠네요.
这是这样的。这是 glut,你看不到吗?我会在后面放大。然后在 glut 显示函数中调用了显示函数。已经注册了显示。查看显示函数,返回类型是什么?返回类型是 void,函数名是 display,没有参数。这意味着需要注册这样的函数。函数名可以更改,我将改为 render。因为 render 通常是绘图函数,所以将名称改为 render,然后在这里也要相应地更改,在实际实现中也要将 display 改为 render 函数。

Attendees 1 11:07 이 2개 함수 등록했어요. 그럼 얘도 마찬가지로 진짜 호출되는지 한번 테스트를 해봐야겠죠. 확인을 해볼 거고 랜덤 함수 구현으로 가서 여기다 똑같이 한번 찍어보죠. 프린트 f.
已经注册了这两个函数。那么我们也同样需要测试一下是否真的被调用。我们将进行确认,然后转到 render 函数的实现,在这里同样添加一个打印。打印 f。

Attendees 1 11:37 그래서 실행을 해보면은
所以当我们执行时

Attendees 1 11:47 이 랜덤 수업이 계속 호출이 되고 있어요. 밑에 보면은
这个随机课程一直在被调用。如果你看下面的话

Attendees 1 11:55 지금 타이머를 걸어놨기 때문에 지금 계속 출력 여기 뼈가 점점 늘어나는 거 보이죠. 줄어드는 거 보인다는 얘기는 계속 밑에 출력이 똑같은 게 출력이 되고 있다는 얘기예요. 랜더 이즈 콜드가 왜 지금 계속 그리고 있기 때문에
与会者 1 11:55 我现在已经设置了计时器,所以现在不断输出,在这里可以看到骨骼在逐渐延长。说减少是因为下面不断输出的是相同的内容。渲染被调用的原因是因为它一直在绘制

Attendees 1 12:15 몇 번 출력됐는지 한번 적으려면 어떻게 해야 되나 인트에
与会者 1 12:15 如果想记录已经输出了多少次,应该怎么在整数中实现

Attendees 1 12:40 넘 콜스 이렇게 해서 출력하면 이거 항상 얼마만 찍힐까요? 이거 랜덤 호출될 때마다 넘 쿼리 뭐로 초기화돼요? 0으로 초기화돼서 계속 영어만 찍히죠. 자 이럴 때 사용하는 스킬이 뭐지? 이거를 어떤 타입으로 바꿔주면 돼요? 스테틱 타입으로 바꿔주면 되죠 스테틱이라는 건 뭐예요? 스테틱은 한 번만 초기화가 되고 다음 함수가 호출될 때도 살아 있는 거죠. 스테 스테틱 변수 그래서 이렇게 하면은
听众 1 12:40 每次调用时会打印多少?每次随机调用时查询会如何初始化?是否会被初始化为 0,然后一直只打印英文?那么这种情况下应该使用什么技巧?需要将它转换为什么类型?需要转换为静态类型。静态是什么意思?静态是指只初始化一次,下次函数调用时仍然保持存在。静态变量,因此这样做的话

Attendees 1 13:26 그래도 0이네 스테이팅을 플러스 해줘야 되죠. 그거 플러스 해줘야 되지 한 번 할 때마다 호출될 때마다 플러스 해줘야겠죠.
听众 1 13:26 还是 0,需要对静态变量进行累加。每次调用时都需要累加。

Attendees 1 13:42 그래서 랜덤 함수가 20번 계속 호출되는 거를 확인할 수가 있을 거예요.
出席者 1 13:42 所以你可以确认随机函数会被连续调用 20 次。

Attendees 1 13:55 그래서 우리가 보통 여기다가 이제 뭘 넣나 랜덤 함수에다가 화면에 그릴 내용들을 여기다 포함을 시키죠. 화면에 그릴 내용들 그래서 한번 클리어 버퍼에서 화면을 지우고 그다음에 색상을 지정하고 그다음에 색상으로 화면을 지우고 그다음에 내가 바라볼 관측 공간을 여기서 지정을 하고 그다음에 여기서 이제 객체를 그려주고 이런 역할을 하는 거죠. 랜드 함수에서 다음 콜백 함수는 윈도우 관련된 콜백 함수 중에서 마지막으로 크로즈 펑크라는 게 있어요. 크로즈 펑크 이거는 뭐냐 하면 윈도우가 다칠 때 호출되는 함수를 시스템에 등록하는 거예요. 마찬가지로 파라미터는 등록 함수에 이름을 넣어주면 되고 마찬가지로 콜백 함수에 파라미터는 없어요. 리턴 타입은 보이드고 이런 콜백 함수 왜 필요할까 여러분이 x 버튼 딱 누르는 순간 이제 여러 가지 정리해 줄 일들이 좀 필요하겠죠. 예를 들면 동적으로 뭔가 할당이 돼 있으면 그거 딜리트 해 주고 그런 일들이 필요하니까 이런 함수도 이제 필요해요.
出席者 1 13:55 通常我们在这里,现在添加什么,在随机函数中包含要在屏幕上绘制的内容。在屏幕上绘制的内容,所以先清除缓冲区清空屏幕,然后指定颜色,然后用颜色清空屏幕,然后在这里指定我要观察的空间,然后在这里绘制对象,这就是它的作用。随机函数中,下一个回调函数是窗口相关回调函数中的最后一个,叫做关闭函数。关闭函数是什么呢?就是在窗口关闭时注册要调用的系统函数。同样,参数是在注册函数中放入名称,回调函数的参数也是没有的。返回类型是 void,为什么需要这种回调函数呢?当你点击 x 按钮的那一刻,可能需要做一些清理工作。例如,如果有动态分配的内容,就需要删除它,所以这种函数现在是必要的。

Attendees 1 15:06 그래서 얘도 보면은 메인 함수 또 가보면은 등록이 돼 있나 모르겠네요. 여기 있네요. glut 크로즈 펑크에서 크로즈라는 함수를 여기다 등록을 했네요. 크로즈 함수 한번 프로토 타입 가보면은 선원으로 가보면은 여기 있네요. 리턴 타입은 보이드고 인자는 없는 거고 그렇죠 구현으로 한번 가볼까요? 구현으로 가보면은 프로그램 종류에 따른 후처리 그래서 아무것도 없으니까 여기도 뭐 확인 한번 해보려면 프린트 해놓으면 되겠죠. 프린트 프
参会人员 1 15:06 所以看一下主函数,我想看看是否已经注册。哦,在这里。在 GLUT 关闭函数中,他在这里注册了关闭函数。让我们看看关闭函数的原型,返回类型是 void,没有参数。让我们看看实现。在实现中,根据程序类型进行后处理,因为没有什么,如果要确认的话,可以在这里打印。打印 p

Attendees 1 15:49 근데 뭐 굳이 이거 확인 안 해봐도 알겠죠 이제 그래서 넘어갈게요. 다음은 이제 마우스 관련된 콜백 함수 마우스 관련된 콜백 함수 마우스 이벤트를 처리하는 콜백 함수로서 몇 가지가 있어요. 마우스 관련된 거는 glut 마우스 펑크로 등록할 함수는 얘는 뭐냐 하면은 어떤 함수를 등록하냐 하면은 마우스 버튼을 여러분이 왼쪽 버튼 탁 누를 수 있죠. 오른쪽 버튼 누를 수도 있고 가운데 버튼 누를 수도 있죠. 얘는 클릭할 때예요. 클릭할 때 그래서 마우스 버튼을 클릭할 때 마다마다마다 자동으로 호출되는 콜백 함수를 등록을 하는 함수가 바로 glut 마우스 펑크예요. 근데 콜백 함수에 물론 이제 여기다 함수에 이름을 넣어주면 되는데 아무 함수의 이름이나 넣어주는 게 아니라 프로토타입이 어떤 함수 리턴 타입은 보이드고 그다음에 인자로는 인트짜리 4개를 받아야 돼요. 인트짜리 하나 둘 셋 넷 그러면은 여기 등록할 콜백 함수에 인자는 어떤 의미가 있을까? 첫 번째 인자는 버튼이에요.
参会人员 1 15:49 但是即使不确认,现在也大概知道了。所以我们继续。接下来是鼠标相关的回调函数,处理鼠标事件的回调函数有几种。对于鼠标相关的,通过 GLUT 鼠标函数注册的函数是什么?就是当你点击鼠标左键、右键或中键时。这是点击时。因此,每次点击鼠标按钮时,都会自动调用的回调函数是通过 GLUT 鼠标函数注册的。但是在回调函数中,当然可以在这里输入函数名,但不是随便哪个函数名,而是函数的返回类型是 void,并且接受 4 个整型参数。第一个参数是按钮。

Attendees 1 17:04 버튼 마우스를 클릭할 때 왼쪽 버튼을 눌렀는지 오른쪽 버튼을 눌렀는지 중간 버튼을 눌렀는지 구분을 해야겠죠. 그래서 그 구분이 바로 버튼에 전달이 돼요. 그래서 이 버튼이 가질 수 있는 파라미터는 glut 레프트 버튼, 미들 버튼, 라이트 버튼 셋 중에 하나를 갖게 돼요. 들어온다는 얘기죠. 이 버튼으로 그다음에 스테이트는 마우스를 클릭할 수도 있지만 마우스를 뗄 수도 있겠죠. gg 업 하면은 마우스를 떼는 순간 혹은 gg 다운 하면은 누르는 순간 이런 이벤트 마우스의 스테이트가 여기에 저장이 되고 그다음에 이 XY는 뭘까요? XY는 XY는 마우스를 클릭하는 순간 좌측 상단을 기준으로 해서 이 마우스의 위치가 있겠죠 위치 이 위치가 이제 x 콤마 y에 전달이 된다는 얘기예요. 알겠나요? 그래서 요 GLT 마우스 펑크를 사용하는 방법 간단히 살펴보면 여기 메인 함수에 같이 보면은 여기 있네요. 여기
参会人员 1 17:04 当点击鼠标按钮时,需要区分是按下左键、右键还是中键。这个区分会直接传递给按钮。因此,这个按钮可以有 GLUT 左键、中键、右键三种之一。这意味着它会进入。接下来,状态可能是鼠标点击,也可能是鼠标释放。当鼠标抬起时,即释放鼠标的那一刻,或者按下鼠标时,这些鼠标事件的状态会被存储在这里。那么 XY 是什么?XY 是指鼠标点击时的位置,以左上角为基准,即鼠标的位置,这个位置会传递到 x 和 y。明白了吗?所以,使用 GLT 鼠标函数的方法简单来说,可以看看主函数,就在这里。

Attendees 1 18:17 어떻게 등록을 했어요? glut 마우스 펑크로 등록을 했죠. 콜백 함수의 이름은 mouse 마우스라는 함수를 등록을 했어요. 얘 선원으로 가보면은 선원으로 한번 가볼게요. 아까 얘기했던 대로 프로토 타입이 어떻게 돼요? 리턴 타입은 보이드고 인자로는 인트 4개를 받는다고 했죠. 버튼 스테이트 x y 그러면 구현 한번 가볼게요. 구현 구현으로 정의로 한번 가보면은 여기 추적 처리돼 있는 걸 한번 해제해 볼까요?
参会人员 1 18:17 是如何注册的?是用 GLUT 鼠标函数注册的。回调函数名是 mouse 鼠标函数。让我们看看它的原型。正如之前讨论的,返回类型是 void,参数是接收 4 个整型。按钮、状态、x、y。那么让我们看看它的实现。让我们解除这里的跟踪处理。

Attendees 1 19:00 이렇게 했더니 버튼 값을 가지고 서로 다른 메시지를 출력을 해주네요. 그렇죠 왼쪽 버튼 버튼이 만약에 레프트 버튼이면은 왼쪽 버튼 버튼이 오른쪽 버튼이면은 오른쪽 버튼 그다음에 버튼이 눌린 상태면은 눌림 그다음에 해제된 상태면 해제 이렇게 찍고 처음에 뭘 안 찍었나 위치가 있다고 했죠. 위치 저 위치도 한번 찍을게요. 프린트 f 위치는 x 콤마 y는 퍼센트 d 콤마 퍼센트 d 퍼센트 d 콤마 퍼 d로 찍고 줄 바꾸고 여기다가 뭐 집어넣으면 되나요? x 콤마 y 찍어주면 되겠죠. 그러면 이제 눌린 위치도 출력이 되고 어떤 이벤트가 발생이 됐는가도 출력이 될 거예요. 한번 해볼까요?
与会者 1 19:00 这样做后,按钮值可以输出不同的消息。对吧,如果是左键按钮,就是左键按钮;如果是右键按钮,就是右键按钮。然后,如果按钮被按下,就显示按下;如果按钮被释放,就显示释放。我之前没有打印什么,但是有位置,对吧。我也要打印位置。打印 f 位置是 x,逗号,y 是%d,逗号,%d,%d,逗号,%d,换行。在这里可以插入什么吗?打印 x,逗号,y 就可以了,对吧。这样就可以输出按下的位置,也可以输出发生了什么事件。我们来试试看?

Attendees 1 20:10 랜덤 함수가 계속 랜덤 함수를 꺼야겠다. 이거 출력되는 거는 랜덤 함수 출력되는 거는 끄도록 하고
与会者 1 20:10 随机函数要一直关闭这个随机函数。输出的这个是随机函数输出的,要把它关掉。

Attendees 1 20:34 여기 한 가운데 정도에서 가운데 정도에서 왼쪽 버튼을 탁 눌렀어요. XY는 3, 3, 4 콤마 301 찍히죠. 그다음에 왼쪽 버튼 눌림이라고 찍히죠. 그다음에 아직 누르고 있는 상태예요. 왼쪽 버튼을 딱 떼볼게요. 떼는 순간 똑같이 3 3 4 콤마 301 찍히고 왼쪽 버튼이고 해지됐다 이렇게 나오죠. 3 3 4 콤마 301은 어디를 기준으로 좌측 상단을 기준으로 0 콤마형이에요. 그래서 마우스를 이쪽에다 이렇게 갖다 대고 여기서 이번에는 우측 마우스 버튼을 한번 눌러볼게요. 하나 둘 셋 아이고 뭐야 우측 마우스 버튼이 지금 메뉴를 연결해놔가지고 그런 거고 가운데 버튼을 한번 눌러볼게요. 가운데 버튼 하나, 둘 셋 누르는 순간 뭐야 가운데 버튼은 표시가 안 돼 있나 가운데 버튼은 체크를 안 했네. 여기서 가운데 버튼은 체크를 안 했으니까 아무튼 아무튼 뭐 무슨 말인지 알겠죠? 어려운 내용 아니고 왼쪽 찍으면은 용크마 0 되나 볼까요? 팔크마 6으로 나오죠.
与会者 1 20:34 在这里大约中间位置,在中间位置的左侧按钮点击了。XY 是 3, 3, 4 逗号 301 被记录下来。然后显示左侧按钮被按下。接着是仍然处于按下状态。我将松开左侧按钮。松开的瞬间,同样记录 3 3 4 逗号 301,并显示左侧按钮已释放。3 3 4 逗号 301 是以左上角为 0 逗号为基准。所以我把鼠标放在这里,这次右侧鼠标按钮按一下。一、二、三,哎呀,右侧鼠标按钮现在连接了菜单,中间按钮也按一下。中间按钮一、二、三,按下的瞬间,咦,中间按钮似乎没有标记,没有勾选。在这里中间按钮没有勾选,总之大概明白是什么意思了吧?不是很难的内容,如果点击左侧,会不会变成 0?变成 6。

Attendees 1 21:43 더 가까이 가면은 1 콤마 1 나오네요. 이 끝에 찍으면 얼마가 될까 635콤마 638. 지금 윈도우 크기가 좀 바뀌어서 그래요. 그래서 이렇게 클릭할 때마다 클릭할 때마다 출력이 되는 거를 확인할 수가 있어요.
与会者 1 21:43 再靠近一些,出现 1 逗号 1。如果点击最末端会是多少,635 逗号 638。现在窗口大小有些变化。所以每次点击时都可以确认输出。

Attendees 1 22:11 마우스 이벤트 처리하는 순서 첫 번째 거 클릭할 때 혹은 뺄 때 두 번째 거는 우리 보통 드래깅한다고 하죠. 드래깅 마우스를 탁 누르고 쭉 끓을 때 마우스를 누르고 끓을 때 그걸 이제 드레깅이라고 하는데 glut에서는 그런 이벤트를 캡처를 해요. 그래서 glut 모션 펑크로 등록을 해요. 모션 펑크로 그래서 마찬가지로 등록할 함수의 프로토타입은 리턴 타입이 보이고 인자로 x하고 y를 갖고 이 XY는 이제 뭔지 예측이 되죠. 마우스를 드레깅할 때 그 위치예요. 위치 마우스 버튼을 누르고 움직일 때 자동으로 호출되는 콜백 함수를 등록하고 콜백 함수의 파라미터는 좌측 상단을 기준으로 마우스의 위치가 전달이 된다라는 거네요. 테스트 한번 해볼까요?
参会人员 1 22:11 处理鼠标事件的顺序,第一个是点击时或松开时,第二个是我们通常说的拖拽。鼠标拖拽是指按下鼠标并拖动。当按下鼠标并拖动时,这就是所谓的拖拽,GLUT 会捕获这种事件。因此,在 GLUT 中通过动作函数来注册。动作函数的原型是返回类型为 void,参数为 x 和 y,这些 x 和 y 很容易预测,就是鼠标拖拽时的位置。这是一个在按下鼠标按钮并移动时自动调用的回调函数,其参数是以左上角为基准的鼠标位置。我们来测试一下吧?

Attendees 1 23:11 여기 있네 glu티 모션 펑크 마우스를 버튼을 누른 상태에서 움직일 때 호출되는 함수죠. 모션이라는 함수로 등록을 했어요. 나는 모션이 마음에 안 들어 그러면 어떻게 하면 돼요? 마우스 드래깅 해줘도 돼요. 함수의 이름은 아무튼 모션 함수로 가보면은 리턴 타입은 보이드고 함수의 이름은 모션이고 인자로 XY를 받는 그런 함수예요. 그다음에 구현으로 한번 가보면은 이렇게 돼 있네요. 프린트 f에서 x 콤마 y를 찍고 있네요.
参会人员 1 23:11 这里是 GLUT 动作函数,在按住鼠标按钮移动时调用的函数。我们用动作函数注册了它。如果我不喜欢这个动作怎么办?你也可以使用鼠标拖拽。无论如何,查看动作函数,返回类型是 void,函数名是 motion,参数是 x 和 y。接下来看实现,它在 printf 中输出 x 和 y。

Attendees 1 23:59 그래서 모션 한번 해볼까요? 지금은 이제 이것도 마우스를 클릭할 때도 메시지가 출력이 되죠. 그다음에 클릭한 상태에서 끌면은 그때 현재 움직이는 좌표들이 여기 막 출력이 될 거예요.
那么,我们来做一个动作怎么样?现在,当你点击鼠标时也会输出消息。接着,在点击并拖动时,当前移动的坐标将会被输出。

Attendees 1 24:18 실행을 시킨 거고
已经执行了

Attendees 1 24:26 여기 이쪽에 한번 클릭을 할게요. 딱 클릭한 순간 왼쪽 버튼 눌림 4 콤마 3 이렇게 되고 이렇게 끌면은 끄는 순간 클릭한 상태에서 끄니까 어때요? 현재 위치가 계속 출력이 되죠 이렇게 지금 계속 마우스 버튼을 누르고 있는 상태예요. 마우스 버튼 떼고 움직여 볼까요? 그러면 이제 출력이 안 되죠. 마우스 버튼 오른쪽 마우스 버튼 가운데 마우스 버튼 눌러도 되나 그러네요. 그러니까 이거 마우스 펑크는 왼쪽 마우스 버튼이든 오른쪽 마우스 버튼이든 혹은 가운데 마우스 버튼이든 누른 상태에서만 움직이면은 체크가 된다는 거죠.
与会者 1 24:26 我将在这里单击。单击的那一刻,左键按下 4,逗号 3,就是这样,然后拖动时,因为是在点击状态下拖动,所以怎么样?当前位置会持续输出,就像现在一直处于按下鼠标按键的状态。松开鼠标按键并移动怎么样?那么现在就不会输出了。鼠标右键、鼠标中键也可以按。也就是说,这个鼠标函数无论是左键、右键还是中键,只有在按住并移动时才会被触发。

Attendees 1 25:14 그러면은 마우스 버튼을 누르지 않았을 때도 뭔가 내가 정보를 얻고 싶을 때도 있죠. 그럴 때는 모션 펑션에다가 앞에다가 패시브라는 거를 이렇게 붙여주면 돼요. 패시브 GLT 패시브 모션 펑크 하면은 얘는 마우스 버튼을 누르지 않고 움직일 때 자동으로 호출되는 콜백 함수를 등록하는 거예요. 그다음에 콜백 함수의 프로토 타입은 똑같네요. 리턴 타입은 보이드고 인자로 XY를 받는 거고 얘도 그냥 쉽게 어디 있나요? 등록을 어디서 하죠? 메인 함수에서 주엘유티 패시브 모션 펑크에서 패시브 모션 함수를 등록을 한 거고 구현으로 가보면은 여기서 그냥 출력을 할게요. 좌표를 좌표를 출력하고 실행을 시키면은
与会者 1 25:14 那么,在没有按鼠标按键的时候,也可能需要获取一些信息。这时,只需在运动函数前面加上"被动"(passive)就可以了。使用 GLUT 被动运动函数,当鼠标未按键时移动时,将自动调用这个回调函数。然后,回调函数的原型是相同的。返回类型是 void,参数是 XY,同样很简单。在哪里注册?在主函数中,使用 glutPassiveMotionFunc 注册被动运动函数。在实现中,我将直接输出坐标,然后执行。

Attendees 1 26:18 내가 그냥 마우스 좌표 이렇게 누르지 않은 상태예요. 누르지 않고 이렇게 움직여도 막 출력이 되죠. 지금 정지된 상태고 움직이고 아이고 움직이고 0 콤마 0쪽으로 가면은 되게 작은 값이 나오겠죠. 누르지 않은 상태에서 이렇게 움직여도 되는 거고 그래서 이런 이벤트들이 마우스 관련 이벤트들이 많이 있는데 그거를 핸들링하기 위한 처리하기 위한 콜백 함수들을 등록하는 방법과 사용하는 방법에 대해서 지금 소개를 한 거예요. 그다음에 이제 윈도우와 마우스 그다음에 남은 건 뭔가 윈도우 마우스 했으면 이제 키보드가 있겠죠. 여러분 게임할 때 키보드 조작 많이 하죠. 키보드 이벤트도 처리를 해줘야 돼요. 그래서 키보드 이벤트를 처리하는 콜백 함수는 glut 키보드 펑크예요. 키보드 펑크 얘로 등록을 하겠다는 얘기죠. 등록할 콜백 함수의 프로토타입은 리턴 타입은 보이드고 그다음에 얘는 인자를 몇 개를 받냐 하면 3개를 받네요.
参与者 1 26:18 我只是没有单击鼠标坐标。即使不点击,也会输出。现在是静止状态,移动,哦,移动到 0,0 附近,会出现很小的值。即使不点击也可以这样移动,所以这些鼠标相关的事件有很多,现在我介绍了如何注册和使用处理这些事件的回调函数。接下来,窗口和鼠标之后,剩下的是什么?窗口、鼠标后,就是键盘了。大家玩游戏时经常使用键盘控制对吧。还需要处理键盘事件。所以处理键盘事件的回调函数是 GLUT 键盘函数。意思是要用这个注册回调函数。回调函数的原型返回类型是 void,它接收 3 个参数。

Attendees 1 27:30 3개 3개를 봤는데 첫 번째는 언사인드 캐릭터 타입으로 키를 받고 두 번째는 XY를 받아요. 이 언사인 캐릭터 타입으로 키는 뭐냐 하면은 키보드에서 여러분 어떤 키를 누르면 그 키에 아스키 값이 있죠? 그 아스키 값이 이제 언사인드 캐릭터 타입으로 이 키에 전달이 돼요. 그다음에 XY는 키보드 키보드에서 어떤 키를 누르는 순간 마우스의 위치도 같이 전달이 되는 거예요. XY는 마우스 위치가 전달이 되고 이것도 뭐 간단하게 테스트를 해보면은 메인 함수에서 한번 봅시다.
参与者 1 27:30 3 个,我看到 3 个。第一个是无符号字符类型,接收键,第二个接收 XY 坐标。这个无符号字符类型的键是什么?当你在键盘上按下某个键时,那个键有一个 ASCII 值。这个 ASCII 值会以无符号字符类型传递给这个键。然后 XY 是,在按下键盘上的某个键的那一刻,鼠标位置也会一起传递。XY 传递鼠标位置,我们可以在主函数中简单地测试一下。

Attendees 1 28:19 이렇게 등록을 했네요. glut 키보드 펑크로 키보드라는 함수를 등록을 했어요. 프로토타입 가보면은
参与者 1 在 28:19 已经注册了。使用 glut 键盘函数注册了键盘函数。让我们看看原型

Attendees 1 28:31 여기 있네요. 리턴 타입은 보이드고 함수의 이름은 키보드고 첫 번째 인자는 언사인드 캐릭터 타입으로 키 여기 아스키 값이 들어온다는 얘기죠. 그다음에 XY 구현 한번 가볼까요? 구현으로 한번 가보면은 키 값이 여러분 아스키 값 다 기억 못하죠 a의 아스키 값 기억 못하고 하니까 이렇게 호다운표로 하면은 해당 아스키 값이 스키 값을 확인할 수가 있는 거죠. 그래서 키 q를 누르면 q를 누르면은 엑시트 했어요. 그건 뭐 해라는 얘기예요. 종료시키겠다는 얘기죠 q를 누르면 종료를 하겠다는 얘기예요. 또는 또는 키 값이 27하고 같은 27은 뭘까요? 27 아는 사람 있나요? 아스키 값 27 아스키 값 27은 이스케이프 코드가 맞나 모르겠네. 아무튼 한번 해볼까요? escp가 맞나? 여기서 일단은 q를 한번 눌러볼게요. q를 탁 누르는 순간 종료가 됐죠 q가 종료가 된다는 걸 확인했고 esc 키를 탁 누르는 순간도 종료가 되네요.
参与者 1 在 28:31,原型在这里。返回类型是 void,函数名是 keyboard,第一个参数是无符号字符类型,这里是键的 ASCII 值。那么让我们来看看实现。在实现中,你可能记不住所有的 ASCII 值,比如记不住'a'的 ASCII 值,所以使用这种方式可以确认 ASCII 值。例如,当按下'q'键时,程序会退出,这意味着当按下'q'键时将终止程序。或者,键值等于 27,27 是什么?有人知道 27 的 ASCII 值吗?我不确定 27 是否是转义码。无论如何,让我们试试。是不是 ESC?首先,当我按下'q'键时,程序立即退出。我们确认了'q'键会导致退出,当按下 ESC 键时,程序也会立即退出。

Attendees 1 29:56 그렇죠 그래서 뭔가 as 시키고 그러고 그다음에 나는 보통 게임 만들 때 뭘로 제어 많이 하나요? as a 뭐죠? awd 뭐 그런 거 하나요? 그래서 a하고 같으면은 뭐 해주면 돼요 뭔가 이제 캐릭터의 움직임을 맞춰주면 되겠죠 이런 키보드 이벤트를 처리할 수가 있어요.
对的,所以当我们制作游戏时,通常会用什么来控制?是什么?AWD 等这样的东西吗?所以如果是 A,就可以做一些事情了,比如调整角色的移动,这样就可以处理键盘事件。

Attendees 1 30:31 그래서 키보드 이벤트는 glut 키보드 펑션이 있고 그다음에 이 키보드 펑션으로는 이제 화살표는 제어가 안 돼요. 화살표 여러분 키보드에 있는 화살표 있죠? 화살표나 F1, f2, f3 같은 키는 다른 함수로 등록을 해줘야 되는데 이거는 스페셜 키보드 펑크인가 그런 게 있을 거예요. 한번 필요하면 찾아보면 돼요. 그거는 타이머 콜백 함수 타이머 타이머는 뭔가 알람을 설정해 놓는 거죠. 알람 glut 타이머 펑크라는 함수로 이제 타이머를 설정할 수 있는데 인자가 이건 좀 많네요. 보통 다른 콜백 함수 등록하는 것들은 그냥 어땠어요? 함수에 이름만 넣어주면 됐었죠 함수에 이름만 넣어줬으면 됐는데 이거는 함수가 인자가 하나 둘 3개나 되네요. 3개 첫 번째 인자 뭐 같아요 언사인드 인트의 타임 하면은 이거는 밀리세컨드 단위로 해서 면 밀리세컨드 후에 두 번째 인자로 등록한 함수를 호출하겠다 그런 얘기예요.
因此,键盘事件有 GLUT 键盘函数,但这个函数不能控制箭头键。你们知道键盘上的箭头键吧?箭头键或 F1、F2、F3 这样的键需要用另一个函数注册,这可能是特殊键盘函数。如果需要的话可以查找一下。关于定时器回调函数,定时器是设置一个闹钟。使用 GLUT 定时器函数可以设置定时器,这个函数的参数似乎比较多。通常其他回调函数注册时只需要传入函数名就可以了,但这个函数有三个参数。第一个参数看起来是无符号整型时间,以毫秒为单位,意思是在多少毫秒后调用第二个参数中注册的函数。

Attendees 1 31:51 그다음에 세 번째 인자는 뭐냐 하면은 그 두 번째 함수로 등록한 함수한테 전달할 아이디 여기 두 번째 함수 등록한 함수 보면은 인자를 하나 갔죠. 인트의 아이디를 갖죠. 여기서 그래서 이 함수에 전달할 아이디가 바로 타이머 아이디 세 번째 인재가 되는 거예요. 다시 설명하면은 타이머를 타이머 룰이 아니라 타이머 콜백 함수를 등록한다. 타이머 콜백 함수를 등록을 하고 그다음에 파라미터 로그는 첫 번째 파라미터는 타입 이거는 이제 설정할 시간 그러니까 설정을 몇 미리 세컨드 후에 호출된다 그런 얘기예요. 천을 주면은 어떻게 되나요? 이거는 천 하면 1초 후에 호출되도록 하는 거죠. 1초 후에 타이머가 올리도록 하는 거예요. 0.5초 후에 올리도록 하고 싶다 그러면 얼마를 주면 돼요? 500을 주면 되겠죠 그다음에 두 번째 인자로 펑크는 펑션의 이름이에요.
接下来,第三个参数是什么呢?是传递给第二个注册函数的标识符。查看第二个注册的函数,它接收一个参数,是一个整型标识符。因此,在这里传递给该函数的标识符就是定时器标识符,作为第三个参数。再解释一遍,注册定时器回调函数,然后第一个参数是类型,即设置调用的时间,比如多少毫秒后调用。如果给 1000,意味着 1 秒后调用定时器。如果想在 0.5 秒后调用,应该给多少?给 500 就可以了。第二个参数是函数名。

Attendees 1 32:55 호출될 타이머 함수의 이름을 두 번째로 넣어주는 거고 근데 여기 등록할 함수는 프로토타입이 어때야 돼요? 리턴 타입은 보이드고 인자로 정수 하나를 갖죠. 정수 하나를 갖는 함수를 등록해줘야 되고 그다음에 세 번째 인자인 타이머 아이디는 여러 개의 타이머가 어떤 여러 개의 타이머를 설치할 수가 있어요. 어떤 타이머는 0.5초 후에 호출되고 어떤 타이머는 1초 후에 호출되고 어떤 타이머는 10초 후에 호출되도록 여러 개를 등록을 할 수 있기 때문에 타이머를 구별하기 위한 아이디를 여기다가 이제 세 번째 인자로 주게 되면은 그 아이디가 어디에 전달이 된다 요 등록 함수에 요 아이디로 전달이 되는 거예요. 이렇게 이제 얘기하는 것보다는 실제 예를 들어보는 게 훨씬 좋을 거예요.
要注册的是定时器函数的名称。这里注册的函数原型应该是什么?返回类型是 void,并且接收一个整数参数。需要注册一个接收一个整数的函数。第三个参数是定时器标识符,因为可以设置多个定时器。有些定时器 0.5 秒后调用,有些 1 秒后调用,有些 10 秒后调用。为了区分这些定时器,在第三个参数中传递标识符,这个标识符会传递给注册函数。与其这样解释,不如直接看个实际例子会更好。

Attendees 1 33:52 한번 보면은 타이머 함수를 잘 써야 돼요. 뭔가 여기 타이머 함수 등록했네요. 이거 해석 한번 해보세요. 해석 주얼리티 타이머 펑션 100을 줬어요. 그러면은 이게 얼마 후에 올리겠다는 얘기예요. 100이니까 0.1초 후에 0.1초 후에 누구를 호출하겠다는 얘기예요 타이머라는 함수를 여기 두 번째 등록한 함수를 호출하겠다는 얘기예요. 그다음에 이 함수한테 어떤 값을 넘겨주겠다는 얘기예요 0 값을 넘겨주겠다는 얘기죠. 그러면 타이머 함수 프로토타입 한번 가볼까 정의로 바로 한번 가볼게요. 정의로 가보면은 여기서는 x는 y 값하고 막 증가시키네요. 이건 안 하고 한번 찍어볼게요.
听众们,你们要好好使用定时器函数。这里已经注册了定时器函数。让我为你们解释一下。如果我给定时器函数的质量评分 100 分,那意味着它会在多长时间后调用。100 表示 0.1 秒后,0.1 秒后调用在这里第二个注册的函数。然后要传递给这个函数一个值,这里是传递 0 值。那么我们来看看定时器函数的原型定义。在定义中,可以看到 x 和 y 值在增加。这个我们先不管,我们来测试一下。

Attendees 1 34:55 tim이야 Dr 타이머
听众 1 34:55 Tim,Dr 定时器

Attendees 1 35:04 타이머 위드 아이디는 아이디 얼마
与会者 1 35:04 带有 ID 的计时器 ID 是多少

Attendees 1 35:17 이렇게 하면 어떻게 될까요? 아이디 한 다음에 이 전달받은 아이디를 갖는 타이머가 호출됐습니다. 이렇게 출력이 되겠죠. 그래서 타이머를 우리가 0.1초 후에 하지 말고 7천 초 7천 밀리세컨드 이거 몇 초 후에 7초 후에 호출되도록 할게요.
与会者 1 35:17 这样做会怎么样?在 ID 之后,调用具有这个传递的 ID 的计时器。这样就会输出。所以我们不要在 0.1 秒后设置计时器,而是在 7000 毫秒后,也就是 7 秒后调用。

Attendees 1 35:53 7초 지금이 7초였어요. 시작하고 타이머 위드 아이디 제로 이렇게 콜드 이렇게 출력이 됐죠. 밑에 나와서 안 보이나요? 지금 마우스 같은 게 움직일 때마다 출력이 저기 뭐야 메시지가 프린트가 돼가지고 조금 헷갈리니까 다 지울까 이런 것들은
听众 1 35:53 7 秒的时候。计时器从零开始,就这样输出。在下面显示出来了吗?每当鼠标移动时都会打印出一些消息,所以有点混乱,想要全部清除。

Attendees 1 36:21 주목하는 건 뭐야? 패시브 패시브 모션 펑션 다시 실행하고 1초, 2초, 3초, 4초, 5초, 6초 아무 벌써 출력이 났네요. 아무튼 이렇게 해서 이제 7초 후에 출력이 된 거예요. 7초가 조금 급하면은 10초
听众 1 36:21 重点是什么?被动运动函数,重新执行,1 秒、2 秒、3 秒、4 秒、5 秒、6 秒,已经输出了。总之就是在 7 秒后输出。如果 7 秒太急,可以改成 10 秒。

Attendees 1 36:52 10이면 어떻게 해야 되나 이렇게 해주면 되겠죠. 시작해서 1초 2초 3초 여기 2천만 볼게요. 4 5 6 7 8 9 10초 대략 10초 후에 호출이 됐죠. 그다음에 또 10초 후에 호출이 될까요? 안 되겠죠 타이머는 여러분 저기 뭐야? 타이머는 한 번만 호출이 되는 거예요. 그럼 10초마다 반복적으로 타이머를 호출하고 싶다. 그러면 어떻게 하면 될까? 이 타이머 함수로 지정한 여기서 두 번째 타이머를 또 지정을 해주면 돼요. 다시 걸면은 어떻게 이렇게 해주면은 이번에는 1초마다 노출을 한번 해볼게요. 여기도 천밀리세컨드니까 메인 함수에서 1초 후에 타이머라는 함수를 호출하도록 설정을 해놨죠. 그러면 1초 후에 타이머 함수가 호출이 되고 또 타이머에서는 이 메시지를 출력을 할 거고 그다음에 또 뭐 해줬어요? glut 타이머 펑크에서 다음 타이머를 여기서 다시 설정을 해줬죠.
参会者 1 36:52 如果是 10 秒怎么办?这样可以吧。从开始到 1 秒、2 秒、3 秒,我们来看这 2000 万。4、5、6、7、8、9、10 秒大概 10 秒后调用了。那么下一次 10 秒后还会调用吗?不会的。定时器是什么?定时器只会调用一次。那么如果想每 10 秒重复调用定时器怎么办?只需要在这个定时器函数中再次指定第二个定时器。重新设置,这次我们来尝试每 1 秒显示一次。这里也是 1000 毫秒,所以在主函数中设置了 1 秒后调用定时器函数。那么 1 秒后定时器函数会被调用,并且会输出这个消息,然后在 GLUT 定时器函数中又重新设置了下一个定时器。

Attendees 1 38:06 어떤 함수 타이머라는 함수를 똑같이 호출해 주는 거예요. 그럼 이렇게 되면 어떻게 될까요? 1초마다 한 번씩 호출이 되겠죠.
参会者 1 38:06 以同样的方式再次调用这个定时器函数。这样的话会怎么样?每 1 秒调用一次。

Attendees 1 38:17 1초마다 이제 타이머 함수가 계속 호출이 될 거예요. 반복적으로 그럼 나는 1밀리세컨드마다 호출하고 싶어 그럼 1초에 천 번 호출하겠다는 얘기죠. 그럼 어떻게 하면 되나 후기를 1ml 1mm는 너무 빠르고 10ml 10ml 정도로 맞춰주면은
听众 1 38:17 现在计时器函数将每秒持续被调用。反复地,那么我想每毫秒调用一次,也就是说每秒调用一千次。那么如何做到呢?后记是 1 毫升,1 毫米太快了,调整到 10 毫升、10 毫升左右会比较合适。

Attendees 1 38:43 이제 계속 호출이 되고 있는 거죠. 쭉 보면 계속 호출이 되고 있는 형태예요. 그래서 지금까지 여러 개의 콜백 함수 등록하는 거를 배웠네요. 리쉐입 디스플레이 크로즈 마우스 모션 패시브 모션 키보드 타이머 뭐 이런 것들을 배운 거예요. 조금만 더 하고 쉬는 시간 갖도록 할게요. 타임하우스까지 했죠. 그다음에 여러분 이제 마우스 오른쪽 버튼 누르면은 이렇게 팝업 메뉴 만들 수도 있어요. 팝업 메뉴 만드는 법 알려 공부하면은 팝업 메뉴 만들 때는 glut 크리에이트 메뉴라는 함수를 사용을 할 거예요. 크리에이트 메뉴 이거는 메뉴를 생성하고 그다음에 메뉴를 선택 시 처리할 콜백 함수를 등록을 한 함수예요. 그래서 인자로 주는 게 콜백 함수 함수의 이름이고 리턴 타입은 보이드고 그다음에 아이디 값을 전달하는 받는 함수를 등록을 할 거예요.
听众 1 38:43 现在它持续被调用。如果仔细观察,会发现它一直在被调用。到目前为止,我们已经学习了注册多个回调函数。我们学习了重塑、显示、关闭、鼠标、被动鼠标、键盘、计时器等函数。我们再稍微讲一会儿,然后休息一下。我们讲到了计时器。接下来,当你按下鼠标右键时,可以创建弹出菜单。学习创建弹出菜单时,将使用 GLUT 的创建菜单函数。创建菜单是用于生成菜单,并在菜单选择时注册处理回调函数。因此,传入的参数是回调函数的名称,返回类型是 void,然后将注册一个接收 ID 值的函数。

Attendees 1 39:58 그래서 파라미터 보면 펑크는 등록할 메뉴 처리 함수의 이름 그다음에 이 함수는 glut 크리에이트 메뉴라는 함수는 반환 값이 있어요. GL 인트라는 타입 그냥 인트 타입이라고 생각하면 돼요. 생성한 메뉴에 대한 아이디를 반환을 해요. 이 아이디를 가지고 뭔가 상위 메뉴의 인자로 활용을 할 수가 있어요. 그래서 무슨 말인지 잘 모르겠지만 나중에 이 예제를 보면 쉽게 이해가 될 거예요.
所以从参数来看,函数是注册菜单处理函数的名称,然后这个函数的 glutCreateMenu 返回值是 GL 整型,可以简单地理解为整型。它返回创建菜单的 ID。可以用这个 ID 作为上级菜单的参数。虽然现在可能听起来不太明白,但看完这个例子后就会很容易理解。

Attendees 1 40:32 그래서 크리에이트 메뉴라는 함수가 있고 그다음에 에드 메뉴 엔트리라는 게 있어요. 일단은 메뉴를 하나 만든 상태에서 우리 이것도 보면 오른쪽 마우스 버튼 딱 누르면은 이런 메뉴들이 막 뜨죠. 이게 이제 엔트리에요. 메뉴 엔트리 아까 크리에이트 메뉴라는 거는 그냥 큰 메뉴 전체를 만든 거고 에드 메뉴 엔트리 하면 요다음 이전 마지막 본 상태 이런 세부적인 메뉴들이 이제 만들어지는 거예요. 그래서 문자로 보면은 컨스트 캐릭터의 포인트 레이블 이렇게 나왔다는 얘기는 뭐예요? 얘가 뭔가 한글을 넣어주면 된다는 얘기죠. 그래서 다음을 하고 싶으면 여기다가 이제 다음이라고 적으면 되죠. 그다음에 그러면 사용자가 다음을 탁 누르죠. 탁 누르면은 그때 메뉴 처리 함수한테 어떤 값이 전달이 돼야겠죠 그 값이 바로 요 밸류예요. 밸류 요 밸류 요 엔트리를 눌렀을 때 전달할 값이 밸류예요. 그래서 메뉴 아이템을 추가하는 거고 레이블은 아이템의 이름이고 그다음에 밸류는 해당 아이템의 아이디.
有 glutCreateMenu 这个函数,然后还有添加菜单项的函数。首先创建一个菜单,当你右键点击时,就会弹出这些菜单。这就是菜单项。glutCreateMenu 是创建整个大菜单,而添加菜单项则是创建具体的子菜单细节。如果是字符串,就是 const char*类型,意思是你可以在这里输入汉字。比如想写"下一个",就在这里写"下一个"。当用户点击这个菜单项时,会向菜单处理函数传递一个值,这个值就是 value。value 是点击菜单项时要传递的值。所以是在添加菜单项,标签是项目的名称,value 是该项目的 ID。

Attendees 1 41:46 그래서 에드 메뉴 엔트리라는 함수가 있고 그다음에 에드 서브 메뉴라는 함수가 있어요. 서브 메뉴 서브 메뉴는 뭐냐 하면은 오른쪽 마우스 버튼 누르면 이런 거 같은 경우는 어때요? 서브 메뉴를 받죠? 요 화면 같은 애들은 서브 메뉴를 갖기 때문에 이 화면 같은 메뉴를 등록할 때 사용되는 게 에드 서브 메뉴라는 함수예요. 그다음에 첫 번째 인자는 레이블은 뭘까요? 이거는 레이블은 요 화면이라는 레이블이 되겠죠. 그다음에 두 번째 인자로는 서브 메뉴 아이디인데 이거는 이제 서브 메뉴가 갖는 화면을 보면은 어둡게 하기 이거 자체가 하나의 메뉴가 되는 거죠. 그러니까 이것의 아이디 얘 아이디 아이디를 두 번째 인자로 등록을 하면은 화면 밑에 이런 메뉴가 등록이 되는 거죠. 그럼 이 아이디는 어디서 만든 아이디인가? 바로 맨 처음에 크리에이트 메뉴 아이디가 리턴하는 값 있죠 그 아이디를 저장을 하고 있어야 돼요.
所以有一个添加菜单条目的函数,然后还有一个添加子菜单的函数。什么是子菜单呢?就像是右键单击时出现的那种情况?我们会收到子菜单。这些屏幕都有子菜单,所以在注册这种菜单时使用的是添加子菜单函数。第一个参数是标签是什么?这个标签就是这个屏幕的标签。然后第二个参数是子菜单 ID,当我们看到子菜单屏幕时,这个变暗的东西本身就是一个菜单。所以在第二个参数中注册这个 ID,菜单就会在屏幕底部注册。那么这个 ID 是从哪里来的呢?就是最初创建菜单 ID 返回的值,我们需要保存这个 ID。

Attendees 1 42:51 그래서 여기 보면은 어떤 생성한 어디 어디야 반환 값은 언제 사용한다고 했어요? 상위 메뉴의 인자로 사용할 때 반환 값을 사용한다고 했었죠. 그래서 간단하게 메뉴 생성 예제를 보면은 다음과 같은 메뉴를 만들고 싶어요. 오른쪽 마우스 버튼을 탁 누르면은 4개가 이렇게 뜰 거예요. 포인트 라인 폴리곤 그다음에 칼라 엑시트 그다음에 칼라에다가 마우스 버튼을 탁 갖다 대면은 서브 메뉴가 떠서 레드 그린 블루라는 메뉴가 뜰 거예요. 그러면 이 메뉴를 만들 때 크립 이 위쪽 메뉴부터 만드는 것보다는 이 하위 메뉴부터 만드는 게 좋아요. 왜냐하면 이 하위 메뉴를 만든 다음에 그 아이디를 가지고 있어야지만이 이 상위 메뉴 만들 때 사용할 수가 있겠죠. 그래서 메뉴 생성 예제에 보면은 칼라 메뉴 아이디 요 밑에 레드 그린 블루에 해당하는 거예요. glu티 크리에이트 메뉴 한 다음에 칼라 메뉴라는 이 인자로 전달하는 게 뭐라고 했어요?
所以在这里,我们之前说过返回值在什么时候使用?是在作为上级菜单的参数时使用。那么让我们看一个简单的菜单创建示例。当右键单击时,会出现 4 个选项:点、线、多边形,然后是颜色、退出。当鼠标悬停在颜色上时,会弹出红、绿、蓝的子菜单。创建这个菜单时,最好是从底层菜单开始创建。为什么呢?因为只有先创建子菜单并保存其 ID,才能在创建上级菜单时使用。在菜单创建示例中,颜色菜单 ID 就是在下面的红、绿、蓝对应的部分。创建菜单后,传递颜色菜单作为参数时是什么来着?

Attendees 1 44:04 인자로 전달하는 게 레드 그린 블루를 선택을 했을 때 처리할 핸들러 혹은 메뉴 처리 함수예요. 칼라 메뉴라는 거를 등록을 했어요. 그다음에 리턴되는 값은 뭔가 칼라 메뉴 아이디가 리턴이 되죠. 다시 요 컬러 메뉴라는 것은 이제 요 칼러 메뉴 레드 그린
当传递参数 1 44:04 时,处理红、绿、蓝选择时的处理程序或菜单处理函数。已注册了颜色菜单。接下来返回的值是颜色菜单 ID。然后这个颜色菜单是关于红、绿

Attendees 1 44:39 레드 그린 블루라는 메뉴를 선택했을 때 처리할 함수의 이름이고 얘가 리턴하는 값은 뭐다? 칼라 메뉴 아이디 이거는 요 메뉴에 요 메뉴를 생성하고 요 메뉴에 아이디가 있겠죠. 예를 들면 100 이런 아이디를 리턴하니까 얘가 이제 받게 되는 거예요. 그다음에 glut 에드 메뉴 엔트리 화면은 방금 생성한 컬러 메뉴 밑에 레드 그린 분류라는 NTB가 이제 들어가게 되는 거죠. 그다음에 레드 버튼을 누르면 0 값이 어디에 전달이 될까 컬러 메뉴 아이디에 전달이 되겠죠. 그다음에 그린 버튼을 누르면은 여기 있네요. 컬러 메뉴 핸들러 그린 버튼을 누르면 여기 이 값이 여기에 전달이 되고 블루 버튼을 누르면 이 값이 여기에 전달이 되겠죠. 그래서 이 하위 메뉴를 먼저 만든 다음에 그다음에 또 메뉴를 만들었네요. 어떤 메뉴 크리에이트 메뉴에서 크리에이트 메뉴라는 걸 만들었네요. 크리에이트 메뉴를 보면은 이렇게 돼 있고 크리에이트 메뉴는 이제 이쪽 메뉴예요.
出席人员 1 44:39 讨论了当选择红、绿、蓝菜单时要处理的函数名称,它返回的值是颜色菜单 ID。这是创建该菜单并为其分配 ID,例如 100。然后使用 glutAddMenuEntry 将屏幕上的颜色菜单下添加红绿分类标签。当按红色按钮时,0 值将传递给颜色菜单 ID。按绿色按钮时,值将传递到颜色菜单处理程序,蓝色按钮也是如此。因此,先创建子菜单,然后又创建了菜单。在创建菜单中创建了菜单,创建菜单看起来是这样的,它是这边的菜单。

Attendees 1 45:52 이쪽 메뉴고 상위 메뉴고 에드 메뉴 엔트리에서 포인트 요 엔트리 하나를 만들었고 그때 영을 전달하라고 했어요. 요 영은 어디에 전달이 됐나 크리에이트 메뉴의 아이디에 전달이 되겠죠. 여기에 그다음에 두 번째 엔트리는 라인 얘는 1이에요. 1 값을 주고 세 번째 엔트리는 폴리곤, 세 번째 엔트리는 폴리곤 그다음에 네 번째가 중요해요. 왜 네 번째는 에드 메뉴 엔트리가 아니라 에드 서브 메뉴를 썼죠. 왜 이 칼라라는 메뉴는 엔트리 메뉴가 아니라 서브 메뉴를 갖기 때문에 에드 서브 메뉴, 애드 서브 메뉴를 하고 칼라라고 하고 인자로는 뭘 줬어요? 컬러 메뉴 아이디라고 줬죠 이 컬러 메뉴 아이디는 누구였지? 아까 여기 컬러 메뉴 레드 그린 분류 만들 때 리턴 된 타입 있죠 얘를 얘를 여기다 주게 되면은 아까 만들었던 레드 그린 블루가 이 칼라 밑에 서브 메뉴로 딱 붙게 되는 거예요. 그렇기 때문에 아까 뭐라고 했어요? 상위 메뉴가 있고 하위 메뉴가 있으면 하위 메뉴부터 만들라고 했죠.
与会者 1 45:52 这边的菜单和顶级菜单都是在添加菜单条目时创建的,当时要求传递零。这个零被传递到了创建菜单的 ID。这里,第二个条目是线,它的值是 1,第三个条目是多边形。第四个很重要。为什么第四个使用的是添加子菜单而不是添加菜单条目?因为这个颜色菜单不是菜单条目,而是有子菜单,所以使用添加子菜单,并传递了什么参数?传递了颜色菜单 ID。这个颜色菜单 ID 是什么?就是之前创建红色、绿色分类时返回的类型。如果将它放在这里,之前创建的红色、绿色、蓝色就会作为颜色的子菜单出现。因此,之前说过什么?如果有顶级菜单和子菜单,要先创建子菜单。

Attendees 1 47:03 왜 하위 메뉴 만들어서 아이디를 가지고 있다가 상위 메뉴 만들 때 등록을 시켜줘야 되니까 그래서 여기 하위 메뉴 만든 다음에 상위 메뉴 만들라고 했죠. 그다음에 GLT 에드 메뉴 엔트리 이건 그냥 메뉴 엔트리 등록하는 거네요. 엑시트 해서 엑시트 누르면 3이 전달이 되도록 하고 그래서 컬러 메뉴에서 이 아이디 3을 받으면 어떻게 하라고 했어요? 엑시트 그러면 이제 프로그램이 종료가 되는 거겠죠. 그다음에 이런 메뉴들을 만들었으면은 이거는 팝업 메뉴이기 때문에 마우스 왼쪽 버튼이든 가운데 버튼이든 오른쪽 버튼이든 붙여야 돼요. 그래서 glut 어태치 메뉴 이 만든 메뉴를 어디다 붙이겠다는 얘기예요. 오른쪽 버튼을 붙이겠다는 얘기죠. 오른쪽 버튼을 탁 누르는 순간 이쪽 메뉴들이 이제 펼쳐지게 되는 거예요. 한번 볼까요? 코드를 메뉴 생성 예제에서 컬러 메뉴 아이디는 이제 서브 메뉴예요. glut 크리에이트 메뉴에서 컬러 메뉴
与会者 1 47:03 为什么要先创建子菜单并保存 ID,然后在创建顶级菜单时注册?所以先创建子菜单,然后再创建顶级菜单。接下来是 GLUT 添加菜单条目,这就是注册菜单条目。退出,当点击退出时传递 3,那么在颜色菜单中收到 ID 3 时要怎么做?退出,这样程序就会结束。然后,既然已经创建了这些菜单,因为这是弹出菜单,所以必须绑定到鼠标左键、中键或右键。因此,GLUT 附加菜单意味着将创建的菜单绑定到某处。这里是绑定到右键。当右键被点击时,这些菜单就会展开。让我们看看代码。在菜单创建示例中,颜色菜单 ID 现在是子菜单,在 GLUT 创建菜单时。

Attendees 1 48:13 그다음에 레드 그린 블루 그다음에 또 GLT 크리에이트 메뉴에서 이번에는 상위 메뉴 크리에이트 메뉴를 만든 거고 포인트 라인 폴리곤 그다음에 서브 메뉴 칼라 칼라를 주는데 컬러 메뉴 아이디를 줬는데요. 그다음에 마지막으로는 엔트리로는 엑시트 그다음에 이 메뉴들을 어디에다 붙였어요? 라이트 버튼에다가 붙였죠. 요 아이디는 활용하고 있어요. 안 하고 있어요. 지금 크리에이트 메뉴 아이디는 사용 안 하고 있죠. 근데 만약에 이 크리에이트 메뉴가 또 다른 메뉴의 또 다른 상위 메뉴의 서브 메뉴로 들어갈 수 있죠. 그럴 때 이제 활용을 하라는 얘기예요. 이 크리에이트 메뉴 아이디는 지금은 그렇게 되어 있지는 않고 2층 구조만 가지고 있는 거죠.
然后是红色、绿色、蓝色,接下来是在 GLT 创建菜单中,这次是创建顶级菜单,点、线、多边形,然后是子菜单颜色,给予颜色菜单 ID。最后是退出条目。这些菜单放在哪里了?放在了右键上。这个 ID 正在使用吗?现在不在使用创建菜单 ID。但是,如果这个创建菜单可能成为另一个菜单的子菜单,那么就要开始使用它了。现在它只有两层结构。

Attendees 1 49:06 그래서 오른쪽 버튼 딱 누르는 순간 좀 안 좋아. 뭐야 심리적으로는 안 좋아 보이는데 이런 메뉴가 이제 뜨는 거예요. 포인트 라인 폴리곤 그다음에 칼라는 레드 그린 블록 이렇게 뜨는 거겠죠. 그래서 여러분이 포인트를 탁 누르는 순간은 어떤 이벤트로 전달이 될까? 포인트는 크리에이트 메뉴 있죠 얘한테 얼마 값이 전달이 되냐면 이제 0 값이 전달이 되는 거예요. 크리에이트 메뉴 여기 있네요. 여기 아이디에 0 값이 전달이 되는 거고 액시트를 누르는 순간은 어떻게 될까? 여기 3 값이 전달이 되겠죠. 이 아이디가 3하고 같으면 엑시트 하니까 이제 프로그램이 종료가 될 거예요. 3 누르면 이제 종료가 되겠죠. 그래서 간단한 메뉴까지 이렇게 만들 수가 있어요.
所以当右键点击的那一瞬间,感觉有点不太好。在心理上看起来不太舒服,这个菜单就出现了。点、线、多边形,然后是红色、绿色、蓝色等颜色。当你点击点的那一刻,会传递什么事件?点击创建菜单,传递的值是 0。创建菜单在这里,0 值传递到这个 ID。当点击退出时会怎样?这里会传递 3 值。如果这个 ID 与 3 相同,就会退出程序。点击 3 就会退出。这样就可以创建简单的菜单了。

Attendees 1 49:59 그다음에 보조 함수는 이건 좀 중요한 보조 함수인데 glut 스텝이 디스플레이라는 함수가 있어요. glet 포스트 리 디스플레이는 아까 우리 그리기 함수 등록할 때 어떤 함수 썼어요? glet 디스플레이 펑크라는 함수 썼다고 했었죠. 이 glut 디스플레이 펑크로 등록되는 콜백 함수를 강제로 호출하는 함수가 바로 gut 포스트 리 디스플레이라는 함수예요. 이거는 어떨 때 쓰냐 하면 타이머 함수하고 같이 활용하면 좋아요. 그래서 아까 우리 코드 보면은
接下来是一个重要的辅助函数,叫做 glut 步骤显示函数。我们之前注册绘图函数时使用了哪个函数?我们之前说过使用了 glut 显示函数(glut display func)。glut 后期显示(glut post redisplay)是一个强制调用通过 glut 显示函数注册的回调函数的函数。这个函数通常与定时器函数一起使用效果很好。就像我们之前看到的代码中一样。

Attendees 1 50:41 타이머 함수에서 타이머 함수에서
出席者 1 50:41 在定时器函数中,在定时器函数中

Attendees 1 50:49 타이머 함수에서 주엘유티 포스트 리 디스플레이 함수를 호출해 주면 어떻게 될까요? 이게 10밀리세컨드의 이 타이머 함수가 호출이 되죠. 거기서 glut 포스트 리 디스플레이 함수를 호출하면 누가 호출이 될까 랜더 함수가 호출이 되겠죠. 10밀리세컨드마다 랜드 함수를 반복적으로 호출해 주겠다는 얘기예요.
如果在定时器函数中调用 GLUT 的后重绘函数会发生什么?假设这个定时器函数每 10 毫秒被调用一次。在那里调用 GLUT 后重绘函数,谁会被调用?渲染函数将被调用。这意味着每 10 毫秒会重复调用渲染函数。

Attendees 1 51:16 이해되나요?
你理解了吗?

Attendees 1 51:20 그다음에 전체 코드를 한번 보면은 전체 코드 렌더에서 하는 역할을 보면은 뭐가 있나 보면은 삼각형 하나를 그려요. 삼각형 하나를 그리는데 XY 에서 처음은 x 콤마 y고 그다음에 두 번째 점은 x 더하기 300 콤마 y고 세 번째 점은 x 더하기 150 콤마 y 더하기 300이에요. 그러면 이거는 x 콤마 y를 기준으로 이제 삼각형을 그리는 거예요. 삼각형을 그리는데 타이머 함수에서 해주는 게 뭘까? 타이머 함수에서 이 x와 y 값을 10씩 증가를 시켜주겠다는 얘기예요. 이 x와 y는 어디에 있는 변수가 근데 저녁 변수를 잡아놨네요. 그렇죠 저녁 변수로 10,100 잡았으니까 10 타이머를 조금 천천히 호출 한번 해볼게요. 1초마다 한 번씩
接下来看看整个代码,在渲染中做的是什么。首先绘制一个三角形。这个三角形是基于 x,y 坐标绘制的。第一个点是 x,y;第二个点是 x+300,y;第三个点是 x+150,y+300。这是以 x,y 为基准绘制三角形。计时器函数的作用是什么呢?就是让 x 和 y 值每次增加 10。这些 x 和 y 变量是在哪里定义的呢?他们已经将这些变量设置为晚上的值,也就是 10,100。我们将稍微慢慢调用计时器,每秒调用一次。

Attendees 1 52:17 1초마다 한 번씩 호출하면서 삼각형이 100 올라가죠. 여기가 x 콤마 y 좌표예요. 여기가 더하기 300이 요이고 더하기 150 콤마 300이 이 점이 되는 거죠. 1초마다 한 번씩 이게 뭔가 애니메이션을 줄 때 지금 삼각형이 너무 크죠. 삼각형이 너무 크니까 30 15 30 이렇게 하고 그다음에 100밀리세컨드마다 호출하도록 할게요. 그럼 조금 더 빨리 호출되면서 조금 더 부드럽게 움직이겠죠. 이렇게 움직이는 사각형이 보이죠.
每秒调用一次,三角形向上移动 100。这里是 x,y 坐标,这里是加上 300,这里是加上 150 和 300 的点。每秒调用一次,给出一种动画效果。现在三角形太大了,所以我们将其改为 30、15、30,然后每 100 毫秒调用一次。这样调用得更快,移动会更加平滑。这样就可以看到移动的矩形了。

Attendees 1 53:12 그래서 여러 가지 이제 사실 이제 여기 위치를 바꿔도 되지만 젤 트랜슬레이트 f 해가지고 뭘 해줘도 돼요 이동을 시켜줘도 되겠죠. 회전을 시켜줘도 되고 스케일을 해도 되고 그런 애니메이션들이 만들 수가 있어요.
所以,现在实际上可以更改位置,通过平移 f 或者移动、旋转、缩放,都可以创建这些动画。

Attendees 1 53:31 10분 쉬었다가 2시 10분에 다시 과제에 대해서 설명을 할게요.
休息 10 分钟后,我将在 2 点 10 分继续讲解作业。

clovanote.naver.com