Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 19 of 19

Thread: Fastest way of moving and drawing VBOs

  1. #11

  2. #12
    Junior Member Newbie
    Join Date
    Jul 2008
    Posts
    16
    No WebGL, I don't like "ES". I made a c++ extension for nodejs. It allows me to use opengl 4.3 and compatibility context or core so getting off the ground is quick.

    A whole mess of calls, see below a simple snippet. The javascript calls OpenGL::vertexAttrib4Ii, which queues an APC in the gui thread calling APC_vertexAttrib4Ii, that executes it. Calling c++ from javascript is super super slow. So calling vertexAttrib4Ii in immediate mode, a bunch of times was crawling, >500ms per frame. When I used a display list, back to super fast, but not dynamic. Using glMulti*Indirect it was back to super fast, so I think it is the right direction for me.

    VOID CALLBACK OpenGL::APC_vertexAttrib4Ii(__in ULONG_PTR dwParam){
    PParam8 params = (PParam8)dwParam;
    PSLIST_ENTRY entry = (PSLIST_ENTRY)dwParam;
    params->obj->glVertexAttribI4iv(params->i32args[0], &params->i32args[1]);
    glGetErrorFileLine(params->obj->tryError(TEXT("glVertexAttribI4iv")));
    freeParam8(params);
    }


    Handle<Value> OpenGL::vertexAttrib4Ii(const Arguments& args) {
    HandleScope scope;
    if(args.Length() < 5){
    return scope.Close(Undefined());
    }
    OpenGL *obj = OpenGL::Unwrap<OpenGL>(args.This());
    PParam8 params = getParam8();
    params->obj = OpenGL::Unwrap<OpenGL>(args.This());
    params->i32args[0] = argnint(args, 0);
    params->i32args[1] = argnint(args, 1);
    params->i32args[2] = argnint(args, 2);
    params->i32args[3] = argnint(args, 3);
    params->i32args[4] = argnint(args, 4);
    DWORD success = QueueUserAPC(APC_vertexAttrib4Ii, obj->threadHandle, (ULONG_PTR)params);
    if(!success){
    DWORD err = GetLastError();
    OutputDebugString(TEXT("vertexAttrib4Ni" L" error\n"));
    }
    return scope.Close(Undefined());
    }

  3. #13
    Junior Member Newbie
    Join Date
    Jul 2008
    Posts
    16
    If you are a nodejs junky, I might pass it your way if you are interested.

  4. #14
    Junior Member Newbie
    Join Date
    Jul 2008
    Posts
    16
    Through lots of magical macro work, see below, the calls define, and instantiate both calls and the apc and everything. The code above is part of what one line gets expanded to.

    glGen(genBuffer, params->obj->glGenBuffers);
    glGen(genFramebuffer, params->obj->glGenFramebuffers);
    glGen(genProgramPipeline, params->obj->glGenProgramPipelines);
    glGen(genQuery, params->obj->glGenQueries);
    glGen(genRenderbuffer, params->obj->glGenRenderbuffers);
    glGen(genSampler, params->obj->glGenSamplers);
    glGen(genTexture, glGenTextures);
    glGen(genTransformFeedback, params->obj->glGenTransformFeedbacks);
    glGen(genVertexArray, params->obj->glGenVertexArrays);
    glMethod0(end, glEnd);
    glMethod0(loadIdentity, glLoadIdentity);
    glMethod0(endList, glEndList);
    glMethod_u(activeTexture, params->obj->glActiveTexture);
    glMethod_u(clear, glClear);
    glMethod_u(enableClientState, glEnableClientState);
    glMethod_u(enable, glEnable);
    glMethod_u(frontFace, glFrontFace);
    glMethod_u(cullFace, glCullFace);
    glMethod_u(disable, glDisable);
    glMethod_u(begin, glBegin);
    glMethod_u(generateMipmap, params->obj->glGenerateMipmap);
    glMethod_u(callList, glCallList);
    glMethod_eo(bindTexture, glBindTexture);
    glMethod_eo(bindTransformFeedback, params->obj->glBindTransformFeedback);
    glMethod_eo(bindBuffer, params->obj->glBindBuffer);
    glMethod_eo(bindFramebuffer, params->obj->glBindFramebuffer);
    glMethod_eo(bindRenderbuffer, params->obj->glBindRenderbuffer);
    glMethod_eo(bindSampler, params->obj->glBindSampler);
    glMethod_eo(beginQuery, params->obj->glBeginQuery);
    glMethod_e(endQuery, params->obj->glEndQuery);
    glMethod_uu(hint, glHint);
    glMethod_uu(newList, glNewList);
    glMethod_uuu(texParameteri, glTexParameteri);
    glMethod_f(clearDepth, glClearDepth);
    glMethod_ff(depthRange, glDepthRange);
    glMethod_fff(scale, glScalef);
    glMethod_ffff(clearColor, glClearColor);
    glMethod_ffff(texCoord4f, glTexCoord4f);
    glMethod_ffff(vertex4f, glVertex4f);
    glMethod_ffff(color4f, glColor4f);
    glMethod_uuuu(color4ub, glColor4ub);
    glMethod_iiii(vertex4i, glVertex4i);
    glMethod_ffff(rotate, glRotatef);
    glMethod_uuuuu(texStorage2D, params->obj->glTexStorage2D);
    glMethod_uuuuuu(texStorage3D, params->obj->glTexStorage3D);

  5. #15
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    23
    glMapBuffer, how I mock thee!

    Anyway, I am now playing with glMapBuffer, drawing 75,000 quads with 30 FPS and glMapBuffer-ing all of those vertices every frame. Quite a nice performance, though I have to ask:

    When creating a GUI, should I scratch the buffer as I do now and reconstruct all of the vertices every frame, even if only a handful of gui elements change? At first it seems wasteful, but I wouldn't have to keep any state of the vertices, I could just fill the buffer as I go along.
    Or should I instead map the buffer, write only the changes that occur in that frame at once?
    Or throw away glMapBuffer and use glBufferSubData? I've read the PDF, so I know that glMapBuffer should be the winner, but I've read this - http://www.stevestreeting.com/2007/0...w-i-mock-thee/ and it made me a little bit suspicious.

  6. #16
    Junior Member Newbie
    Join Date
    Jul 2008
    Posts
    16
    I read that link, the replies at the bottom indicate that writer wasn't orphaning the buffers before mapping them. This causes the mapping process to read back from the gpu the buffer and bring it to the cpu. Orphaning is glBufferData with null for data pointer, it lets the GL know the buffer is no longer needed. After orphaning, the glMapBuffer command maps a new buffer causing no readback, and is much faster. That assumes the GL driver doesn't get badly confused by the whole process. Orphaning is how the article I posted gets the good numbers with glMapBuffer.

  7. #17
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    23
    They indicate no such thing. In the writer's own words: Yep, that's what they say, but it doesn't work. I went through all the papers and tips articles I could find and tried all combinations of glBufferData with NULL pointers, all the access modes. Nada.

    That's what has got me worried. I will of course test all of this on my own, I just wanted something of a last-minute reassurance that glMapBuffer is a good way to update a lot of disconnected parts of a buffer, which it seems to be.

    Anyway, your PDF was very helpful, I appreciate it.

  8. #18
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,714
    They indicate no such thing. In the writer's own words: Yep, that's what they say, but it doesn't work. I went through all the papers and tips articles I could find and tried all combinations of glBufferData with NULL pointers, all the access modes. Nada.
    Did you read the very next page? http://www.stevestreeting.com/2007/0...ta-the-return/

    Also, this is from like five years ago. I wouldn't trust any OpenGL performance information that old.

  9. #19
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    23
    I haven't, I stand corrected. And I didn't trust it, that's why I asked here.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •