同步操作将从 FlameAI/SIGer 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
本篇issue的灵感来源于一次「计算机图形学」的作业。
开篇先来几张视觉冲击力强的实现效果图:
·开发环境:win10 VS2019
·所需调用的OpenGL库:glut
温馨提示:新建项目时务必记得提前下载glut包、配置好环境!
主要代码来源于CSDN上的一位名叫iamttp的博主。
附原帖链接
#include <GL/glut.h>
#include <cmath>
#include <cstdio>
#include <ctime>
static double myratio; // angle绕y轴的旋转角,ratio窗口高宽比
static double x = 0.0f, y = 0.0f, z = 1.3f; //相机位置
static double lx = 0.0f, ly = 0.0f, lz = -1.0f; //视线方向,初始设为沿着Z轴负方向
const int WIDTH = 1000;
const int HEIGHT = 1000;
bool mouseDown = false;
double xrot = 0.0f, yrot = 0.0f;
double xdiff = 0.0f, ydiff = 0.0f;
/**
* 定义观察方式
*/
void changeSize(int w, int h) {
//除以0的情况
if (h == 0) h = 1;
myratio = 1.0f * w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//设置视口为整个窗口大小
glViewport(0, 0, w, h);
//设置可视空间
gluPerspective(45, myratio, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z, x + lx, y + ly, z + lz, 0.0f, 1.0f, 0.0f);
}
/**
* 视野漫游函数
*/
void orientMe(double directionx, double directiony) {
x += directionx * 0.1;
y += directiony * 0.1;
glLoadIdentity();
gluLookAt(x, y, z, x + lx, y + ly, z + lz, 0.0f, 1.0f, 0.0f);
}
/**
* 视野漫游函数
*/
void moveMeFlat(int direction) {
z += direction * (lz) * 0.1;
glLoadIdentity();
gluLookAt(x, y, z, x + lx, y + ly, z + lz, 0.0f, 1.0f, 0.0f);
}
// 鼠标右键stop
bool stop = false;
/**
* 鼠标事件
*/
void mouse(int button, int state, int x, int y) {
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
stop = !stop;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
mouseDown = true;
xdiff = x - yrot;
ydiff = -y + xrot;
}
else
mouseDown = false;
}
/**
* 鼠标移动事件
*/
void mouseMotion(int x, int y) {
if (mouseDown) {
yrot = x - xdiff;
xrot = y + ydiff;
glutPostRedisplay();
}
}
/**
* 加入按键控制
*/
double rateZoom = 1.5f;
const int N = 110, M = 1000;
struct col {
GLushort r, g, b;
} colKTable[N];
struct pos {
double x, y, z;
} posArr[HEIGHT * WIDTH];
col colArr[HEIGHT * WIDTH];
int index_list[HEIGHT * WIDTH];
struct complex {
double i, j;
inline complex mul(complex& b) {
double tempI = i * b.i - j * b.j;
double tempJ = i * b.j + j * b.i;
i = tempI, j = tempJ;
return *this;
}
inline complex add(complex& b) {
i += b.i, j += b.j;
return *this;
}
};
complex alpha{ 0, 0 };
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(x, y, z, x + lx, y + ly, z + lz, 0.0f, 1.0f, 0.0f);
// 实现鼠标旋转的核心
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_DOUBLE, sizeof(pos), posArr);
glColorPointer(3, GL_UNSIGNED_SHORT, sizeof(col), colArr);
glDrawElements(GL_POINTS, HEIGHT * WIDTH, GL_UNSIGNED_INT, index_list);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glFlush();
glutSwapBuffers();
}
double CalFrequency() {
static int count;
static double save;
static clock_t last, current;
double timegap;
++count;
if (count <= 50)
return save;
count = 0;
last = current;
current = clock();
timegap = (current - last) / (double)CLK_TCK;
save = 50.0 / timegap;
return save;
}
bool isGo = true;
void myIdle() {
if (stop) return;
double FPS = CalFrequency();
printf("FPS = %f\n", FPS);
double rate = 0.03;
static double ii = -1, jj = -1;
if (isGo) {
static bool flag = true;
if (flag) ii += rate;
else ii -= rate;
if (ii > 1) {
jj += rate;
flag = false;
}
if (ii < -1) {
jj += rate;
flag = true;
}
if (jj == 0) {
ii += rate;
}
}
complex C{ ii, jj };
double d = rateZoom * 2 / HEIGHT;
#pragma omp parallel for
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++) {
auto& item = colArr[i * WIDTH + j];
item.r = item.g = item.b = 0;
complex X{ -rateZoom + i * d, -rateZoom + j * d }; // (-1.5,1.5)
X = X.add(alpha);
for (auto& k : colKTable) {
X = X.mul(X).add(C);
if (X.i * X.i + X.j * X.j > M) {
item.r = k.r;
item.g = k.g;
item.b = k.b;
break;
}
}
}
myDisplay();
}
void init() {
for (int k = 0; k < N; k++) {
int tempK = k * k;
tempK = tempK * tempK;
colKTable[k].r = tempK + tempK;
colKTable[k].g = exp(k);
colKTable[k].b = tempK * k;
}
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++) {
posArr[i * WIDTH + j].x = -0.5 + (double)i / (HEIGHT); // (-1,1)
posArr[i * WIDTH + j].y = -0.5 + (double)j / (WIDTH); // (1,-1)
posArr[i * WIDTH + j].z = 0.1;
index_list[i * WIDTH + j] = i * WIDTH + j;
}
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
}
void processSpecialKeys(int key, int x, int y) {
bool temp;
temp = stop;
stop = false;
isGo = false;
// 越近加的越慢
double addRate = 0.1 * std::abs(std::exp(rateZoom) - 1);
switch (key) {
case GLUT_KEY_UP:
// orientMe(0, 1);
alpha.j += addRate;
break;
case GLUT_KEY_DOWN:
// orientMe(0, -1);
alpha.j -= addRate;
break;
case GLUT_KEY_LEFT:
// orientMe(-1, 0);
alpha.i -= addRate;
break;
case GLUT_KEY_RIGHT:
// orientMe(1, 0);
alpha.i += addRate;
break;
case GLUT_KEY_PAGE_DOWN:
// moveMeFlat(-1);
rateZoom = (rateZoom + addRate) > 2 ? 2 : rateZoom + addRate;
break;
case GLUT_KEY_PAGE_UP:
// moveMeFlat(1);
rateZoom -= addRate;
break;
case GLUT_KEY_END:
moveMeFlat(-1);
break;
case GLUT_KEY_HOME:
moveMeFlat(1);
break;
default:
break;
}
myIdle();
stop = temp;
isGo = true;
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(300, 0);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Demo"); // 改了窗口标题
glutDisplayFunc(myDisplay);
glutIdleFunc(myIdle); // 表示在CPU空闲的时间调用某一函数
glutSpecialFunc(processSpecialKeys); // 按键
glutReshapeFunc(changeSize);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
init();
glutMainLoop();
return 0;
}
· 代码中包含的主要交互功能 :
鼠标右键 —— 暂停/继续
方向键 —— 移动
PGUP —— 放大
PGDN —— 缩小
HOIME —— 三维空间放大
END —— 三维空间缩小
鼠标左键 —— 移动三维空间
代码在这一块儿也有注释,「尝试改变迭代关系」可以呈现不同的动态效果,大家可以自己试试。
· 分形几何可以实现动态效果的原理 :
不同的像素坐标映射比例会决定分形图的大小。
不同的像素坐标映射加上偏移量会决定分形图的偏移。
根据这些原理,大家也可以「调整参数」,实现不一样的视觉效果。
· 其他 :
开源的代码基本可以实现预期的功能,但有一些小bug需要根据自己的开发环境作调整。
大家也可以根据自己的审美调整「色彩的搭配」。
这个内容,可以跟在, #I4R77Y:分形几何 帖子下面,汇集一定的资料后,我建议:
1, 将源码单独建立一个仓,比如叫分形几何 示范程序
2, 围绕这个示范程序库,制作一个详尽的 README,
3, 并依据这个 README, 制作围绕这个示范库的推介,包括作者介绍,同类项目和软件分析比对等。将会是非常棒的独立期刊。有库有宣传。
- 开发环境:win10 VS2019
- 所需调用的OpenGL库:glut
- 代码中包含的主要交互功能
鼠标右键 —— 暂停/继续
方向键 —— 移动
PGUP —— 放大
PGDN —— 缩小
HOIME —— 三维空间放大
END —— 三维空间缩小
鼠标左键 —— 移动三维空间
代码在这一块儿也有注释,「尝试改变迭代关系」可以呈现不同的动态效果,大家可以自己试试。
- 分形几何可以实现动态效果的原理
不同的像素坐标映射比例会决定分形图的大小。
不同的像素坐标映射加上偏移量会决定分形图的偏移。
根据这些原理,大家也可以「调整参数」,实现不一样的视觉效果。
- 其他
开源的代码基本可以实现预期的功能,但有一些小bug需要根据自己的开发环境作调整。
大家也可以根据自己的审美调整「色彩的搭配」。
温馨提示:新建项目时务必记得提前下载glut包、配置好环境!
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
单独建立目录,需要慎重,目前,以 sig 目录下为编委自荐目录。可以先在ISSUES 中充分讨论。再行动,避免过多 PR 被拒绝。
https://www.bilibili.com/video/BV12L4y1g7Uz
录屏
@cchen55 袁老师,前段时间因为我有点事情一直没有跟进分形几何的进度,现在忙完了,今天做了一个动画的视频,您看看效果怎么样
@cchen55 这是程序生成的,然后我录了一下屏
@袁德俊 相当漂亮啊,然后这个音乐配的也很激动人心哈,然后你把那个整个程序仓库然后建好,然后专题就出来,啊然后选一张最漂亮的这个瞬间啊,然后我坐这儿给你看好,就这样等你的这个仓库建立,你单独建一个仓库,然后要求是什么呢?你要写写好说明文档,就说你这个动画怎么产生啊,然后怎么调整能够变化呀。颜色、形状等等吧,能多写一些就能够让同学们DIY。回头我让其他的同学这个尝试一下,看看怎么能弄出不同的版本和花样儿啊,这样子你的任务就完成了,这是一个大任务哈,你申请那点儿小事儿都通过啊。
· 代码中包含的主要交互功能 :
鼠标右键 —— 暂停/继续
方向键 —— 移动
PGUP —— 放大
PGDN —— 缩小
HOIME —— 三维空间放大
END —— 三维空间缩小
鼠标左键 —— 移动三维空间
代码在这一块儿也有注释,「尝试改变迭代关系」可以呈现不同的动态效果,大家可以自己试试。
背景图还有瑕疵,需要继续渲染!2480x3508 300DPI
【OpenGL】专栏总揽 与 CLion VS2019 环境配置(零)
CLion 配置我的 CLion 使用的是Code::Block的 MinGW,如果要在Win10上使用CLion 需要设置 Toolchains ,在 CLion 设置中即可查看。你也可以网上查找 MinGW CLion 配置。配置好CLion,可以正常运行C++后,需要到https://www.transmissionzero.co.uk/software/freeglut-devel/...
原创 2020-01-11 17:20:58 · 1658 阅读 · 0 评论
【OpenGL】太阳、地球、月亮实例(一)
准备把自己这几天的学习opengl的经验写下来,自己是这方面的小白,希望大神可以对有问题以及可以优化的地方提出来。也欢迎指出不足和吐槽。希望帮到小白。自己参考得比较多的网站是这个:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html第一个实例也是上面的网站给出来的,但是进行了一点点优化。所有代码都可以去github免费...
原创 2019-09-12 18:28:25 · 2970 阅读 · 3 评论
【OpenGL】太阳、地球、月亮实例(二)
自己是这方面的小白,希望大神可以对有问题以及可以优化的地方提出来。也欢迎指出不足和吐槽。希望帮到小白。opengl 太阳、地球、月亮 酷炫实例(一):https://blog.csdn.net/qq_40515692/article/details/100778870自己参考得比较多的网站是这个:http://www.cppblog.com/doing5552/archive/2009/0...
原创 2019-09-13 14:51:29 · 800 阅读 · 0 评论
【OpenGL】 粒子系统实例(三)
自己是这方面的小白,希望大神可以对有问题以及可以优化的地方提出来。也欢迎指出不足和吐槽。希望帮到小白。opengl 太阳、地球、月亮 酷炫实例(一):https://blog.csdn.net/qq_40515692/article/details/100778870opengl 太阳、地球、月亮 酷炫实例(二):https://blog.csdn.net/qq_40515692/arti...
原创 2019-09-14 17:48:20 · 1042 阅读 · 1 评论
【OpenGL】鼠标控制旋转(四)
首先声明自己是这方面的小白,希望大神可以对有问题以及可以优化的地方提出来。也欢迎指出不足和吐槽。希望帮到小白。自己参考得比较多的网站是这个:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html所有代码都可以去github免费下载(不怎么喜欢CSDN的积分下载):https://github.com/Iamttp/Ope...
原创 2019-11-04 18:38:29 · 3075 阅读 · 9 评论
【OpenGL】分形Julia集 OpenGL C++实现(五)
文章目录一、环境配置与运行opengl配置OpenMP配置二、代码讲解三、最终代码四、效果演示一、环境配置与运行opengl配置作者用的是VS2019,首先是新建项目然后是下载glut包,它帮助你使用opengl复制文末的代码,Ctrl+F5 运行。这个时候应该会比较卡。修改到release,会优化代码,加快速度。如果你的电脑是单核CPU,可以通过减少N的值加快速度(但是会降低部分精度)。OpenMP配置这样就可以比较愉快的运行了。操作指南:鼠标右键 —— 暂停/
原创 2020-06-24 22:05:53 · 1211 阅读 · 2 评论
【OpenGL】分形Julia集 现代OpenGL C++ GLSL实现(六)
问题1: GLSL现阶段貌似只有float类型,这会导致放大一点后就出现模糊的情况。问题2: 按键我暂时没管了,需要连续按,如果不喜欢可以用标志位解决。但是我发现貌似glfw的鼠标键盘事件貌似都不怎么灵敏,不知道是不是使用方式有误。main.cpp#include #include #define GLEW_STATIC#include <GL/glew.h>#include <GLFW/glfw3.h>#
原创 2020-07-01 21:46:26 · 756 阅读 · 0 评论
【OpenGL】谢尔宾斯基(Sierpinski)地毯 OpenGL分形(七)
main.cpp#include #include #include #define GLEW_STATIC#include <GL/glew.h>#include <GLFW/glfw3.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc.
原创 2020-07-10 09:43:22 · 1090 阅读 · 0 评论
多道程序缓冲区协调操作 C++11多线程+OpenGL可视化实现
先上题目:再上结果分析对于这道题第一想法大都会是生产-消费者模型。这里确实非常类似,区别主要就是Move操作,但是Move操作可以看成 Put 和 Get 操作结合。这里首先讲解下生产-消费者模型:生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。...
原创 2020-07-03 08:26:33 · 1134 阅读 · 0 评论
sig/math/分形几何2与openGLglut库.md @cchen55 2022-10-22
登录 后才可以发表评论