Russian Qt Forum
Апрель 25, 2024, 10:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Struct не работает  (Прочитано 5195 раз)
ubihinon
Гость
« : Июль 15, 2016, 15:23 »

Доброго времени суток.
Нужно создать фрактал Ньютона, столкнулся с проблемой, что структура, которая хранит вершины и цвета выводит ошибку "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);
}
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #1 : Июль 15, 2016, 15:27 »

Вы пытаетесь создать массив структур на стеке, а он не так уж и велик.
Создавайте этот массив в куче и все будет нормально.
Записан
ubihinon
Гость
« Ответ #2 : Июль 15, 2016, 15:29 »

Вы пытаетесь создать массив структур на стеке, а он не так уж и велик.
Создавайте этот массив в куче и все будет нормально.
как создать массив в куче? что это значит?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Июль 15, 2016, 15:37 »

как создать массив в куче? что это значит?
Можно через new, но лучше воспользоваться одним из классов коллекций, например, QVector.
Записан
ubihinon
Гость
« Ответ #4 : Июль 15, 2016, 16:22 »

как создать массив в куче? что это значит?
Можно через new, но лучше воспользоваться одним из классов коллекций, например, QVector.
заработало, спасибо)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 22.