Полная настройка обратной связи Transform (openGL) - PullRequest
6 голосов
/ 11 февраля 2011

GLSL 1.50, openGL 3.3.

В последнее время я пытался заставить свою обратную связь работать, но безуспешно. Я все еще получаю сообщение об ошибке после glBeginTranformFeedback () и, так как я не нашел никакого полного рабочего кода, я собрал свои знания с помощью некоторого кода, который я нашел, и документации, это должно работать хорошо, но я что-то упустил. Поэтому, если кто-нибудь получит полный код (инициализация буферов, настройка, обновление, рендеринг, чтение назад), это определенно поможет, и если вы не знаете, что происходит, вы можете взглянуть на мой код. Я исключил некоторые бенчмаркинг, обработку окон и их создание:

int main()
{
    bool fullsize = false, paused = false; 
    std::string caption = "Tester";

    GLuint dataVAO,speedUpdateVBO,dataVBO;
    std::vector<vector3f> dataW;

    // Create the main rendering window

    init(); //just some camera commands

    UniShader shader; //my shader class keeps everything together
    shader.init();
    shader.addShader("test.vert");
    shader.addShader("test.frag");
    shader.newAttributeVariable("speed");
    shader.newFeedbackVarying("sp");
    shader.linkShader();
    shader.use();

    //init some data
    dataW.push_back(vector3f(0,1,0));

    //creating VAO
    glGenVertexArrays(1,&dataVAO);
    glBindVertexArray(dataVAO);
    //creating VBO
    glGenBuffers(1,&dataVBO);
    glBindBuffer(GL_ARRAY_BUFFER,dataVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vector3f), 0, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(shader.getAttributeIndex("speed"), 3, GL_FLOAT, GL_FALSE, 0, 0);

    glGenBuffers(1, &speedUpdateVBO);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, speedUpdateVBO);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(vector3f), NULL, GL_DYNAMIC_COPY);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, speedUpdateVBO); 
    glBindVertexArray(0);


    while (App.IsOpened())
    {
            App.SetActive();
        benchP = Clock.GetElapsedTime();

        //update calls
        if(!paused)
            //update
        benchU = Clock.GetElapsedTime();

        //render calls
        glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glColor3f(0.6f,0.7f,0.7f);

    GLuint query;
    GLuint count = 0;

    glGenQueries(1, &query);

    glEnableVertexAttribArray(shader.getAttributeIndex("speed"));

    glBindVertexArray(dataVAO);

    glBindBuffer(GL_ARRAY_BUFFER,dataVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vector3f)*dataW.size(), &dataW[0], GL_DYNAMIC_DRAW);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, speedUpdateVBO);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(vector3f)*dataW.size(), NULL, GL_DYNAMIC_COPY);

    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, speedUpdateVBO); 
    glEnable(GL_RASTERIZER_DISCARD);
    glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
    printOglError(); //Until this everything OK, I think
    glBeginTransformFeedback(GL_POINTS); 
    printOglError(); //This one prints out Invalid Value

    glDrawArrays(GL_POINTS,0,dataW.size());

    glEndTransformFeedback();
    glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); 
    glDisable(GL_RASTERIZER_DISCARD);

    //retrieve updated data
    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &count); //count is 0 -> nothing happend

    glBindVertexArray(0);
    glDisableVertexAttribArray(shader.getAttributeIndex("speed"));

    glDeleteQueries(1, &query);

    App.Display();
    //some other benchmark stuff
}

шейдеры: верт

#version 150 core
in vec3 speed;

varying vec3 sp;

const float gravity_constant = 9.81f;

void main(){
    sp = speed;
    sp += vec3(0,-gravity_constant,0);
}

фраг

#version 150 core
varying vec3 sp;

void main (void)
{
    vec3 c = sp;
    gl_FragColor = vec4(c,1.0);
}

Фрагментный шейдер существует только для оптимизации GLSL. Если sp не будет использоваться, GLSL очистит его. Могут быть незначительные ошибки, поскольку я извлек это из гораздо большего кода с множеством изменений, которые тоже не работают.

Ответы [ 4 ]

4 голосов
/ 11 февраля 2011

Взгляните на OpenGL Samples Pack . Возможно, вас заинтересуют ogl-330-transform-feedback.cpp и ogl-400-transform-feedback-object.cpp. Вы можете даже проверить Январь 2011 г. Статус драйверов OpenGL , есть ли у последних драйверов какие-либо проблемы с предоставленными примерами.

Удачи.

1 голос
/ 11 февраля 2011

Даниэль Ракос имеет демонстрационную версию с исходным кодом, реализующую выборку экземпляра с использованием обратной связи преобразования в OpenGL.Это может помочь посмотреть на это:

http://rastergrid.com/blog/2010/02/instance-culling-using-geometry-shaders/

0 голосов
/ 08 сентября 2014

Я также столкнулся с подобной проблемой, что glBeginTransformFeedback сгенерировал «недопустимую операцию». После того, как я прочитал исходный код в файле "gl-440-transform-feedback.cpp" из пакета, предоставленного Orhun, я обнаружил, что добавление

glEnable(GL_RASTERIZER_DISCARD);

до glBeginTransformFeedback() вызов просто решает проблему.

Надеюсь, это поможет.

0 голосов
/ 11 февраля 2011

Возможно, вы захотите проверить Ogre 3D: http://www.ogre3d.org/forums/viewtopic.php?p=299736

Кажется, у них есть рабочая реализация обратной связи преобразования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...