add templates
This commit is contained in:
parent
79b3f91006
commit
637f0ce678
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define ASM_FUNC extern "C"
|
||||||
|
#else
|
||||||
|
#define ASM_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
在cpp中使用extern "C"声明函数,以避免编译时其函数名被修饰(mangle),
|
||||||
|
导致链接失败
|
||||||
|
*/
|
||||||
|
ASM_FUNC int maxofthree(int, int, int);
|
||||||
|
ASM_FUNC int add3(int, int, int);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("%d\n", add3(1, -4, -7));
|
||||||
|
printf("%d\n", add3(1, 2, 3));
|
||||||
|
printf("%d\n", add3(2, -6, 1));
|
||||||
|
|
||||||
|
printf("------\n");
|
||||||
|
|
||||||
|
printf("%d\n", maxofthree(1, -4, -7));
|
||||||
|
printf("%d\n", maxofthree(2, -6, 1));
|
||||||
|
printf("%d\n", maxofthree(2, 3, 1));
|
||||||
|
printf("%d\n", maxofthree(-2, 4, 3));
|
||||||
|
printf("%d\n", maxofthree(2, -6, 5));
|
||||||
|
printf("%d\n", maxofthree(2, 4, 6));
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
.text
|
||||||
|
.globl maxofthree
|
||||||
|
.globl add3
|
||||||
|
maxofthree:
|
||||||
|
#因为参数均为32位整型(int),所以使用ecx,eax等寄存器而非rcx,rax
|
||||||
|
mov %ecx, %eax # 将参数x(在ecx中)放到函数返回值(eax)中
|
||||||
|
cmp %edx, %eax # 比较x(eax)和y(edx)
|
||||||
|
cmovl %edx, %eax # 如果x小于y,将y设置为返回值
|
||||||
|
cmp %r8d, %eax # 比较xy中最大值(eax)和z
|
||||||
|
cmovl %r8d, %eax # 如果比z小,将z设置为返回值
|
||||||
|
ret # 返回eax中的结果
|
||||||
|
add3:
|
||||||
|
mov %ecx, %eax
|
||||||
|
add %edx, %eax
|
||||||
|
add %r8d, %eax
|
||||||
|
ret
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
/* 在这里处理所有的窗口消息(包括输入) */
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch(Message) {
|
||||||
|
|
||||||
|
/* 销毁(关闭)窗口时,让主线程退出 */
|
||||||
|
case WM_DESTROY: {
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 使用默认的输出过程来处理所有其他消息 */
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hwnd, Message, wParam, lParam);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Win32 GUI程序的“main”函数:程序从这里开始执行 */
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||||
|
WNDCLASSEX wc; /* 用于设置窗口的属性 */
|
||||||
|
HWND hwnd; /* 我们的窗口句柄(H代表handle(句柄),WND代表windows(窗口)) */
|
||||||
|
MSG msg; /* 用于临时保存收到的消息 */
|
||||||
|
|
||||||
|
/* 先将整个结构全部置零,然后再设置需要的字段 */
|
||||||
|
memset(&wc,0,sizeof(wc));
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
|
||||||
|
wc.hInstance = hInstance;
|
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
|
||||||
|
/* COLOR_WINDOWS+1为白色。Ctrl+鼠标左键点击COLOR_WINDOW可以查看它的定义 */
|
||||||
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||||
|
wc.lpszClassName = "WindowClass";
|
||||||
|
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* 加载标准图标 */
|
||||||
|
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* 加载标准图标 */
|
||||||
|
|
||||||
|
if(!RegisterClassEx(&wc)) {
|
||||||
|
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, /* x */
|
||||||
|
CW_USEDEFAULT, /* y */
|
||||||
|
640, /* 窗口宽度 */
|
||||||
|
480, /* 窗口高度 */
|
||||||
|
NULL,NULL,hInstance,NULL);
|
||||||
|
|
||||||
|
if(hwnd == NULL) {
|
||||||
|
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
这里是我们程序的核心部分。所有的消息(包括输入)都通过这个循环
|
||||||
|
调用WndProc函数处理。注意GetMessage会程序暂时休眠,直到它收到
|
||||||
|
任意消息为止。所以这个循环不会导致过高的占用CPU。
|
||||||
|
*/
|
||||||
|
while(GetMessage(&msg, NULL, 0, 0) > 0) { /* 如果没有发生错误,且收到了任意消息... */
|
||||||
|
TranslateMessage(&msg); /* 将消息中的键盘码转换为对应的字符 */
|
||||||
|
DispatchMessage(&msg); /* 调用WndProc函数处理消息 */
|
||||||
|
}
|
||||||
|
return msg.wParam;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int add(int x,int y) {
|
||||||
|
int result;
|
||||||
|
asm (
|
||||||
|
"movl %%eax, %1 \n"
|
||||||
|
"addl %%eax, %2 \n"
|
||||||
|
"movl %0, %%eax \n"
|
||||||
|
:"=r"(result) //汇编代码中使用的输出变量
|
||||||
|
:"r"(x),"r"(y) //汇编代码中使用的输入变量
|
||||||
|
:"eax" //汇编代码中写入的寄存器
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int a,b,c;
|
||||||
|
scanf("%d,%d",&a,&b);
|
||||||
|
c=a+b;
|
||||||
|
printf("%d\n",c);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
#include <iostream>
|
||||||
|
// GLEW 使用静态链接,注意函数选项中的相关链接参数
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
// GLFW
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "shader.h"
|
||||||
|
|
||||||
|
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
|
||||||
|
|
||||||
|
// 窗口大小
|
||||||
|
const GLuint WIDTH = 800, HEIGHT = 600;
|
||||||
|
|
||||||
|
// main函数,程序从这里开始执行
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// 初始化GLFW
|
||||||
|
glfwInit();
|
||||||
|
// 设置GLFW必要选项
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
|
|
||||||
|
// 创建GLFW窗口对象
|
||||||
|
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
// 设置必要的回调函数
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
|
||||||
|
// 让GLEW使用现代方式来获取函数指针和扩展
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
// 初始化GLEW,设置OpenGL函数指针
|
||||||
|
glewInit();
|
||||||
|
|
||||||
|
// 设置视图尺寸
|
||||||
|
glViewport(0, 0, WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
|
||||||
|
// 读取shader文件,并编译,见shader.h代码
|
||||||
|
Shader ourShader("shader.vs", "shader.frag");
|
||||||
|
|
||||||
|
|
||||||
|
// 一维数组,每六个代表一个顶点属性,前三个代表位置属性,后三个代表颜色属性
|
||||||
|
GLfloat vertices[] = {
|
||||||
|
// Positions // Colors
|
||||||
|
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Right
|
||||||
|
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom Left
|
||||||
|
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top
|
||||||
|
};
|
||||||
|
GLuint VBO, VAO;//声明顶点缓冲,声明顶点数组用于管理顶点数据
|
||||||
|
glGenVertexArrays(1, &VAO);//创建顶点数组,返回一个独一无二的整数,标识数组
|
||||||
|
glGenBuffers(1, &VBO);//创建顶点缓冲,返回一个独一无二的整数,标识缓冲区
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);//绑定顶点数组
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定顶点缓冲
|
||||||
|
//指定顶点数组的数据源为vertices,第四个参数代表显卡如何管理给定的数据,GL_STATIC_DRWA代表几乎不会改变
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// 指定顶点属性的解析方式。即,如何从顶点缓冲获取相应的顶点属性和相应的颜色属性。或者说,顶点着色器中如何知道去哪个顶点属性分量重着色呢
|
||||||
|
//对每一个顶点而言,属性有2种,一是位置属性,而是颜色属性,因此每六个浮点数决定了一个顶点的位置和颜色
|
||||||
|
|
||||||
|
//顶点着色器中使用layout(location = 0)定义了position顶点属性的位置值(Location),因此第一个参数,代表属性分量的索引
|
||||||
|
//参数二:顶点位置属性的维度,参数三:属性向量的数据类型,参数四:是否标准化;参数五,顶点位置属性的总字节长度,参数六:在缓冲数组中的偏移量,即起始位置
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
|
||||||
|
glEnableVertexAttribArray(0);//启用属性0,因为默认是禁用的
|
||||||
|
|
||||||
|
// 参数一,对应顶点着色器中的layout (location = 1) in vec3 color;参数六:说明颜色属性的偏移量在三个浮点数后,与上文vertices一致
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
|
||||||
|
glEnableVertexAttribArray(1);//启用属性1.
|
||||||
|
|
||||||
|
//顶点数组对象(Vertex Array Object, VAO)的好处就是,当配置顶点属性指针时,你只需要将上面的代码调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。如下文循环中的绑定再解绑
|
||||||
|
glBindVertexArray(0); // 解绑 VAO
|
||||||
|
// 游戏主循环
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
// 检查事件,调用相应的回调函数,如下文的key_callback函数
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
// 渲染
|
||||||
|
// 清除颜色缓冲区(the colorbuffer)
|
||||||
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//渲染颜色到后台缓冲
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);//清除前台缓冲
|
||||||
|
|
||||||
|
// 绘制三角形
|
||||||
|
ourShader.Use();//启用着色器程序
|
||||||
|
glBindVertexArray(VAO);//每次循环都调用,绑定函数绑定VAO
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
glBindVertexArray(0);//解绑
|
||||||
|
|
||||||
|
// 交换屏幕缓冲区(the screen buffers)
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
}
|
||||||
|
// 正确释放所有不再需要的资源
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
glDeleteBuffers(1, &VBO);
|
||||||
|
// 终止GLFW,清理所有GLFW使用的资源
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 当键盘按键被按下/释放时,该函数被调用
|
||||||
|
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
|
||||||
|
{
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||||
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLuint Program;
|
||||||
|
|
||||||
|
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
|
||||||
|
{
|
||||||
|
// 1. 读取顶点(vertex)/片段(fragment)源文件
|
||||||
|
std::string vertexCode;
|
||||||
|
std::string fragmentCode;
|
||||||
|
std::ifstream vShaderFile;
|
||||||
|
std::ifstream fShaderFile;
|
||||||
|
// 确保ifstream对象能够抛出异常:
|
||||||
|
vShaderFile.exceptions(std::ifstream::badbit);
|
||||||
|
fShaderFile.exceptions(std::ifstream::badbit);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 打开文件
|
||||||
|
vShaderFile.open(vertexPath);
|
||||||
|
fShaderFile.open(fragmentPath);
|
||||||
|
std::stringstream vShaderStream, fShaderStream;
|
||||||
|
// 将文件内容读取成字符流
|
||||||
|
vShaderStream << vShaderFile.rdbuf();
|
||||||
|
fShaderStream << fShaderFile.rdbuf();
|
||||||
|
// 关闭文件
|
||||||
|
vShaderFile.close();
|
||||||
|
fShaderFile.close();
|
||||||
|
// 将字符流转换为string字符串
|
||||||
|
vertexCode = vShaderStream.str();
|
||||||
|
fragmentCode = fShaderStream.str();
|
||||||
|
}
|
||||||
|
catch (std::ifstream::failure e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||||
|
}
|
||||||
|
const GLchar* vShaderCode = vertexCode.c_str();
|
||||||
|
const GLchar * fShaderCode = fragmentCode.c_str();
|
||||||
|
// 2. 编译着色器(shaders)
|
||||||
|
GLuint vertex, fragment;
|
||||||
|
GLint success;
|
||||||
|
GLchar infoLog[512];
|
||||||
|
// 顶点着色器(Vertex Shader)
|
||||||
|
vertex = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
|
||||||
|
glShaderSource(vertex, 1, &vShaderCode, NULL);//指定源代码
|
||||||
|
glCompileShader(vertex);//编译着色器
|
||||||
|
// 输出编译错误
|
||||||
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);//查看是否编译成功
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
// 片段着色器(Fragment Shader)
|
||||||
|
fragment = glCreateShader(GL_FRAGMENT_SHADER);//创建片段着色器
|
||||||
|
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||||
|
glCompileShader(fragment);
|
||||||
|
// 输出编译错误
|
||||||
|
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
// 着色器程序(Shader Program)
|
||||||
|
this->Program = glCreateProgram();//创建着色程序
|
||||||
|
glAttachShader(this->Program, vertex);//关联顶点着色器
|
||||||
|
glAttachShader(this->Program, fragment);//关联片段着色器
|
||||||
|
glLinkProgram(this->Program);//链接编译器
|
||||||
|
// 输出链接错误
|
||||||
|
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
// 链接入程序后不再需要这些着色器了,删除它们。
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
|
||||||
|
}
|
||||||
|
// 使用当前着色器
|
||||||
|
void Use()
|
||||||
|
{
|
||||||
|
glUseProgram(this->Program);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 position;//in 代表输入向量, location,与下面的顶点属性描述有关。
|
||||||
|
layout (location = 1) in vec3 color;
|
||||||
|
|
||||||
|
out vec3 ourColor;//out 代表输出3维向量,作为片段着色器的输入,见下文
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 1.0f);
|
||||||
|
ourColor = color;
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rdrawing.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include <raygui.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计算基圆、外旋轮半径和笔尖在外旋轮中位置
|
||||||
|
*
|
||||||
|
* @param baseL 基圆相对半径
|
||||||
|
* @param outerL 外旋轮相对半径
|
||||||
|
* @param pointL 笔尖在外旋轮中相对位置
|
||||||
|
* @param pBaseR 基圆实际半径
|
||||||
|
* @param pOuterR 外旋轮实际半径
|
||||||
|
* @param pPointR 笔尖在滚动圆中实际位置
|
||||||
|
*/
|
||||||
|
void updateRadius(int baseL, int outerL, int pointL, int *pBaseR, int *pOuterR, int *pPointR) {
|
||||||
|
int totalL=baseL+outerL;
|
||||||
|
if (pointL>outerL)
|
||||||
|
totalL+=pointL;
|
||||||
|
else
|
||||||
|
totalL+=outerL;
|
||||||
|
int totalR = 420;
|
||||||
|
int remainder = totalR % totalL;
|
||||||
|
if (remainder!=0) {
|
||||||
|
if (remainder < totalL / 2) {
|
||||||
|
totalR -= remainder;
|
||||||
|
} else {
|
||||||
|
totalR += ( totalL - remainder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pBaseR = (totalR) / totalL * baseL;
|
||||||
|
*pOuterR = (totalR) / totalL * outerL;
|
||||||
|
*pPointR = (totalR) / totalL * pointL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int baseL=2; //默认基圆相对半径
|
||||||
|
int outerL=13; //默认外旋轮相对半径
|
||||||
|
int pointL=3; //默认笔尖在滚动圆中相对位置
|
||||||
|
int baseR,outerR,pointR;
|
||||||
|
int cx=450,cy=450;
|
||||||
|
int speed = 1;
|
||||||
|
|
||||||
|
Color trackColor = BLUE;
|
||||||
|
updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR);
|
||||||
|
|
||||||
|
//初始化绘图窗口
|
||||||
|
InitWindow(1300,900,"Epitrochoid");
|
||||||
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
//读取字体文件
|
||||||
|
char guichars[]="外旋轮基圆笔尖半径速度颜色清除: 0123456789xABCDEF";
|
||||||
|
// 将字符串中的字符逐一转换成Unicode码点,得到码点表
|
||||||
|
int codepointsCount;
|
||||||
|
int *codepoints=LoadCodepoints(guichars,&codepointsCount);
|
||||||
|
// 读取仅含码点表中各字符的字体
|
||||||
|
Font font = LoadFontEx("c:\\windows\\fonts\\simhei.ttf",20,codepoints,codepointsCount);
|
||||||
|
// 释放码点表
|
||||||
|
UnloadCodepoints(codepoints);
|
||||||
|
|
||||||
|
|
||||||
|
//设置GUI控件的字体和大小
|
||||||
|
GuiSetFont(font);
|
||||||
|
GuiSetStyle(DEFAULT,TEXT_SIZE,20);
|
||||||
|
|
||||||
|
// 轨迹图层
|
||||||
|
Image trackImage=GenImageColor(900,900,WHITE);
|
||||||
|
// 绘制图层边框
|
||||||
|
ImageFillRectangleEx(&trackImage,0,0,900,900,LIGHTGRAY);
|
||||||
|
ImageFillRectangleEx(&trackImage,5,5,890,890,WHITE);
|
||||||
|
|
||||||
|
//转动圆图层
|
||||||
|
Image circlesImage = GenImageColor(900,900,BLANK);
|
||||||
|
float r=0;
|
||||||
|
int lastx,lasty;
|
||||||
|
lasty=cy;
|
||||||
|
lastx=cx+(baseR+outerR-pointR);
|
||||||
|
int frameCount = 0;
|
||||||
|
|
||||||
|
//主绘图循环
|
||||||
|
while(!WindowShouldClose()) { //窗口未被关闭
|
||||||
|
//使用raygui绘制控制面板
|
||||||
|
int newOuterL = GuiSliderBar((Rectangle){ 90, 20, 180, 30 },"外旋轮半径",TextFormat("%i", (int)outerL), outerL, 1, 50);
|
||||||
|
int newBaseL = GuiSliderBar((Rectangle){ 90, 60, 180, 30 },"基圆半径",TextFormat("%i", (int)baseL), baseL, 1, 50);
|
||||||
|
int newPointL = GuiSliderBar((Rectangle){ 90, 100, 180, 30 },"笔尖半径",TextFormat("%i", (int)pointL), pointL, 1, 50);
|
||||||
|
speed = GuiSliderBar((Rectangle){ 90, 150, 180, 30 },"速度",TextFormat("%i", (int)speed), speed, 1, 50);
|
||||||
|
GuiLabel((Rectangle){ 20, 220, 180, 30 },TextFormat("颜色: 0x%02X%02X%02X",(int)(trackColor.r), (int)(trackColor.g),(int)(trackColor.b)));
|
||||||
|
trackColor= GuiColorPicker((Rectangle){ 50, 250, 196, 192 }, NULL, trackColor);
|
||||||
|
int doClear = GuiButton((Rectangle){ 120, 700, 80, 30 },"清除");
|
||||||
|
if (newOuterL!=outerL || newBaseL!=baseL || newPointL!=pointL) {
|
||||||
|
//圆参数有变化,清除轨迹图层
|
||||||
|
if (newOuterL!=outerL)
|
||||||
|
pointL=newOuterL;
|
||||||
|
else
|
||||||
|
pointL=newPointL;
|
||||||
|
outerL=newOuterL;
|
||||||
|
baseL=newBaseL;
|
||||||
|
updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR);
|
||||||
|
lasty=cy;
|
||||||
|
lastx=cx+(baseR+outerR-pointR);
|
||||||
|
r=0;
|
||||||
|
ImageClearBackground(&trackImage,WHITE);
|
||||||
|
ImageFillRectangleEx(&trackImage,0,0,900,900,LIGHTGRAY);
|
||||||
|
ImageFillRectangleEx(&trackImage,5,5,890,890,WHITE);
|
||||||
|
} else if (doClear) {
|
||||||
|
//按下了清除按钮,清除轨迹图层
|
||||||
|
ImageClearBackground(&trackImage,WHITE);
|
||||||
|
ImageFillRectangleEx(&trackImage,0,0,900,900,LIGHTGRAY);
|
||||||
|
ImageFillRectangleEx(&trackImage,5,5,890,890,WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新圆位置
|
||||||
|
r+=0.01;
|
||||||
|
float outerCX=cx+ (baseR+outerR)*cos(r);
|
||||||
|
float outerCY=cy+ (baseR+outerR)*sin(r);
|
||||||
|
float theta = r * (baseL+outerL) / outerL;
|
||||||
|
int x=round(outerCX - pointR * cos(theta));
|
||||||
|
int y=round(outerCY - pointR * sin(theta));
|
||||||
|
|
||||||
|
//更新轨迹
|
||||||
|
ImageDrawLineEx(&trackImage,lastx,lasty,x,y,3,trackColor);
|
||||||
|
|
||||||
|
frameCount++;
|
||||||
|
if (frameCount>=speed) {
|
||||||
|
//更新转动圆图层中各圆的位置
|
||||||
|
ImageClearBackground(&circlesImage,BLANK);
|
||||||
|
|
||||||
|
ImageDrawCircleEx(&circlesImage,cx,cy,baseR,1,LIGHTRED);
|
||||||
|
ImageDrawCircleEx(&circlesImage,outerCX,outerCY,outerR,1,LIGHTSLATEGRAY);
|
||||||
|
ImageDrawLineEx(&circlesImage,cx,cy,outerCX,outerCY,1,LIGHTRED);
|
||||||
|
ImageDrawLineEx(&circlesImage,x,y,outerCX,outerCY,1,LIGHTSLATEGRAY);
|
||||||
|
ImageDrawPointEx(&circlesImage,x,y,7,RED);
|
||||||
|
|
||||||
|
//将图层绘制到屏幕中(GPU绘图)
|
||||||
|
Texture trackTexture = LoadTextureFromImage(trackImage);
|
||||||
|
Texture circlesTexture = LoadTextureFromImage(circlesImage);
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawTexture(trackTexture,300,0,WHITE);
|
||||||
|
DrawTexture(circlesTexture,300,0,WHITE);
|
||||||
|
EndDrawing();
|
||||||
|
UnloadTexture(circlesTexture);
|
||||||
|
UnloadTexture(trackTexture);
|
||||||
|
frameCount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastx=x;
|
||||||
|
lasty=y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//释放图层资源
|
||||||
|
UnloadImage(circlesImage);
|
||||||
|
UnloadImage(trackImage);
|
||||||
|
//关闭窗口
|
||||||
|
CloseWindow();
|
||||||
|
}
|
Loading…
Reference in New Issue