// Display handles all drawing per frame. We first call the setupForDisplay 
// helper method to setup some uninteresting GL state and then bind the mesh
// using the buffers provided by our OSD objects
//
void
display() 
{
    setupForDisplay(g_width, g_height, g_size, g_center);

    //
    // Bind the GL vertex and index buffers
    //
    glBindBuffer(GL_ARRAY_BUFFER, g_vertexBuffer->BindVBO());

    OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_drawContext->patchArrays;
    for (int i=0; i<(int)patches.size(); ++i) {
        OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];

        //
        // Bind the solid shaded program and draw elements based on the buffer contents
        //
        bindProgram(g_quadFillProgram);

        glDrawElements(GL_LINES_ADJACENCY, patch.GetNumIndices(),
                       GL_UNSIGNED_INT, NULL);

        //
        // Draw the wire frame over the solid shaded mesh
        //
        bindProgram(g_quadLineProgram);
        glUniform4f(glGetUniformLocation(g_quadLineProgram, "fragColor"), 
                    0, 0, 0.5, 1);
        glDrawElements(GL_LINES_ADJACENCY, patch.GetNumIndices(),
                       GL_UNSIGNED_INT, NULL);
    }

    //
    // This isn't strictly necessary, but unbind the GL state
    //
    glUseProgram(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    //glDisableClientState(GL_VERTEX_ARRAY);

    //
    // Draw the HUD/status text
    //
    //glColor3f(1, 1, 1);
    drawString(10, 10, "LEVEL = %d", g_level);
    drawString(10, 30, "# of Vertices = %d", g_farmesh->GetNumVertices());
    drawString(10, 50, "KERNEL = CPU");
    drawString(10, 70, "SUBDIVISION = %s", "CATMARK");

    //
    // Finish the current frame
    //
    glFinish();
}
// Display handles all drawing per frame. We first call the setupForDisplay 
// helper method to setup some uninteresting GL state and then bind the mesh
// using the buffers provided by our OSD objects
//
void
display() 
{
    setupForDisplay(g_width, g_height, g_size, g_center);

    //
    // Bind the GL vertex and index buffers
    //
    glBindBuffer(GL_ARRAY_BUFFER, g_vertexBuffer->GetGpuBuffer());

    //
    // Bind the solid shaded program and draw elements based on the buffer contents
    //
    bindProgram(g_quadFillProgram);
    glDrawElements(GL_LINES_ADJACENCY, g_elementArrayBuffer->GetNumIndices(),
                    GL_UNSIGNED_INT, NULL);

    //
    // Draw the wire frame over the solid shaded mesh
    //
    bindProgram(g_quadLineProgram);
    glUniform4f(glGetUniformLocation(g_quadLineProgram, "fragColor"), 
                       0, 0, 0.5, 1);
    glDrawElements(GL_LINES_ADJACENCY, g_elementArrayBuffer->GetNumIndices(),
                    GL_UNSIGNED_INT, NULL);

    //
    // This isn't strictly necessary, but unbind the GL state
    //
    glUseProgram(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    //glDisableClientState(GL_VERTEX_ARRAY);

    //
    // Draw the HUD/status text
    //
    //glColor3f(1, 1, 1);
    drawString(10, 10, "LEVEL = %d", g_level);
    drawString(10, 30, "# of Vertices = %d", g_osdmesh->GetFarMesh()->GetNumVertices());
    drawString(10, 50, "KERNEL = CPU");
    drawString(10, 70, "SUBDIVISION = %s", "CATMARK");

    //
    // Finish the current frame
    //
    glFinish();
}
    void ShaderState::bind() {
        bindShader();
        bindVertexShader();
        bindFragmentShader();
        bindProgram();

        typedef ShaderState C;
        class_<C, ShaderStatePtr, bases<State>, boost::noncopyable>
            ("ShaderState", no_init)
            .def(init< optional<ProgramPtr> >())
            .def("isSupported", &C::isSupported)
            .staticmethod("isSupported")
            .def("setUniform4f", &C::setUniform4f)
            ;

        implicitly_convertible<ShaderStatePtr, StatePtr>();
    }
void
OpenSubdivPtexShader::draw(const MHWRender::MDrawContext &mDrawContext,
                           OsdPtexMeshData *data)
{
    MStatus status;

    glPushAttrib(GL_POLYGON_BIT|GL_ENABLE_BIT);

    // in ptexviewer, cull back face even in wireframe mode (for performance)
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    if (_wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    } else {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    CHECK_GL_ERROR("draw begin\n");

    // If shader source attribute has changed, update effectRegistry
    updateRegistry();

    GLuint bPosition = data->bindPositionVBO();
    GLuint bNormal = data->bindNormalVBO();
    OpenSubdiv::OsdGLDrawContext *osdDrawContext = data->getDrawContext();

    glBindBuffer(GL_ARRAY_BUFFER, bPosition);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
    glEnableVertexAttribArray(0);

    if (not _adaptive) {
        glBindBuffer(GL_ARRAY_BUFFER, bNormal);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
        glEnableVertexAttribArray(1);
    }

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->patchIndexBuffer);

    OpenSubdiv::OsdPatchArrayVector const & patches =
        osdDrawContext->patchArrays;

    for (size_t i = 0; i < patches.size(); ++i) {
        OpenSubdiv::OsdPatchArray const & patch = patches[i];

        GLint surfaceProgram = bindProgram(mDrawContext, osdDrawContext, patch);

        if (patch.desc.type != OpenSubdiv::kNonPatch) {
            glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());

            if (osdDrawContext->GetVertexTextureBuffer()) {
                glActiveTexture(GL_TEXTURE0);
                glBindTexture(GL_TEXTURE_BUFFER,
                              osdDrawContext->GetVertexTextureBuffer());
                glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, bPosition);
            }
            if (osdDrawContext->GetVertexValenceTextureBuffer()) {
                glActiveTexture(GL_TEXTURE1);
                glBindTexture(GL_TEXTURE_BUFFER,
                              osdDrawContext->GetVertexValenceTextureBuffer());
            }
            if (osdDrawContext->GetQuadOffsetsTextureBuffer()) {
                glActiveTexture(GL_TEXTURE2);
                glBindTexture(GL_TEXTURE_BUFFER,
                              osdDrawContext->GetQuadOffsetsTextureBuffer());
            }
            if (osdDrawContext->GetPatchParamTextureBuffer()) {
                glActiveTexture(GL_TEXTURE3);
                glBindTexture(GL_TEXTURE_BUFFER,
                              osdDrawContext->GetPatchParamTextureBuffer());
            }
            glActiveTexture(GL_TEXTURE0);

            glDrawElements(GL_PATCHES,
                           patch.numIndices, GL_UNSIGNED_INT,
                           reinterpret_cast<void *>(patch.firstIndex *
                                                    sizeof(unsigned int)));
        } else {
            GLint nonAdaptiveLevel = glGetUniformLocation(surfaceProgram,
                                     "nonAdaptiveLevel");
            if (nonAdaptiveLevel != -1) {
                glProgramUniform1i(surfaceProgram, nonAdaptiveLevel, _level);
            }

            glDrawElements(_scheme == OsdPtexMeshData::kLoop ? GL_TRIANGLES : GL_LINES_ADJACENCY,
                           patch.numIndices, GL_UNSIGNED_INT,
                           reinterpret_cast<void *>(patch.firstIndex *
                                                    sizeof(unsigned int)));
        }
        CHECK_GL_ERROR("post draw\n");
    }

    glUseProgram(0);

    glDisableVertexAttribArray(0);
    if (not _adaptive)
        glDisableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glPopAttrib();

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    CHECK_GL_ERROR("draw end\n");
}
// #### Main draw method
//
//      Called by OpenSubdivShaderOverride for each renderItem.
//      Binds the vertex buffer and calls glDrawElements for 
//      each patch.
//
void
OpenSubdivShader::draw(const MHWRender::MDrawContext &mDrawContext,
                             OsdMeshData *data)
{
    glPushAttrib(GL_POLYGON_BIT|GL_ENABLE_BIT);

    if (_wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    } else {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    CHECK_GL_ERROR("draw begin\n");

    // If shader source attribute has changed, update effectRegistry
    updateRegistry();

    // Bind position vertex buffer
    GLuint bPosition = data->bindPositionVBO();
    OpenSubdiv::OsdGLDrawContext *osdDrawContext = data->getDrawContext();

    glBindBuffer(GL_ARRAY_BUFFER, bPosition);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->GetPatchIndexBuffer());

    // Get list of patches from OSD
    OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches =
        osdDrawContext->patchArrays;

    // Draw patches
    for (size_t i = 0; i < patches.size(); ++i) {
        OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];

        GLuint program = bindProgram(mDrawContext, osdDrawContext, patch);

        GLuint uniformGregoryQuadOffsetBase =
            glGetUniformLocation(program, "OsdGregoryQuadOffsetBase");
        GLuint uniformPrimitiveIdBase =
            glGetUniformLocation(program, "OsdPrimitiveIdBase");
        glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
                           patch.GetQuadOffsetIndex());
        glProgramUniform1i(program, uniformPrimitiveIdBase,
                           patch.GetPatchIndex());

        GLenum primType = GL_PATCHES;
        if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::QUADS) {
            primType = GL_LINES_ADJACENCY;
        } else if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
            primType = GL_TRIANGLES;
        } else if (patch.GetDescriptor().GetType() >= OpenSubdiv::FarPatchTables::REGULAR) {
            glPatchParameteri(GL_PATCH_VERTICES, patch.GetDescriptor().GetNumControlVertices());
        }
        glDrawElements(primType,
                       patch.GetNumIndices(), GL_UNSIGNED_INT,
                       reinterpret_cast<void *>(patch.GetVertIndex() *
                                                sizeof(unsigned int)));

        CHECK_GL_ERROR("post draw\n");
    }

    // Clear state
    glUseProgram(0);
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glPopAttrib();

    CHECK_GL_ERROR("draw end\n");
}
Exemple #6
0
//------------------------------------------------------------------------------
void
display() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(0, 0, g_width, g_height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDisable(GL_LIGHTING);
    glColor3f(1, 1, 1);
    glBegin(GL_QUADS);
    glColor3f(1, 1, 1);
    glVertex3f(-1, -1, 1);
    glVertex3f( 1, -1, 1);
    glVertex3f( 1,  1, 1);
    glVertex3f(-1,  1, 1);
    glEnd();

    double aspect = g_width/(double)g_height;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, aspect, 0.01, 500.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-g_pan[0], -g_pan[1], -g_dolly);
    glRotatef(g_rotate[1], 1, 0, 0);
    glRotatef(g_rotate[0], 0, 1, 0);
    glTranslatef(-g_center[0], -g_center[1], -g_center[2]);
    glRotatef(-90, 1, 0, 0); // z-up model

    GLuint bVertex = g_vertexBuffer->GetGpuBuffer();
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, bVertex);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (float*)12);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementArrayBuffer->GetGlBuffer());

    GLenum primType = GL_LINES_ADJACENCY;
    if (g_scheme == kLoop) {
        primType = GL_TRIANGLES;
        bindProgram(g_triFillProgram);
    } else {
        bindProgram(g_quadFillProgram);
    }

    if (g_wire > 0) {
        glDrawElements(primType, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, NULL);
    }
    
    if (g_wire == 0 || g_wire == 2) {
        GLuint lineProgram = g_scheme == kLoop ? g_triLineProgram : g_quadLineProgram;

        bindProgram(lineProgram);
        GLuint fragColor = glGetUniformLocation(lineProgram, "fragColor");
        if (g_wire == 2) {
            glProgramUniform4f(lineProgram, fragColor, 0, 0, 0.5, 1);
        } else {
            glProgramUniform4f(lineProgram, fragColor, 1, 1, 1, 1);
        }
        glDrawElements(primType, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, NULL);
    }
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    glUseProgram(0);

    if (g_drawNormals)
        drawNormals();
    
    if (g_drawCoarseMesh)
        drawCoarseMesh(g_drawCoarseMesh);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableClientState(GL_VERTEX_ARRAY);

    if (g_drawHUD) {
        glColor3f(1, 1, 1);
        drawString(10, 10, "LEVEL = %d", g_level);
        drawString(10, 30, "# of Vertices = %d", g_osdmesh->GetFarMesh()->GetNumVertices());
        drawString(10, 50, "KERNEL = %s", getKernelName(g_kernel));
        drawString(10, 70, "CPU TIME = %.3f ms", g_cpuTime);
        drawString(10, 90, "GPU TIME = %.3f ms", g_gpuTime);
        drawString(10, 110, "SUBDIVISION = %s", g_scheme==kBilinear ? "BILINEAR" : (g_scheme == kLoop ? "LOOP" : "CATMARK"));
        
        drawString(10, g_height-30, "w:   toggle wireframe");
        drawString(10, g_height-50, "e:   display normal vector");
        drawString(10, g_height-70, "m:   toggle vertex deforming");
        drawString(10, g_height-90, "h:   display control cage");
        drawString(10, g_height-110, "n/p: change model");
        drawString(10, g_height-130, "1-7: subdivision level");
        drawString(10, g_height-150, "space: freeze/unfreeze time");
    }
        
    glFinish();
    glutSwapBuffers();
}
Exemple #7
0
void GPUProgram::bind() {
    glEnable(unit);
    bindProgram(unit, glProgram);
}
Exemple #8
0
void GPUProgram::reload(const std::string& _code) {
    std::string code = _code;

    // If a syntax error occurs while loading the shader we want to break.  
    // However, it makes no sense to break in this loading code when the
    // error is really in the shader code.  To hack this under MSVC we print
    // out the error as if it were a MSVC error so double clicking will take
    // us there, then break in this code.  To reload the shader we jump back
    // to the top of the loading routine and try again.
     
    bool reloadFromFile = (code == "");

    bool ignore = false;

LOADSHADER:

    if (reloadFromFile) {
 
        if (fileExists(filename)) {
            code = readFileAsString(filename);
        } else {
            error("Critical Error", 
                std::string("Cannot locate file \"") + filename + "\" to reload it.", true);
            exit(-1);
        }
    }

    unit = getUnitFromCode(code, extension);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glEnable(unit);

    genPrograms(1, &glProgram);
    bindProgram(unit, glProgram);
    // Clear the error flag.
    glGetError();

    loadProgram(code);

    // Check for load errors
    if ((glGetError() == GL_INVALID_OPERATION) && (! ignore)) {

        int                  pos = 0;
        const unsigned char* msg = NULL;
        getProgramError(pos, msg);

        deletePrograms(1, &glProgram);

        int line = 1;
        int col  = 1;

        // Find the line and column position.
        int x = 0;
        for (x = 0, col = 1; x < pos; ++x, ++col) {
            if (code[x] == '\n') {
                ++line;
                col = 1;
            }
        }

        if (col > 1) {
            --col;
        }

        // Count forward to the end of the line
        int endCol = col;
        while ((x < (int)code.size()) && (code[x] != '\n') && (code[x] != '\r')) {
            ++x;
            ++endCol;
        }

        // Extract the line
        std::string codeLine = code.substr(pos - col + 1, endCol - col);

        // Show the line
        std::string text = format("%s (%d:%d) : %s%s%s", filename.c_str(), line, col, msg, NEWLINE, NEWLINE);
        text += codeLine + NEWLINE;
        for (int i = 0; i < col - 1; ++i) {
            text += " ";
        }

        text += "^";

        #ifdef G3D_WIN32
        {
            // Print the error message in MSVC format
            std::string fullFilename = resolveFilename(filename);
            debugPrintf("%s%s(%d) : GPU Program Error : %s%s%s",
                   NEWLINE, fullFilename.c_str(), line, msg, NEWLINE, NEWLINE);
        }
        #endif

        #ifndef _DEBUG
            Log::common()->print("\n******************************\n");
            Log::common()->print(text);
            exit(-1);
        #endif

        const char* choice[] = {"Debug", "Ignore", "Ignore All", "Exit"};

        switch (prompt("Error Loading Program", text.c_str(), choice, 4, true)) {
        case 0:
            // Debug
            {
                ////////////////////////////////////////////////////////////////////////////
                //                                                                        //
                //                              PUSH  F4                                  //
                //                                                                        // 
                //   If your program breaks on this line in debug mode under Windows,     //
                //   go to the MSVC Debug window and click on the error message (or       //
                //   just press F4 be taken to the error line in your shader.             //
                //                                                                        //
                //   When you change it and press continue, G3D will try to reload your   //
                //   shader (if it came from a file).                                     //
                //                                                                        //
                ////////////////////////////////////////////////////////////////////////////
                debugBreak();
                reloadFromFile = true;
                goto LOADSHADER;
                break;
            }

        case 1:
            // Ignore
            break;

        case 2:
            // Ignore all
            ignore = true;
            break;

        case 3:
            // Exit
            exit(-1);
        }
    }
    bindingTable.parse(code);

    glPopAttrib();
}
// #### Main draw method
//
//      Called by OpenSubdivShaderOverride for each renderItem.
//      Binds the vertex buffer and calls glDrawElements for 
//      each patch.
//
void
OpenSubdivShader::draw(const MHWRender::MDrawContext &mDrawContext,
                             OsdMeshData *data)
{
    glPushAttrib(GL_POLYGON_BIT|GL_ENABLE_BIT);

    if (_wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    } else {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    CHECK_GL_ERROR("draw begin\n");

    // If shader source attribute has changed, update effectRegistry
    updateRegistry();

    // Bind position vertex buffer
    GLuint bPosition = data->bindPositionVBO();
    OpenSubdiv::OsdGLDrawContext *osdDrawContext = data->getDrawContext();

    glBindBuffer(GL_ARRAY_BUFFER, bPosition);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->patchIndexBuffer);

    // Get list of patches from OSD
    OpenSubdiv::OsdPatchArrayVector const & patches =
        osdDrawContext->patchArrays;

    // Draw patches
    for (size_t i = 0; i < patches.size(); ++i) {
        OpenSubdiv::OsdPatchArray const & patch = patches[i];

        bindProgram(mDrawContext, osdDrawContext, patch);

        if (patch.desc.type != OpenSubdiv::kNonPatch) {
            glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());

            glDrawElements(GL_PATCHES,
                           patch.numIndices, GL_UNSIGNED_INT,
                           reinterpret_cast<void *>(patch.firstIndex *
                                                    sizeof(unsigned int)));
        } else {
            glDrawElements(_scheme == OsdMeshData::kLoop ? GL_TRIANGLES : GL_LINES_ADJACENCY,
                           patch.numIndices, GL_UNSIGNED_INT,
                           reinterpret_cast<void *>(patch.firstIndex *
                                                    sizeof(unsigned int)));
        }
        CHECK_GL_ERROR("post draw\n");
    }

    // Clear state
    glUseProgram(0);
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glPopAttrib();

    CHECK_GL_ERROR("draw end\n");
}