Page 1 of 1

OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sat Sep 05, 2015 00:26
by Azkarell
Hi all,

in the last few days I tried to get cegui running. After some initial problems to compile cegui, I'm now able to draw my first window, at least as long as i dont use glEnableVertexAttribArray in my custom render logic. glDisableVertexAttribArray wont help. Calling one of these functions is enough that i wont see my window anymore.

Code: Select all

void bindHelper(int target, int data, int loc, int dataSize, int datatype,int stride, int offset){
   glBindBuffer(target, data);
   glVertexAttribPointer((loc), dataSize, datatype, false, stride,  (int* )offset);
   glEnableVertexAttribArrayARB((loc));
   
}


is my helper function to bind my attribute arrays. loc I'm getting via glGetAttribLocation.

after the call to glDrawElements i call glDisableVertexAttribArray so in my opinion it should work or do I miss something?
I'm sure that it's not a missing call to glBindBuffer(0), glActiveTexture(GL_TEXTURE0) or anything else GL related. The window disappears the second i call glEnableVertexAttribArray (with or without ARB).

One additional remark: I tried to use OpenGLRenderer instead of OpenGL3Renderer, but for whatever reason my linker didnt find the corresponding symbol. (I'm using visual studio 2013 prof, and compiling the Opengl lib didnt showed any errors). but i think thats unrelated but I wanted to mention it, maybe there are some compile errors or something else I'm totally unware since everything compiled just fine and not sure how this is even possible.

EDIT: remark solved. forgot/didnt set flag in cmake for openglrenderer

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sat Sep 05, 2015 00:45
by lucebac
Did you call renderer.enableExtraStateSettings?

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sat Sep 05, 2015 12:25
by Azkarell
yeah, i enabled extra states with no difference.

Some additional hints if it helps:
I'm using sfml to create a window for rendering.
injecting mouse works just fine (drag and drop works and is still recognized even after cegui-window disapears).
I'm using a dedicated rendering thread for all gl calls could this cause problems? (and im using sf::Context to generate my textures on some other threads which didnt caused me any problems and as it seems cegui works just fine as long as i dont use glEnableVertexAttribArray.)

EDIT: my rendering code

Code: Select all

void Mesh::draw(){

   
   if (is_valid && shader  ){
      int loc;
      shader->bind();
      {
         guard g(mutex);
         loc = shader->getUniformLocation("model");
         glUniformMatrix4fv(loc, 1, false, glm::value_ptr(model));
      }
      loc = shader->getAttributLocation("in_pos");
      bindHelper(GL_ARRAY_BUFFER, vBO, loc, 3, GL_FLOAT,layout.stride_vertex, layout.offset_vertex);
      if (has_color){
         loc = shader->getAttributLocation("in_col");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 4, GL_FLOAT, layout.stride_color, layout.offset_color);

      }
      if (has_tex_cords){
         loc = shader->getAttributLocation("in_tc");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 2, GL_FLOAT, layout.stride_tc, layout.offset_tc);
      }
      if (has_normals){
         loc = shader->getAttributLocation("in_normal");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 3, GL_FLOAT, layout.stride_normals, layout.offset_normals);
      }

      if (has_textures){
         for (int i = 0; i < textures.size(); ++i){
            loc = shader->getUniformLocation(textures[i].get_use());
            textures[i].bind_texture(loc, i);
         }
      }


      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBO);
      glDrawElements(GL_TRIANGLES, layout.count_indices, GL_UNSIGNED_SHORT, 0);
      glDisableVertexAttribArray(shader->getAttributLocation("in_pos"));
      if (has_color) glDisableVertexAttribArray(shader->getAttributLocation("in_col"));
      if (has_tex_cords) glDisableVertexAttribArray(shader->getAttributLocation("in_tc"));
      if(has_normals) glDisableVertexAttribArray(shader->getAttributLocation("in_normal"));
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      
      if (has_textures){
         for (auto t : textures){
            t.unbind_texture();
         }
      }
      shader->unbind();
      return;
   }

}


EDIT2: some more code initializing cegui part1 called shortly after start of program:

Code: Select all

   CEGUI::OpenGL3Renderer::bootstrapSystem();
   CEGUI::OpenGL3Renderer* renderer = static_cast<CEGUI::OpenGL3Renderer*>( CEGUI::System::getSingleton().getRenderer());
   renderer->enableExtraStateSettings(true);
   CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());

   rp->setResourceGroupDirectory("imagesets", "./data/cegui/imagesets/");
   rp->setResourceGroupDirectory("animations", "./data/cegui/animations/");
   rp->setResourceGroupDirectory("layouts", "./data/cegui/layouts/");
   rp->setResourceGroupDirectory("looknfeel", "./data/cegui/looknfeel/");
   rp->setResourceGroupDirectory("schemes", "./data/cegui/schemes");
   rp->setResourceGroupDirectory("fonts", "./data/cegui/fonts");
   rp->setResourceGroupDirectory("xml_schemes", "./data/cegui/xml_schemes");



   CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
   CEGUI::Font::setDefaultResourceGroup("fonts");
   CEGUI::Scheme::setDefaultResourceGroup("schemes");
   CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeel");
   CEGUI::WindowManager::setDefaultResourceGroup("layouts");
   CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
   CEGUI::SchemeManager::getSingleton().createFromFile("TaharezLook.scheme","schemes");
   CEGUI::SchemeManager::getSingleton().createFromFile("Generic.scheme");
   if (!CEGUI::FontManager::getSingleton().isDefined("DejaVuSans-12")){
      CEGUI::FontManager::getSingleton().createFromFile( "DejaVuSans-12.font");
   }
   CEGUI::System::getSingleton().getDefaultGUIContext().setDefaultFont("DejaVuSans-12");


part2: called at start of rendering thread

Code: Select all

   CEGUI::WindowManager& wmg = CEGUI::WindowManager::getSingleton();
   cegui_my_rootwindow = wmg.createWindow("DefaultWindow", "root");
   cegui_my_rootwindow->setMousePassThroughEnabled(true);
   CEGUI::GUIContext guicontext = CEGUI::System::getSingleton().getDefaultGUIContext();
   cegui_my_rootwindow->setAlpha(1.0f);
   CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(cegui_my_rootwindow);
   CEGUI::FrameWindow* fWnd = static_cast<CEGUI::FrameWindow*>(wmg.createWindow("TaharezLook/FrameWindow", "testWindow"));
   
   cegui_my_rootwindow->addChild(fWnd);
   // position a quarter of the way in from the top-left of parent.
   fWnd->setPosition(CEGUI::UVector2(CEGUI::UDim(0.25f, 0.0f), CEGUI::UDim(0.25f, 0.0f)));
   
   // set size to be half the size of the parent
   fWnd->setSize(CEGUI::USize(CEGUI::UDim(0.5f, 0.0f), CEGUI::UDim(0.5f, 0.0f)));
   fWnd->setText("Hello World!");

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 12:31
by YaronCT
It seems from my experiments that calling "glEnableVertexAttribArray" does break CEGUI, however "glDisableVertexAttribArray" seems to fix it.

Is the CEGUI rendering done in the same thread of the rest (your own's) rendering?

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 15:01
by Azkarell
yes, i'll render everything from the same thread.

after i serialized everything to one thread(texture/mesh loading + rendering). the call to cegui renderALLGUIcontext now crashes my nvoglnv64.dll.
if i dont call cegui::renderall everything works fine.

i'll try another driver an maybe it works then.

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 15:16
by YaronCT
Can u try doing:

Code: Select all

for (int i=0; i<500; ++i)
    glDisableVertexAttribArray(i);


just B4 calling "renderAllGUIContexts", just to c wether it helps?

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 15:25
by Azkarell
after enabling debugging for ogl. Ill get following message as soon as I enable (uncomment) CEGUI::System::renderAllGUIcontext:

GL_INVALID_OPERATION error generated. VAO names must be generated with glGenVertexArrays before they can be bound or used. before my nvoglnv64.dll crashes.

but im trying your suggestion too.

EDIT: your suggestion didnt help, only that i get index out of bound exceptions untill gl_invalid_operation and driver crash.

EDIT2:
So after some modification for some reason it now works multithreaded but not singlethreaded (GL_INVALID_OPERATION) :D.

Code: Select all

void Mesh::draw()
   if (is_valid && shader  ){
      int loc;
      shader->bind();
      
      glBindVertexArray(vA0);
      {
         guard g(mutex);
         loc = shader->getUniformLocation("model");
         glUniformMatrix4fv(loc, 1, false, glm::value_ptr(model));
         
         
      }
      loc = shader->getAttributLocation("in_pos");
      bindHelper(GL_ARRAY_BUFFER, vBO, loc, 3, GL_FLOAT,layout.stride_vertex, layout.offset_vertex);
      if (has_color){
         loc = shader->getAttributLocation("in_col");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 4, GL_FLOAT, layout.stride_color, layout.offset_color);

      }
      if (has_tex_cords){
         loc = shader->getAttributLocation("in_tc");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 2, GL_FLOAT, layout.stride_tc, layout.offset_tc);
      }
      if (has_normals){
         loc = shader->getAttributLocation("in_normal");
         bindHelper(GL_ARRAY_BUFFER, vBO, loc, 3, GL_FLOAT, layout.stride_normals, layout.offset_normals);
      }

      if (has_textures){
         for (int i = 0; i < textures.size(); ++i){
            loc = shader->getUniformLocation(textures[i].get_use());
            textures[i].bind_texture(loc, i);
         }
      }
      
      
      
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBO);
   
      glDrawElements(GL_TRIANGLES, layout.count_indices, GL_UNSIGNED_SHORT, 0);
      
   /*   glDisableVertexAttribArray(shader->getAttributLocation("in_pos"));
      if (has_color) {
         glDisableVertexAttribArray(shader->getAttributLocation("in_col"));
         
      }
      if (has_tex_cords){
         glDisableVertexAttribArray(shader->getAttributLocation("in_tc"));
      
      }
      if (has_normals) {
         glDisableVertexAttribArray(shader->getAttributLocation("in_normal"));
      
      }*/
      /*glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ARRAY_BUFFER, 0);
   */
      
      if (has_textures){
         for (auto t : textures){
            t.unbind_texture();
         
         }
      }
      shader->unbind();
   


i added a vAO but i think there are still some problems. because I need to call bindHelper each frame, and in my understanding vAO shouldnt need that. (and yes i dont call glDisableVertexAttribArray).

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 16:16
by Ident
OpenGL is a state machine. The vao doesn't remember the shader or any other non-vertex related settings. Read the Opengl Specification, it is the best source for these kind of things. Just in case you assumed the vao will change the shader accordingly.


VAOs are indeed the way to go here, VBO's are annoying to use if you render many different buffers maybe even with different shaders and layout.

Or just use the good old OpenGLRenderer, which might be better suited if you dont wanna used vaos for whatever insane reason :hammer:

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 16:29
by Azkarell
according to valve (https://youtu.be/btNVfUygvio) vao are slow.
although im not sure if this still upholds. so i didnt want to use them, i just tried them to see if it fixes my problem with cegui. (without cegui everything works just fine ).
and accroding to http://ogldev.atspace.co.uk/www/tutoria ... ial32.html
i dont need to call glEnableVertexAttribArray and glVertexAttribPointer each frame just one call to glBindVertexArray(), but i guess that I'll do something wrong in initializing them.

Re: OpenGl3Renderer and glEnableVertexAttribArray problems.

Posted: Sun Sep 06, 2015 16:46
by Ident
Azkarell wrote:according to valve (https://youtu.be/btNVfUygvio) vao are slow.
although im not sure if this still upholds. so i didnt want to use them, i just tried them to see if it fixes my problem with cegui. (without cegui everything works just fine ).

Did you detect this as your bottleneck in your rendering code? Are you making an AAA game with next gen graphic technology where every nanosecond matters? I really doubt it. You can of course use vbos if you think this is important in your case and CEGUi should work fine with it.

In either case you might wanna try the OpenGLRenderer (without 3) if you wanna go the non-vao route.