// 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"); }
//------------------------------------------------------------------------------ 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(); }
void GPUProgram::bind() { glEnable(unit); bindProgram(unit, glProgram); }
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"); }