Доброго времени суток.
Нужно создать фрактал Ньютона, столкнулся с проблемой, что структура, которая хранит вершины и цвета выводит ошибку "segmentation fault", когда в структуре больше 300000 вершин. что нужно сделать, чтобы рисовались все вершины?
struct VertexData
{
QVector3D position;
QVector3D color;
};
NewtonFractal::NewtonFractal() :
paletteSize(128),
count(1),
indexBuf(QOpenGLBuffer::IndexBuffer)
{
initializeOpenGLFunctions();
arrayBuf.create();
indexBuf.create();
width = 812;
height = 631;
minX = -2.2f;
maxX = 0.8f;
minY = -1.5f;
maxY = 1.5;
stepX = (maxX - minX) / (GLfloat) width;
stepY = (maxY - minY) / (GLfloat) height;
// stepX = 0.01;
// stepY = 0.01;
palette = new GLfloat*[paletteSize];
black = new GLfloat[3];
black[0] = 1.0f;
black[1] = 0.3f;
black[2] = 0.3f;
createPalette();
}
NewtonFractal::~NewtonFractal()
{
arrayBuf.destroy();
indexBuf.destroy();
delete palette;
delete black;
}
std::complex<GLfloat> functions(std::complex<GLfloat>value)
{
return (pow(value,6)+pow(value,3)-(std::complex<GLfloat>)1);
}
void NewtonFractal::createPalette() {
for(int row = 0; row < paletteSize; row++)
palette[row] = new GLfloat[3];
int i;
for (i = 0; i < 32; i++) {
palette
- = (8 * i) / (GLfloat) 255;
palette[1] = (128 - 4 * i) / (GLfloat) 255;
palette[2] = (255 - 8 * i) / (GLfloat) 255;
}
for (i = 0; i < 32; i++) {
palette[32 + i][0] = (GLfloat) 1;
palette[32 + i][1] = (8 * i) / (GLfloat) 255;
palette[32 + i][2] = (GLfloat) 0;
}
for (i = 0; i < 32; i++) {
palette[64 + i][0] = (128 - 4 * i) / (GLfloat) 255;
palette[64 + i][1] = (GLfloat) 1;
palette[64 + i][2] = (8 * i) / (GLfloat) 255;
}
for (i = 0; i < 32; i++) {
palette[96 + i][0] = (GLfloat) 0;
palette[96 + i][1] = (255 - 8 * i) / (GLfloat) 255;
palette[96 + i][2] = (8 * i) / (GLfloat) 255;
}
}
GLfloat* NewtonFractal::generateNewton(GLfloat u, GLfloat v)
{
int i=0;
std::complex<GLfloat>z(u,v);
std::complex<GLfloat>dz(0,0);
std::complex<GLfloat>z0(error,error);
while(i < paletteSize) {
dz=(functions(z+(std::complex<GLfloat>)error)-functions(z))/(std::complex<GLfloat>)error;
z0=z-functions(z)/dz;
if (abs(z0-z)<error) {
return palette;
}
i++;
z=z0;
}
GLfloat black1[] = {1.0f, 0.0f, 1.0f};
return black;
}
void NewtonFractal::repaintNewton()
{
unsigned long long i = 0;
for (GLfloat y = maxY; y >= minY; y -= stepY) {
for (GLfloat x = minX; x <= maxX; x += stepX) {
i++;
}
}
count = i;
VertexData vertices[count]; // на этой строке появляется ошибка
GLushort indices[count];
i = 0;
for (GLfloat y = maxY; y >= minY; y -= stepY) {
for (GLfloat x = minX; x <= maxX; x += stepX) {
if(i < count) {
GLfloat *color = generateNewton(x, y);
vertices = {QVector3D(x, y, 0.0f), QVector3D(color[0], color[1], color[2])};
indices = i;
i++;
}
}
}
arrayBuf.bind();
arrayBuf.allocate(vertices, count * sizeof(VertexData));
indexBuf.bind();
indexBuf.allocate(indices, count * sizeof(GLushort));
}
void NewtonFractal::draw(QOpenGLShaderProgram *program)
{
// создание матрицы
QMatrix4x4 matrix;
matrix.ortho(minX, maxX, minY, maxY, ((GLfloat) -1), ((GLfloat) 1));
// привязка матрицы к переменной шейдера
program->setUniformValue("mvp_matrix", matrix);
repaintNewton();
quintptr offset = 0;
int vertexLocation = program->attributeLocation("a_position");
program->enableAttributeArray(vertexLocation);
program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
offset += sizeof(QVector3D);
int colorLocation = program->attributeLocation("a_color");
program->enableAttributeArray(colorLocation);
program->setAttributeBuffer(colorLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
}