Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456

Баг в коде Reaction Diffusion Gray-Scott model

11.12.2020, 02:04. Показов 4552. Ответов 47

Студворк — интернет-сервис помощи студентам
Изначально первоисточник формул https://www.karlsims.com/rd.html
Как сделать тоже самое в коде С++ получить значение цвета параметр “c” из кода javascript. Пытаюсь сделать этот код Reaction Diffusion Gray-Scott model

https://youtu.be/BV9ny785UNc?t=2315
что за
JavaScript
1
2
floor((a-b)*255);  // это вроде округление и умножение на 255..
c=constrain (c, 0,255); // что это?
http://яваскрипт.укр/Constrain
это типа нормализация? А где поиск макс мин значения во всем массиве значений?
Как это вообще возможно. Или это обрезка значений?
https://www.arduino.cc/referen... constrain/
x: if x is between a and b.
a: if x is less than a.
b: if x is greater than b.
Тогда работать по идее не должно вообще.
Вроде что-то рисует но проблема с окрасом. Нужен окрас всем каналам float от 0 до 1.
Самое забавное что делал сам другой алгоритм с просто описания из
Cyclic_Symmetric_Multi-Scale_Turing_Patterns.pdf
Один паттерн Тьюринга,перевод гугла.
«В этой модели есть только одно« вещество », которое играет роль пигментации,
активатор и ингибитор. Он представлен одним числом с плавающей запятой для каждого элемента прямоугольный массив. Элементы массива можно рассматривать как эквивалентные ячейкам в дискретном модель, предложенная Тьюрингом в его статье. Число с плавающей запятой, представляющее концентрацию вещество становится значением пикселя в результирующем изображении шкалы серого. Распространение моделируется с помощью среднее значение определенной области вокруг каждого элемента, меньшей площади для активатора и большей область для ингибитора. Простое правило итеративно применяется ко всем элементам массива для (обычно) сотен временных шагов: если средняя концентрация в меньшей области больше, чем средняя концентрация в большей области, увеличьте значение на небольшую величину, в противном случае уменьшите значение на небольшую величину. В на каждом временном шаге полученные значения повторно нормализуются в несколько произвольный диапазон от -1,0 до 1,0, чтобы избежать "убегай". Чтобы избежать краевых эффектов, накладываются периодические граничные условия ».

Сделал две свертки там с ядрами 3х3 и 5х5
Что –то рисовало.
Название: ScreenShot00662.jpg
Просмотров: 382

Размер: 26.1 Кб
Название: ScreenShot00661.jpg
Просмотров: 382

Размер: 34.4 Кб
А этот код вроде намного проще и ядро всего 3х3, и на сайте большое разнообразие форм.Не знаю как исправить код.
C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <gl/glut.h>
#include <iostream> 
using namespace std;
 
const int imSiz=300; // размер картинки
 
float grid[imSiz+2][imSiz+2][2]={0};  // основной массив
float next[imSiz+2][imSiz+2][2]={0}; // буферный массив
bool render_complete=0;
float
Da=1.0,
Db=0.5,
k=0.062,
f=0.085;
 
 
//==============================================
//==============================================
//рисуем пиксели с окрасом
void drawPixelArray() 
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    for(int i = 1; i < imSiz+1; i++)
    {
        for (int j = 1; j < imSiz+1; j++)
        {
            float a=grid[i][j][1];
            glColor3f(a, a, a);
            glVertex2i(i,j);
        }
    }
    glEnd();
    render_complete=1;
}
//рисуем пиксели с окрасом
//==============================================
//==============================================
 
 
 
 
//==============================================
//==============================================
//====расчет  новой концетрации 
void conectratCorrection()
{
 
//------------------------------------------
//очистка буфера next
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
    next[i][j][0]=0;
    next[i][j][1]=0;
    }
}
//очистка буфера next
//------------------------------------------
 
 
 
//------------------------------------------
//свертка массива greed с ядром 3 на 3, лапласиан    
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
    float sumA=
    grid[i][j][0]*-1.0+
    grid[i-1][j][0]*0.2+
    grid[i+1][j][0]*0.2+
    grid[i][j+1][0]*0.2+
    grid[i][j-1][0]*0.2+
    grid[i-1][j-1][0]*0.05+
    grid[i+1][j-1][0]*0.05+
    grid[i+1][j+1][0]*0.05+
    grid[i-1][j+1][0]*0.05;
 
    float sumB=
    grid[i][j][1]*-1.0+
    grid[i-1][j][1]*0.2+
    grid[i+1][j][1]*0.2+
    grid[i][j+1][1]*0.2+
    grid[i][j-1][1]*0.2+
    grid[i-1][j-1][1]*0.05+
    grid[i+1][j-1][1]*0.05+
    grid[i+1][j+1][1]*0.05+
    grid[i-1][j+1][1]*0.05; 
 
    float a=grid[i][j][0];
    float b=grid[i][j][1];
    //next[i][j][0]=a+(Da*sumA)-(a*b*b)+(f*(1.0-a));
    //next[i][j][1]=b+(Db*sumB)+(a*b*b)-((k+f)*b);
    next[i][j][0]=(Da*sumA)-(a*b*b)+(f*(1.0-a));
    next[i][j][1]=(Db*sumB)+(a*b*b)-((k+f)*b);
    }
}
//свертка массива greed с ядром 3 на 3, лапласиан
//------------------------------------------
 
 
//------------------------------------------
//сумма старых значений  grid и новых next.
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
        grid[i][j][0]+=next[i][j][0];
        grid[i][j][1]+=next[i][j][1];
    }
}
 
//сумма старых значений  grid и новых next.
//------------------------------------------
drawPixelArray(); 
}
//====расчет  новой концетрации
//==============================================
//==============================================
 
 
//==============================================
//==============================================
//нарисовать квадрат 10 пикселей веществом B
void genArr()
{
for(int i = 0; i < imSiz+2; i++)
{
    for (int j = 0; j < imSiz+2; j++)
    {
        if(i>120 && i<180 && j>120 && j<180)
        {
            grid[i][j][0]=1;
            grid[i][j][1]=1;
        }
        else
        {
            grid[i][j][0]=1;
            grid[i][j][1]=0;
        }
    }
}
//drawPixelArray();
conectratCorrection();
}
//нарисовать квадрат 10 пикселей веществом B
//==============================================
//==============================================
 
 
 
//==============================================
//==============================================
//проверяет готов ли рендер, если да то обновляет экран и запуск таймера
void TimerFunction(int value)
{
    if(render_complete) 
    {
        glutSwapBuffers();
        render_complete=0;
        glutTimerFunc(33, TimerFunction, 1);
        cout << "New frame"<<endl;
        conectratCorrection();
    }
    else
    {
        cout << "Frame lost!----------"<<endl;
    }
}
//проверяет готов ли рендер, если да то обновляет экран и запуск таймера
//==============================================
//==============================================
 
 
void setupGL() 
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, imSiz , imSiz, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glPointSize(1);
    genArr();
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(imSiz, imSiz); 
    glutInitWindowPosition(500, 200);
    glutCreateWindow("Reaction Diffusion Gray-Scott model");
    setupGL();
    glutTimerFunc(33, TimerFunction, 1);
    glutMainLoop();
    return 0;
}
Рисует ерунду.

Название: ScreenShot00660.jpg
Просмотров: 379

Размер: 1.0 Кб
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.12.2020, 02:04
Ответы с готовыми решениями:

Heat equaton, thermal diffusion equation, теплопроводность
Не могу разобраться в чем проблема. Пожалуйста взгляните. Пытался 3d уравнение теплового приготовления пищи стейк. clear all close all...

Создание input с привязкой к ng-model программно(в коде функции)
Всем привет! Вопрос: возможно ли создать &lt;select&gt; программно- в функции(например когда нажал какую-нибудь кнопку-редактировать) и...

Баг в коде
ловит кекалочку после ввода функции Выбираю функцию ,не срабатывет , снова выдаёт результат другой функцции , потом следует выбор b...

47
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
13.12.2020, 17:21  [ТС]
Студворк — интернет-сервис помощи студентам
zayats80888, Вроде сделал и ошибок нет но рисует ерунду. Где-то алгоритмическая ошибка? Редактировал код с поста 18.

C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#include <gl/glut.h>
#include <iostream> 
using namespace std;
#include <stdlib.h>
#include <math.h>
#include <iomanip>
 
const int imSiz=300; // размер картинки
 
typedef float(ArrType)[imSiz+2][imSiz+2][2];
ArrType nextArr;   // буферный массив
ArrType grid;  // основной массив
 
ArrType *gridPtr = &grid,  
        *nextArrPtr = &nextArr;   
 
 
 
float ColorArr[imSiz+2][imSiz+2][3]; //  массив для окраса
 
bool render_complete = 0;
 
float dA = 1.0;
float dB = 0.5;
float k = 0.062f;
float feed = 0.055f;
 
int counter;
int FramesPass=50;
 
void swap()
{
    ArrType *temp = gridPtr;
    gridPtr = nextArrPtr;
    nextArrPtr = temp;
}
 
 
float constrain(float x,float a,float b)
{
    if(x<a){return a;}
    if(x>b){return b;}
    return x;
}
 
 
 
float laplaceA(int x,int y) {
  float sumA = 0;
  sumA += grid[x][y][0] * -1;
  sumA += grid[x - 1][y][0] * 0.2f;
  sumA += grid[x + 1][y][0] * 0.2f;
  sumA += grid[x][y + 1][0] * 0.2f;
  sumA += grid[x][y - 1][0] * 0.2f;
  sumA += grid[x - 1][y - 1][0] * 0.05f;
  sumA += grid[x + 1][y - 1][0] * 0.05f;
  sumA += grid[x + 1][y + 1][0] * 0.05f;
  sumA += grid[x - 1][y + 1][0] * 0.05f;
  return sumA;
}
 
float laplaceB(int x, int y) {
  float sumB = 0;
  sumB += grid[x][y][1] * -1.0f;
  sumB += grid[x - 1][y][1] * 0.2f;
  sumB += grid[x + 1][y][1] * 0.2f;
  sumB += grid[x][y + 1][1] * 0.2f;
  sumB += grid[x][y - 1][1] * 0.2f;
  sumB += grid[x - 1][y - 1][1] * 0.05f;
  sumB += grid[x + 1][y - 1][1] * 0.05f;
  sumB += grid[x + 1][y + 1][1] * 0.05f;
  sumB += grid[x - 1][y + 1][1] * 0.05f;
  return sumB;
}
 
 
 
 
 
//==============================================
//рисует пиксели
void drawPixelArray() 
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            glColor3f(ColorArr[x][y][0], ColorArr[x][y][1], ColorArr[x][y][2]);
            glVertex2i(x,y);
        }
    }
    glEnd();
}
//рисует пиксели
//==============================================
 
 
 
 
 
//==============================================
//число от 0 до 1 преобразует в цвет RGB
void ColoringAlgorithm()
{
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            float color=nextArr[x][y][0]-nextArr[x][y][1];
            color=constrain(color, 0.0f, 1.0f); // наверно на всякий случай тут constrain
            ColorArr[x][y][0]=0.5+0.4*sin(15.1*color+1.6);
            ColorArr[x][y][1]=0.5+0.4*sin(13.1*color+0.4);
            ColorArr[x][y][2]=0.5+0.45*sin(14.2*color-1.5);
        }
    }
    drawPixelArray();
}
//число от 0 до 1 преобразует в цвет RGB
//==============================================
 
 
 
 
 
//===================================================
//расчет  новой концетрации 
void NewConectration()
{
    ArrType &grid = *gridPtr; 
    ArrType &nextArr = *nextArrPtr;
//копирование строки и стольбцов, нужно для правильности свертки
    for(int y = 0; y < imSiz+2; y++)
    {
        grid[imSiz+1][y][0]=grid[1][y][0]; // строка 1 в строку imSiz+1
        grid[0][y][0]=grid[imSiz][y][0]; 
        grid[imSiz+1][y][1]=grid[1][y][1]; 
        grid[0][y][1]=grid[imSiz][y][1]; 
        //cout<<setw(5)<<fixed<<setprecision(1)<<grid[1][y][0];
    }
 
 
////ОТЛАДКА---------------------------------
////показать весь массив
//cout<< "\n";
//cout<< "\n";
//for(int x = 0; x < imSiz+2; x++)
//{
//  for (int y = 0; y < imSiz+2; y++)
//  {
//  cout<<setw(5)<<fixed<<setprecision(1)<<grid[x][y][0];
//  }
//  cout<< "\n";
//}
////показать весь массив
////ОТЛАДКА---------------------------------
 
 
//копирование столбцов
    for(int x = 0; x < imSiz+2; x++)
    {
        grid[x][imSiz+1][0]=grid[x][1][0];
        grid[x][imSiz+1][1]=grid[x][1][1];
        grid[x][0][0]=grid[x][imSiz][0];
        grid[x][0][1]=grid[x][imSiz][1];
 
    }
//копирование строки и стольбцов, нужно для правильности свертки
    //cout<< "\n";
    //cout<< "\n";
////ОТЛАДКА---------------------------------
////показать весь массив
//for(int x = 0; x < imSiz+2; x++)
//{
//  for (int y = 0; y < imSiz+2; y++)
//  {
//  cout<<setw(5)<<fixed<<setprecision(1)<<grid[x][y][0];
//  }
//  cout<< "\n";
//}
////показать весь массив
////ОТЛАДКА---------------------------------
 
 
 
//свертка ядром 3х3
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            float a = grid[x][y][0];
            float b = grid[x][y][1];
            nextArr[x][y][0] = a + dA * laplaceA(x, y) - a * b * b + feed * (1 - a);
            nextArr[x][y][1] = b + dB * laplaceB(x, y) + a * b * b - (k + feed) * b;
            nextArr[x][y][0] = constrain(nextArr[x][y][0], 0.0f, 1.0f);
            nextArr[x][y][1] = constrain(nextArr[x][y][1], 0.0f, 1.0f);
        }
    }
 
    counter++;
    if(counter==FramesPass) // пропуск окраса N кадров,ускорение дифузии
    {
        ColoringAlgorithm();
    }
    swap();
////====непонятное копирование одного массива в другой с буферным 
////он же в  оригинальном коде "swap" , без этого не пашет
//float temp0,temp1;
//  for(int x = 1; x < imSiz+1; x++)
//  {
//      for (int y = 1; y < imSiz+1; y++)
//      {
//          temp0=grid[x][y][0];
//          temp1=grid[x][y][1];
//          grid[x][y][0]=nextArr[x][y][0];
//          grid[x][y][1]=nextArr[x][y][1];
//          nextArr[x][y][0]=temp0;
//          nextArr[x][y][1]=temp1;
//      }
//  }
////====непонятное копирование одного массива в другой с буферным 
////он же в  оригинальном коде "swap" , без этого не пашет
 
// пропуск окраса N кадров,ускорение дифузии 
    if(counter==FramesPass) 
    {
        counter=0;
        glutSwapBuffers();
        cout << "FramesPass="<<FramesPass<<endl;
        //NewConectration();
    }
NewConectration();
// пропуск окраса N кадров,ускорение дифузии
}
//расчет  новой концетрации 
//===================================================
 
 
 
 
 
//===================================================
//нарисовать примерно прямоугольник в центре массива веществом B
void FillRectangleArea()
{
    for(int x = 0; x < imSiz+2; x++)
    {
        for (int y = 0; y < imSiz+2; y++)
        {
            if(x>110 && x<180 && y>110 && y<180)
            {
                grid[x][y][0]=1.0;
                grid[x][y][1]=1.0;
            }
            else
            {
                grid[x][y][0]=1.0;
                grid[x][y][1]=0.0;
            }
        }
    }
    NewConectration();
}
//нарисовать прямоугольник в центре массива веществом B
//===================================================
 
 
void setupGL() 
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, imSiz , imSiz, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glPointSize(1);
    FillRectangleArea();
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(imSiz, imSiz); 
    glutInitWindowPosition(500, 200);
    glutCreateWindow("Reaction Diffusion Gray-Scott model");
    setupGL();
    glutMainLoop();
    return 0;
}
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
13.12.2020, 17:31
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Где-то алгоритмическая ошибка?
Ну да, к массивам обращаться ТОЛЬКО через указатели. Я показал как.
Более наглядно: https://wandbox.org/permlink/leFOckYIUM7wTYRV
У вас функции laplace обращаются напрямую, что не правильно.

Добавлено через 4 минуты
Ну и плюсом переименуйте сами массивы, например как у меня и не обращайтесь к ним, тогда сразу увидите ошибки.
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
13.12.2020, 19:03  [ТС]
zayats80888, Cделал по другому, вместо свапа указателей if(bool) {код1} else {код2} ветвление кода и переключение на каждой итерации тоже что и с указателями рисует ерунду... видимо тут хитрый свап очень нужен))). Не понимаю зачем... оставлю пока эту загадку.
Странно с указателями вроде как намного быстрей едет хоть и рисует бред.
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
13.12.2020, 19:35
Цитата Сообщение от Excalibur921 Посмотреть сообщение
видимо тут хитрый свап очень нужен
попробуй такой свап
//с массивами
C++
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
27
28
29
#include <iostream>
 
template <typename T>
void swap1 (T *a, T *b)
{
    T temp_a = *a;
    *a = *b;
    *b = temp_a;
}
 
int main(int argc, char ** argv)
{
    const int size = 5;
    int a[size] = { 1, 2, 3, 4, 5 };
    int b[size] = { 5, 4, 3, 2, 1 };
 
    int *pa = a, *pb = b;
 
    swap1(&pa, &pb);
 
    for (int i = 0; i < size; ++i)
        std::cout << pa[i] << ' ';
    std::cout << std::endl;
    for (int i = 0; i < size; ++i)
        std::cout << pb[i] << ' ';
 
 
    return 0;
}
//без массивов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
template <typename T>
void swap1 (T *a, T *b)
{
    T temp_a = *a;
    *a = *b;
    *b = temp_a;
}
 
int main(int argc, char ** argv)
{
    int a(5), b(6);
    int *pa = &a;
    int *pb = &b;
 
    cout << *pa << " " << *pb << endl;
        swap1 (&pa, &pb);
        cout << *pa << " " << *pb << endl;
 
    return 0;
}
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
13.12.2020, 20:59
Цитата Сообщение от Excalibur921 Посмотреть сообщение
видимо тут хитрый свап очень нужен)))
Просто ошибка в логике где-то.
Ваш код из поста №18. Просто вставил указатели. Убрал "дикую дичь" с рекурсией и сделал нормальную логику glut. Рисует то-же самое, только теперь на события мыши реагирует и не зависает. Основные изменения пометил восклицательными знаками.
Кликните здесь для просмотра всего текста
C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <gl/glut.h>
#include <iostream> 
using namespace std;
#include <stdlib.h>
#include <math.h>
#include <iomanip>
 
const int imSiz=300; // размер картинки
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
typedef float(ArrType)[imSiz+2][imSiz+2][2];
ArrType arr1; 
ArrType arr2; 
 
ArrType *gridPtr = &arr1,   // указатель на основной массив
        *nextPtr = &arr2;   // указатель на буферный массив
 
void swap()
{   // свапаем указатели
    ArrType *temp = gridPtr;
    gridPtr = nextPtr;
    nextPtr = temp;
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
float ColorArr[imSiz+2][imSiz+2][3]; //  массив для окраса
 
bool render_complete = 0;
 
float dA = 1.0;
float dB = 0.5;
float k = 0.062f;
float feed = 0.055f;
 
int counter;
int FramesPass=50;
 
float constrain(float x,float a,float b)
{
    if(x<a){return a;}
    if(x>b){return b;}
    return x;
}
 
float laplaceA(int x,int y) {
  ArrType &grid = *gridPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  
  float sumA = 0;
  sumA += grid[x][y][0] * -1;
  sumA += grid[x - 1][y][0] * 0.2f;
  sumA += grid[x + 1][y][0] * 0.2f;
  sumA += grid[x][y + 1][0] * 0.2f;
  sumA += grid[x][y - 1][0] * 0.2f;
  sumA += grid[x - 1][y - 1][0] * 0.05f;
  sumA += grid[x + 1][y - 1][0] * 0.05f;
  sumA += grid[x + 1][y + 1][0] * 0.05f;
  sumA += grid[x - 1][y + 1][0] * 0.05f;
  return sumA;
}
 
float laplaceB(int x, int y) {
  ArrType &grid = *gridPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
  float sumB = 0;
  sumB += grid[x][y][1] * -1.0f;
  sumB += grid[x - 1][y][1] * 0.2f;
  sumB += grid[x + 1][y][1] * 0.2f;
  sumB += grid[x][y + 1][1] * 0.2f;
  sumB += grid[x][y - 1][1] * 0.2f;
  sumB += grid[x - 1][y - 1][1] * 0.05f;
  sumB += grid[x + 1][y - 1][1] * 0.05f;
  sumB += grid[x + 1][y + 1][1] * 0.05f;
  sumB += grid[x - 1][y + 1][1] * 0.05f;
  return sumB;
}
 
 
 
 
 
//==============================================
//рисует пиксели
void drawPixelArray() 
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            glColor3f(ColorArr[x][y][0], ColorArr[x][y][1], ColorArr[x][y][2]);
            glVertex2i(x,y);
        }
    }
    glEnd();
    glutSwapBuffers(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
//рисует пиксели
//==============================================
 
 
//==============================================
//число от 0 до 1 преобразует в цвет RGB
void ColoringAlgorithm()
{
    ArrType &nextArr = *nextPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            float color=nextArr[x][y][0]-nextArr[x][y][1];
            color=constrain(color, 0.0f, 1.0f); // наверно на всякий случай тут constrain
            ColorArr[x][y][0]=0.5f+0.4f*sin(15.1f*color+1.6f);
            ColorArr[x][y][1]=0.5f+0.4f*sin(13.1f*color+0.4f);
            ColorArr[x][y][2]=0.5f+0.45f*sin(14.2f*color-1.5f);
        }
    }
}
//число от 0 до 1 преобразует в цвет RGB
//==============================================
 
//===================================================
//расчет  новой концетрации 
void NewConectration()
{
    ArrType &grid = *gridPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ArrType &nextArr = *nextPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//копирование строки и стольбцов, нужно для правильности свертки
    for(int y = 0; y < imSiz+2; y++)
    {
        grid[imSiz+1][y][0]=grid[1][y][0]; // строка 1 в строку imSiz+1
        grid[0][y][0]=grid[imSiz][y][0]; 
        grid[imSiz+1][y][1]=grid[1][y][1]; 
        grid[0][y][1]=grid[imSiz][y][1]; 
        //cout<<setw(5)<<fixed<<setprecision(1)<<grid[1][y][0];
    }
 
//копирование столбцов
    for(int x = 0; x < imSiz+2; x++)
    {
        grid[x][imSiz+1][0]=grid[x][1][0];
        grid[x][imSiz+1][1]=grid[x][1][1];
        grid[x][0][0]=grid[x][imSiz][0];
        grid[x][0][1]=grid[x][imSiz][1];
 
    }
//копирование строки и стольбцов, нужно для правильности свертки
 
//свертка ядром 3х3
    for(int x = 1; x < imSiz+1; x++)
    {
        for (int y = 1; y < imSiz+1; y++)
        {
            float a = grid[x][y][0];
            float b = grid[x][y][1];
            nextArr[x][y][0] = a + dA * laplaceA(x, y) - a * b * b + feed * (1 - a);
            nextArr[x][y][1] = b + dB * laplaceB(x, y) + a * b * b - (k + feed) * b;
            nextArr[x][y][0] = constrain(nextArr[x][y][0], 0.0f, 1.0f);
            nextArr[x][y][1] = constrain(nextArr[x][y][1], 0.0f, 1.0f);
        }
    }
 
    counter++;
    if(counter==FramesPass) // пропуск окраса N кадров,ускорение дифузии
    {
        counter=0;
        cout << "FramesPass="<<FramesPass<<endl;
        ColoringAlgorithm(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        glutPostRedisplay(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
    swap(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
 
//===================================================
//нарисовать примерно прямоугольник в центре массива веществом B
void FillRectangleArea()
{
    ArrType &grid = *gridPtr; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    for(int x = 0; x < imSiz+2; x++)
    {
        for (int y = 0; y < imSiz+2; y++)
        {
            if(x>110 && x<180 && y>110 && y<180)
            {
                grid[x][y][0]=1.0;
                grid[x][y][1]=1.0;
            }
            else
            {
                grid[x][y][0]=1.0;
                grid[x][y][1]=0.0;
            }
        }
    }
}
//нарисовать прямоугольник в центре массива веществом B
//===================================================
 
void setupGL() 
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, imSiz , imSiz, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glPointSize(1);
    FillRectangleArea();
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(imSiz, imSiz); 
    glutInitWindowPosition(500, 200);
    glutCreateWindow("Reaction Diffusion Gray-Scott model");
    glutDisplayFunc(drawPixelArray); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    glutIdleFunc(NewConectration); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    setupGL();
    glutMainLoop();
    return 0;
}
1
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
13.12.2020, 22:07  [ТС]
zayats80888, Да появился отклик на закрытие мышкой и не виснет, но субъективно считает как намного дольше и тяжелей. В общем такие расчеты не для CPU…
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
14.12.2020, 23:07
Цитата Сообщение от Excalibur921 Посмотреть сообщение
В общем такие расчеты не для CPU…
Делать было нечего, перенёс ваш код на шейдеры и рендер в текстуру.
Попробуйте запустить у себя. Там OpenGL2.1 + загрузка расширений ARB_framebuffer_object, ARB_texture_rg, ARB_texture_rectangle и ARB_texture_float. Если не запустится, покажите вывод консоли(ну и я помню вы запускали glewInfo, так вот, если не трудно, скиньте файл, который она сгенерировала, что бы посмотреть, что у вас там доступно).
Вложения
Тип файла: zip diffusion_win7x64.zip (214.4 Кб, 16 просмотров)
1
14.12.2020, 23:53

Не по теме:

zayats80888, а как вам мой вариант? мне интересно запустится ли и какой вариант производительнее, код изменился после того как здесь выкладывал
Compute Shaders.7z
сделан на вычислительных шейдерах и версии 4.6, раскраска своя, используются spir-v шейдеры

0
15.12.2020, 00:11

Не по теме:

alecss131, к сожалению она у меня крашится (вроде, модуль драйвера ATI). Если что, видеокарта у меня старая, но вулкан поддерживает. Х.З. что не так. Надо было обработку ошибок добавить.
Моя карточка.

0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
15.12.2020, 01:26  [ТС]
zayats80888, Краш.
glewinfo.txt
visualinfo.txt
1.zip

Переписал код на другой алгоритм.
Два квадратных ядра свертки и можно задавать веса компонентам ядра раздельно и
пропускать итерации без рендера
C++
1
int iterNoRender=1;//сколько итераций без рендера пропускать,
Очень простое правило: если сумма в ядре 5х5 больше суммы ядро 3х3 то прибавить малую величину K иначе отнять.
Веса компонентов взял неизвестно откуда, просто погуглил картинки и визуально вижу что симметричное ядро 5 на 5 подходит…
Пересчитывал хитрые коэффициенты множители суммы каждому ядру чтобы если все значения которые читает ядро равны 1 то и сумма после ядра равна 1.
C++
1
2
float t1=2.08f; // корректирует сумму элементов свертки к единице.
float t2=1.25f; // корректирует сумму элементов свертки к единице.
Без этого не хотят работать ядра с весами. Думал если будут веса от гладкой функции то и рисунок диффузии будет плавный как в Diffusion Gray-Scott но нет..странные кельтские рисунки…инопланетные иероглифы. Это некий клеточный автомат, простые правила формируют сложные паттерны. Все какие-то угловатые...может повернуть ядро свертки на 45 градусов…не знаю. Сколько не менял параметры все время угловатые рисунки.

Заметил странность, если не нормализовать значения после conectratCorrection() применяя conectratNormalization()
То рисует однотипные рисунки, настройки никак не влияют.
Зато после нормализации conectratNormalization()
Очень разнообразны рисунки. Мистика. Растут из одного пикселя как снежинки.



Заполняя все немыслимые уголки.
C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#include <gl/glut.h>
//#include <iostream> 
//using namespace std;
//#include <iomanip>
 
const int imSiz=300; // размер картинки
int iterNoRender=3;//сколько итераций без рендера пропускать,
                    //ускорение анимации 
 
float smallConcentration=0.7f;  
float noiseLim=0.00001f; // плотность  положения рандом точек начальной концентрации
float setConcentrationUp=1.0f; // концентрации растворов
float setConcentrationDn=0.7f; //
 
 
float con3x3w[3][3]=
{
{0.05f, 0.07f, 0.05f},
{0.07f, 0.0f,  0.07f},
{0.05f, 0.07f, 0.05f}
};
//дефалт
//{0.05f, 0.07f, 0.05f},
//{0.07f, 0.0f,  0.07f},
//{0.05f, 0.07f, 0.05f}
 
 
float con5x5w[5][5]=
{
{0.01f, 0.02f, 0.03f, 0.02f, 0.01f},
{0.02f, 0.0f,  0.0f,  0.0f,  0.02f},
{0.03f, 0.0f,  0.0f,  0.0f,  0.03f},
{0.02f, 0.0f,  0.0f,  0.0f,  0.02f},
{0.01f, 0.02f, 0.03f, 0.02f, 0.01f}
};
 
//дефалт
//{0.01f, 0.02f, 0.03f, 0.02f, 0.01f},
//{0.02f, 0.0f,  0.0f,  0.0f,  0.02f},
//{0.03f, 0.0f,  0.0f,  0.0f,  0.03f},
//{0.02f, 0.0f,  0.0f,  0.0f,  0.02f},
//{0.01f, 0.02f, 0.03f, 0.02f, 0.01f}
 
int rnd=10; //сид рандома
int counter;
 
float arr[imSiz+4][imSiz+4]={0};  // основной массив
//float arr[7][7]=
//{
//{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 1.0f, 2.0f, 3.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 4.0f, 5.0f, 6.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 7.0f, 8.0f, 9.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,},
//{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,},
//};
 
 
float buf[imSiz+4][imSiz+4]={0}; // буферный массив
short int  im2,im1,ip1,ip2,jm2,jm1,jp1,jp2;
//float arrVal,arrMin,arrMax,arrMaxMinDelta,randNoise,sum,sumAct, sumInh;;
 
 
void copyRowColumn(); //обьявление функции
bool render_complete=0;
 
 
 
//=========================================
//рисует пиксели
void drawPixelArray()
{ 
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    for(int x = 2; x<imSiz+2; x++)
    {
        for (int y = 2; y <imSiz+2; y++)
        {
            float a=arr[x][y];
            glColor3f(a, a, a);     
            glVertex2i(x,y);
        }
    }
    glEnd();
    //render_complete=1;
}
//рисует пиксели
//=========================================
 
 
 
 
//=========================================
//нормализаия концентрации в диапазон от 0 до 1
void conectratNormalization()
{
//поиск макс мин значений в массиве arr
float arrMin=100;
float arrMax=-100;
    for(int x = 2; x < imSiz+2; x++)
    {
        for (int y = 2; y <imSiz+2; y++)
        {
            float a=arr[x][y];
            if(a>arrMax)
            {
                arrMax=a;
            }
            if(a<arrMin)
            {
                arrMin=a;
            }
        }
    }
//поиск макс мин значений в массиве arr
 
 
//нормализация значений в массиве arr
float arrMaxMinDelta=arrMax-arrMin;
    for(int x = 2; x< imSiz+2; x++)
    {
        for (int y= 2; y <imSiz+2; y++)
        {
            arr[x][y]=(arr[x][y]-arrMin)/arrMaxMinDelta;
        }
    }
//нормализация значений в массиве arr
 
//пропуск iterNoRender интераций без рендера, ускорение анимации 
counter++; // подсчет кол-ва итераций
    if(counter==iterNoRender) 
    {
        drawPixelArray();
        render_complete=1;
        counter=0;
        //cout << "Render complete frames passed="<<FramesPass<<endl;
    }
    else
    {
        if(counter<iterNoRender)
        {
            copyRowColumn();
        }
    }
//пропуск iterNoRender интераций без рендера, ускорение анимации 
//drawPixelArray();
}
//нормализаия концентрации в диапазон от 0 до 1
//=========================================
 
 
 
 
 
//=========================================================
//коррекция концентрации на малую величину smallConcentration 
void conectratCorrection()
{
    for(int i = 2; i <imSiz+2; i++)
    {
        for (int j = 2; j <imSiz+2; j++)
        {
//подсчет адресов массивов заранее
 
im2=i-2;
im1=i-1;
ip1=i+1;
ip2=i+2;
 
jm2=j-2;
jm1=j-1;
jp1=j+1;
jp2=j+2;
//подсчет адресов массивов заранее
 
//средняя сумма 8 элементов вокруг текущего
//по описанию в книге малый радиус это активатор Act.
//ядро свертки 3 на 3
float t1=2.08f; // корректирует сумму элементов свертки к единице.
float sum=
(
arr[im1][jp1]*con3x3w[0][0] +arr[i][jp1]*con3x3w[0][1]  +arr[ip1][jp1]*con3x3w[0][2]
+arr[im1][j]*con3x3w[1][0]                                  +arr[ip1][j]*con3x3w[1][2]
+arr[im1][jm1]*con3x3w[2][0]    +arr[i][jm1]*con3x3w[2][1]  +arr[ip1][jm1]*con3x3w[2][2]
);
float sumAct=t1*sum;
//ядро свертки 3 на 3
 
//средняя сумма 24 элементов вокруг текущего
//по описанию в книге больший радиус это ингибитор Inh.
//ядро свертки 5 на 5
float t2=1.25f; // корректирует сумму элементов свертки к единице.
float sumInh=t2*
(sum // сумма от ядра 3 на 3
+arr[im2][jp2]*con5x5w[0][0] +arr[im1][jp2]*con5x5w[0][1]   +arr[i][jp2]*con5x5w[0][2]  +arr[ip1][jp2]*con5x5w[0][3]        +arr[ip2][jp2]*con5x5w[0][4]
+arr[im2][jp1]*con5x5w[1][0]                                                                                                    +arr[ip2][jp1]*con5x5w[1][4]
+arr[im2][j]  *con5x5w[2][0]                                                                                                    +arr[ip2][j]  *con5x5w[2][4]
+arr[im2][jm1]*con5x5w[3][0]                                                                                                    +arr[ip2][jm1]*con5x5w[3][4]
+arr[im2][jm2]*con5x5w[4][0] +arr[im1][jm2]*con5x5w[4][1]   +arr[i][jm2]*con5x5w[4][2]   +arr[ip1][jm2]*con5x5w[4][3]       +arr[ip2][jm2]*con5x5w[4][4]
);
//ядро свертки 5 на 5
 
//корекция концентрации
            if(sumAct>sumInh)
            {
                buf[i][j]=smallConcentration; 
            }
            else
            {
                buf[i][j]=-smallConcentration; 
            }
        }
    }
//корекция концентрации
 
//обновляем концентрации прибавляя buf к arr
    for(int x = 2; x < imSiz+2; x++)
    {
        for (int y = 2; y < imSiz+2; y++)
        {
                arr[x][y]+=buf[x][y];
        }
    }
//обновляем концентрации прибавляя buf к arr
 
conectratNormalization();
//drawPixelArray();
//glutSwapBuffers();
}
//коррекция концентрации на малую величину smallConcentration 
//=========================================================
 
 
 
 
//================================================
//копируем столбцы и строки для ускорения свертки и правильности свертки
void copyRowColumn() 
{
    //копируем строки
    for(int y = 2; y < imSiz+2; y++)
    {
        arr[imSiz+2][y]=arr[2][y];
        arr[imSiz+3][y]=arr[3][y];
        arr[0][y]=arr[imSiz][y];
        arr[1][y]=arr[imSiz+1][y];
    }
    //копируем строки
 
    //копирование столбцов
    for(int x = 0; x < imSiz+4; x++)
    {
        arr[x][imSiz+2]=arr[x][2];
        arr[x][imSiz+3]=arr[x][3];
        arr[x][0]=arr[x][imSiz];
        arr[x][1]=arr[x][imSiz+1];
    }
    //копирование столбцов
//drawPixelArray();
//glutSwapBuffers();
conectratCorrection();
}
//копируем столбцы и строки для ускорения свертки 
//============================================
 
 
 
 
//============================================
//стартовая генерация концентраций
void genArr()
{
srand(rnd); //число сид генератора
    //записываем всем элментам рандом кроме отступ 2 строки и столбца
    for(int i = 2; i < imSiz+2; i++)
    {
        for (int j = 2; j < imSiz+2; j++)
        {
            float rnd=(float)rand()/RAND_MAX;
            if(rnd<noiseLim)
            {
                arr[i][j]=setConcentrationUp;
            }
            else
            {
                arr[i][j]=setConcentrationDn;
            }
        //cout<<setw(5)<<fixed<<setprecision(0)<<arr[i][j];
        }
        //cout<< "\n";
    }
    //записываем всем элментам рандом кроме отступ 2 строки и столбца
copyRowColumn();
}
//стартовая генерация концентраций
//============================================
 
 
//==============================================
//таймер  проверяет готов ли рендер, если да то обновляет экран и запуск таймера
void TimerFunction(int value)
{
    if(render_complete) 
    {
        glutSwapBuffers();
        render_complete=0;
        glutTimerFunc(30, TimerFunction, 1);
        //cout << "New frame----------"<<endl;
        copyRowColumn();
    }
    else
    {
        //cout << "Frame lost!----------"<<endl;
        //glutTimerFunc(16, TimerFunction, 1);
        
    }
}
//таймер  проверяет готов ли рендер, если да то обновляет экран и запуск таймера
//==============================================
 
void setupGL() 
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, imSiz , imSiz, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glPointSize(1.0);
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(imSiz, imSiz); 
    glutInitWindowPosition(500, 200);
    glutCreateWindow("Reaction Diffusion");
    setupGL();
    genArr();
    glutTimerFunc(33, TimerFunction, 1);
    glutMainLoop();
    return 0;
}
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.12.2020, 09:07
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Краш
Формально нет. Это вынужденное завершение программы.
Все необходимые расширения у вас поддерживаются, они загрузились.
Шейдеры скомпилировались, но вот почему не линкуются - мне реально не понятно...
Ну и драйвер NVidia, как обычно, ничего полезного не сообщил
Вот отладочный вариант сборки с дополнительным выводом и проверками(ну и шейдеры чутка причесал, хотя там и так всё согласно спецификации было).
Попробуйте его, мне реально интересно, что не так с линковкой.
Вложения
Тип файла: zip diffusion_win7x64.zip (218.7 Кб, 9 просмотров)
0
15.12.2020, 11:52

Не по теме:

zayats80888, вот новая версия с дебагом, избавился от некоторых вещей, например std430 в ubo, барьер после вычислительного шейдера (так как только 1 картинка используется и для вычислений и для рисования в кадре, а куда происходит запись читается только в следующем кадре, то есть по сути одновременно и рисования и вычисления или нет?), фрагментный шейдер почти один в один ваш)
добавил вывод ошибок и отладки (только заглушил сообщения 131204 и 131185)
единственное что не понимаю как убрать баг по краям, может подскажете? все вычисления в шейдере
Compute Shaders.7z

0
15.12.2020, 12:29

Не по теме:

alecss131, тоже самое, разыменование nullptr. Это либо у меня в драйвере косяк, либо ты что-то прошляпил. Если есть возможность, скинь исходники, я сам попробую вечерком собрать.

Кликните здесь для просмотра всего текста

0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
15.12.2020, 13:53  [ТС]
zayats80888,
0
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
15.12.2020, 15:23  [ТС]
zayats80888, Может нужно тестить такие проги по возрастанию сложности пока работает?
1)открыть пустое окно.
2)закрасить 1 пиксель
3)нарисовать квадрат на экране, массив пикселей в цикле одним цветом.
4)массив пикселей с градиентным окрасом
5)анимация окраса пикселей по таймеру.
6) простеший GUI, слайдер влияет на закон окраса.
Самое простое взять 3 синусоиды и сдвигать фазу слайдером, f(x) окрас.
7)слайдер и пару кнопок сторонний GUI, NanoGUI, imgui.

Добавлено через 1 час 17 минут
Создал тему по неясностям с ядрами свертки по сетке, вот может в этом баг.
Круглое ядро свертки
А может нужно брать больше диаметр ядра который позволит лучше аппроксимировать круг…А может нужно просто брать вот эти готовые формулы и не выдумывать велик т.к. это имеет научную основу и работает с ядрами 3 на 3…
Еще кроме gray-scott есть
lotka-volterra reaction-diffusion
gierer-meinhardt reaction-diffusion
fitzhugh-nagumo reaction-diffusion
brusselator reaction-diffusion
barkley reaction-diffusion

но оставлю ка я их в покое =)).
0
Модератор
Эксперт Java
 Аватар для alecss131
2889 / 1394 / 412
Регистрация: 11.08.2017
Сообщений: 4,455
Записей в блоге: 2
15.12.2020, 16:57
Excalibur921, шейдеры это грубо говоря ручная реализация того что в старых версиях делалось драверами (или похожим)
обычно в шейдерах усложнение обычно идет так: окно - треугольник - куб - сложная модель и тд
а гуи на чистом opengl никто не пишет, вместо таймера используется бесконечный цикл с паузами или вертикальная синхронизация

Цитата Сообщение от zayats80888 Посмотреть сообщение
драйвер NVidia
когда карточка от интела...

Не по теме:

zayats80888, вот исходники, заодно приложу компилятор шейдеров (вроде никаких dll не требует, если что взял его из vulkan sdk, который стоит, но пользуюсь пока только этим ехе с батником), не буду отрицать что может где ошибка в плюсах. вернул опцию выбора в коде между бинарными и текстовыми шейдерами, ато с std430 в ubo без компиляции не работали
Compute Shaders_all.7z

0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.12.2020, 19:55
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Может нужно тестить такие проги по возрастанию сложности пока работает?
Если бы драйвер давал больше информации, было бы проще.
Ну и это не то ПО, с которым вообще стоит заморачиваться(я про GUI и прочее), там есть опции для запуска из консоли(main --help из консоли) + сами шейдеры можно редактировать, этого вполне хватает для "детских" экспериментов.
Попробуйте такой шейдер feedbackPass.frag.glsl ему подсунуть:
glSlang
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
27
28
#version 120
 
#extension GL_ARB_texture_rectangle : require
 
uniform sampler2DRect u_texture;
 
const vec2 diffus = vec2(1.0, 0.5);
const float kill = 0.0649;
const float feed = 0.0367;
 
void main()
{
    vec2 prev = texture2DRect(u_texture, gl_FragCoord.xy).rg;
    vec2 laplace = texture2DRect(u_texture, gl_FragCoord.xy + vec2(-1.0, -1.0)).rg * 0.05 +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2( 0.0, -1.0)).rg * 0.2  +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2( 1.0, -1.0)).rg * 0.05 +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2(-1.0,  0.0)).rg * 0.2  +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2( 1.0,  0.0)).rg * 0.2  +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2(-1.0,  1.0)).rg * 0.05 +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2( 0.0,  1.0)).rg * 0.2  +
                   texture2DRect(u_texture, gl_FragCoord.xy + vec2( 1.0,  1.0)).rg * 0.05 -
                   prev;
    
    vec2 reaction = vec2(prev.r * prev.g * prev.g) * vec2(-1.0, 1.0);
    vec2 feedKill = vec2(feed * (1.0 - prev.r), -prev.g * (feed + kill));
    vec2 next = prev + diffus * laplace + reaction + feedKill;
    gl_FragColor = vec4(clamp(next, 0.0, 1.0), 0.0, 1.0);
}
Не знаю, что ему не нравится.

Не по теме:

alecss131, ок, позже гляну.

1
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
15.12.2020, 20:09  [ТС]
zayats80888, Работает.

Когда читал про создание старых шейдеров то там в код вставляли мелкие команды проверяющие все значения переменных и корректную работу всех частей кода меняя цвет куска текстуры или двигая пиксель.
1
1472 / 827 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
15.12.2020, 20:38  [ТС]
А возможно добавить редактирование палитры в реальном времени вот как тут? Кстати что за GUI?
Название: ScreenShot00817.jpg
Просмотров: 105

Размер: 9.0 Кб
https://pmneila.github.io/jsexp/grayscott/
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.12.2020, 23:07
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Работает
Есть у меня догадки, почему не линковалось, но то не важно, смахивает на баг в драйвере.
Ну и как производительность в реальном времени, быстрее чем на процессоре? Для ускорения расчетов можете попробовать пропускать кадры, как вы делали. Для этого запускайте программу из консоли с опцией --skip-frames. Например, для пропуска каждой тысячи кадров: main.exe --skip-frames 1000

Цитата Сообщение от Excalibur921 Посмотреть сообщение
А возможно добавить редактирование палитры в реальном времени вот как тут?
Ну у меня на это сейчас нет времени и желания. Так то можно всё.

Не по теме:


alecss131, собрал сам, ситуация такая: с текстовыми шейдерами всё ок, а вот с бинарниками на втором шейдере (fragment.spv) в строке 170 (glLinkProgram(shaderProgram) access violation. Будет время, я изучу эту тему подробнее.



---

Не по теме:


alecss131, по поводу "рамки" на изображении, то вот так её нет:

Кликните здесь для просмотра всего текста
glSlang
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
27
28
29
30
31
32
33
34
35
36
37
38
#version 460 core
 
layout(local_size_x = 30, local_size_y = 30, local_size_z = 1) in;
 
layout(binding = 0, rg32f) uniform readonly image2D grid;
layout(binding = 1, rg32f) uniform writeonly image2D next;
layout(binding = 0, std140) uniform UniformBufferObject {
    float dA;
    float dB;
    float k;
    float feed;
    float kernel[9];
};
 
const ivec2 d[9] = {ivec2(0, 0), ivec2(-1, 0), ivec2(1, 0), ivec2(0, 1), ivec2(0, -1), ivec2(-1, -1), ivec2(1, -1), ivec2(1, 1), ivec2(-1, 1)};
 
vec2 laplace(ivec2 pos, ivec2 size) {
    vec2 s = vec2 (0.0f, 0.0f);
    for (int i = 0; i < 9; i++) {
        s += imageLoad(grid, clamp(pos + d[i], ivec2(0), size)).rg * kernel[i];
    }
    return s;
}
 
void main() {
    uint x = gl_GlobalInvocationID.x;
    uint y = gl_GlobalInvocationID.y;
    ivec2 s = imageSize(grid) - 1;
    ivec2 pos = ivec2(x, y);
    
        vec2 d = imageLoad(grid, ivec2 (x, y)).rg;
        vec2 lap = laplace(pos, s);
        float a = d.x + dA * lap.x - d.x * d.y * d.y + feed * (1 - d.x);
        a = clamp(a, 0.0f, 1.0f);
        float b = d.y + dB * lap.y + d.x * d.y * d.y - (k + feed) * d.y;
        b = clamp(b, 0.0f, 1.0f);
        imageStore(next, pos, vec4(a, b, 0.0f, 0.0f));
}

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.12.2020, 23:07
Помогаю со студенческими работами здесь

баг в коде или уязвимостьо
подскажите пожалуйста дорогие форумчане, есть ли в коде баг или уязвимость if (isset($_GET) and $admin) { ...

Непонятный баг в правильном коде
Есть ирк-бот на c#, раньше все работало нормально, но теперь стало игнорироваться условие if ((CHANNEL != &quot;#shock-world&quot;) |...

Баг в коде (статическая структура)
Задача: • Описать структуру с именем NOTE, содержащую следующие поля: • фамилия, имя; • номер телефона; • дата рождения (массив из...

Баг stm8s003 или ошибка в коде?
При написании программы под контроллер STM8S003 столкнулся с такой проблемой. Когда я работаю с одним каналом АЦП, то все работает...

Не могу найти баг в своем коде
Не работает скрипт или баг где-то? &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;utf-8&quot;&gt; &lt;script&gt; &lt;!-- function...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
[golang] Breadth-First Search
alhaos 19.05.2026
BFS (Breadth-First Search) — это базовый алгоритм обхода графа в ширину, который поуровнево исследует все связанные вершины. Он начинает с выбранной точки и проверяет всех соседей, прежде чем. . .
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru