2011-02-11 10 views
6

GLSL 1.50, openGL 3.3.Configuración completa de Transform Feedback (openGL)

Últimamente trato de que mi retroalimentación de tranform funcione, pero sin éxito. Todavía recibo un error después de glBeginTranformFeedback() y como no he encontrado ningún código de trabajo completo, he acumulado mi conocimiento con algún código que encontré y documentación, pero debería estar funcionando bien pero me falta algo. Por lo tanto, si alguien obtiene el código completo (inicialización de almacenamientos intermedios, configuración, actualización, representación, lectura de nuevo), la ayuda sería definitiva y, si no sabe qué ocurre, podría consultar mi código. Excluí alguna evaluación comparativa, el manejo de las ventanas y de la creación:

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 
} 

shaders: vert

#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); 
} 

frag

#version 150 core 
varying vec3 sp; 

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

Fragmento de sombreado está allí sólo para Optimización GLSL. Si sp no se utilizara, GLSL lo aclararía. Puede haber algunos errores menores ya que extraje esto de un código mucho más grande con múltiples variaciones que también falla.

+0

¿Se puede publicar la implementación de la clase shader? Además, díganos en qué plataforma se está ejecutando y cuál es la versión del controlador. – kvark

+0

¿Puedo pedirle que repita el experimento, pero sin sombreador de fragmentos adjunto al programa (solo el vértice uno)? No se preocupe porque el compilador GLSL optimice el valor 'sp', no lo será (tengo toneladas de sombreadores TF sin ningún componente FP adjunto). – kvark

+0

Bueno, creo que realmente puedo tomarlo desde ese punto, ya que el paquete de muestra lo tiene todo simple y fácil. Pero no puedo pedir más de lo que alguien me está ayudando, así que la clase de sombreado estará en edición, estoy ejecutando en Windows 7, ATI Radeon 3870HD. Catalyst Control Center 10.6 con OpenGL versión 6.14.10.9901 (algo alrededor de 3.3). Borrar el sombreador de fragmentos a "void main() {}" da el mismo error. Si se excluye el sombreado de la carga, se obtiene el mismo error. – Raven

Respuesta

4

Eche un vistazo a OpenGL Samples Pack. Puede interesarle ogl-330-transform-feedback.cpp y ogl-400-transform-feedback-object.cpp. Incluso puede verificar January 2011 OpenGL drivers status si los controladores más recientes tienen problemas con los ejemplos proporcionados.

Buena suerte.

+0

Parece que estas muestras finalmente podrían guiarme desde la oscuridad: D Sí, son perfectas justo lo que necesito. Tendré que reconstruir mi aplicación un poco, así que espero que finalmente funcione. Me di cuenta de que están vinculante mismo objeto búfer como vertexArray y feedbackBuffer .. y desde ese punto se debe especificar punteros .. eso es que debe ser – Raven

0

Es posible que desee echa un vistazo a Ogre 3D: http://www.ogre3d.org/forums/viewtopic.php?p=299736

Parece que tienen una implementación funcional de transformar la retroalimentación.

+1

uhm será como buscar una aguja en la pila, pero hasta que alguien publique algo mejor intentaré atravesarlo. Creo que sé por dónde empezar, pero ogro es un gran motor y podría haber algunas inicializaciones ocultas en otro código. ¡Gracias por la respuesta rápida! :) – Raven

+0

Ok cavó en él y encontró algo. Cambié el orden de las llamadas, pero todavía da error en glBeginTranformFeedback así como en glEndTransformFeedback. La primera diferencia aparte de que están usando su gran interfaz es que todavía están usando la extensión NV, pero estoy ejecutando en ATI y están usando matrices intercaladas, pero necesito separarlas. No debería escribir esos errores de todos modos por lo que algo está mal. – Raven

1

Daniel Rakos tiene una demostración con código fuente, implementando el descarte de instancias utilizando la conversión de comentarios en OpenGL. Podría ayudar a mirarlo:

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

+0

1. buen programa, ahora sé que mi problema no está relacionado con el controlador/tarjeta y hay un código fuente también .. Mhmm sabrosa .. 2. (Sólo para información) que estaba funcionando a 6-7 marcos, yo en 70-210 .. lol y es sólo una diferencia serie: D – Raven

0

También he experimentado un problema similar que genera glBeginTransformFeedback "operación no válida". Después de leer el código fuente en el archivo "GL-440-transform-feedback.cpp" del paquete proporcionado por Orhun, he encontrado que la adición de

glEnable(GL_RASTERIZER_DISCARD); 

antes glBeginTransformFeedback() llamada solo resuelve el problema.

Espero que esto te pueda ayudar.

+0

no tenía a utilizar eso en mi solución, pero me alegro de que ayudó. En caso de que le gustaría ver, es parte de mi biblioteca de shaders: https://github.com/BetaRavener/UniShader/blob/master/src/UniShader/ShaderOutput.cpp. Tenga en cuenta que esto fue desarrollado contra OpenGL 3.3 – Raven

Cuestiones relacionadas