//------------------------------------------------------------------------------ static void display() { Stopwatch s; s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); g_hud.FillBackground(); double aspect = g_width/(double)g_height; identity(g_transformData.ModelViewMatrix); translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly); rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0); rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0); rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0); translate(g_transformData.ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]); perspective(g_transformData.ProjectionMatrix, 45.0f, (float)aspect, 0.01f, 500.0f); multMatrix(g_transformData.ModelViewProjectionMatrix, g_transformData.ModelViewMatrix, g_transformData.ProjectionMatrix); glEnable(GL_DEPTH_TEST); drawStencils(); // draw the control mesh g_controlMeshDisplay.Draw(g_stencilOutput->BindSrcBuffer(), 3*sizeof(float), g_transformData.ModelViewProjectionMatrix); s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); s.Start(); glFinish(); s.Stop(); float drawGpuTime = float(s.GetElapsed() * 1000.0f); if (g_hud.IsVisible()) { g_fpsTimer.Stop(); double fps = 1.0/g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); g_hud.DrawString(10, -100, "# stencils : %d", g_nsamplesDrawn); g_hud.DrawString(10, -80, "EvalStencils : %.3f ms", g_evalTime); g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); g_hud.Flush(); } glFinish(); //checkGLErrors("display leave"); }
//------------------------------------------------------------------------------ void updateGeom() { int nverts = (int)g_orgPositions.size() / 3; std::vector<float> vertex; vertex.reserve(nverts*6); const float *p = &g_orgPositions[0]; const float *n = &g_normals[0]; float r = sin(g_frame*0.001f) * g_moveScale; for (int i = 0; i < nverts; ++i) { float move = 0.05f*cosf(p[0]*20+g_frame*0.01f); float ct = cos(p[2] * r); float st = sin(p[2] * r); g_positions[i*3+0] = p[0]*ct + p[1]*st; g_positions[i*3+1] = -p[0]*st + p[1]*ct; g_positions[i*3+2] = p[2]; p += 3; } p = &g_positions[0]; for (int i = 0; i < nverts; ++i) { vertex.push_back(p[0]); vertex.push_back(p[1]); vertex.push_back(p[2]); vertex.push_back(n[0]); vertex.push_back(n[1]); vertex.push_back(n[2]); p += 3; n += 3; } if (!g_vertexBuffer) g_vertexBuffer = g_osdmesh->InitializeVertexBuffer(6); g_vertexBuffer->UpdateData(&vertex[0], nverts); Stopwatch s; s.Start(); g_osdmesh->Subdivide(g_vertexBuffer, NULL); s.Stop(); g_cpuTime = float(s.GetElapsed() * 1000.0f); s.Start(); g_osdmesh->Synchronize(); s.Stop(); g_gpuTime = float(s.GetElapsed() * 1000.0f); glBindBuffer(GL_ARRAY_BUFFER, g_vertexBuffer->GetGpuBuffer()); glBindBuffer(GL_ARRAY_BUFFER, 0); }
static void updateGeom() { int nverts = (int)g_orgPositions.size() / 3; const float *p = &g_orgPositions[0]; float r = sin(g_frame*0.001f) * g_moveScale; g_positions.resize(nverts*3); for (int i = 0; i < nverts; ++i) { //float move = 0.05f*cosf(p[0]*20+g_frame*0.01f); float ct = cos(p[2] * r); float st = sin(p[2] * r); g_positions[i*3+0] = p[0]*ct + p[1]*st; g_positions[i*3+1] = -p[0]*st + p[1]*ct; g_positions[i*3+2] = p[2]; p+=3; } Stopwatch s; s.Start(); // update control points g_stencilOutput->UpdateData(&g_positions[0], 0, nverts); // Update random points by applying point & tangent stencils g_stencilOutput->EvalStencils(); s.Stop(); g_evalTime = float(s.GetElapsed() * 1000.0f); }
double OsdMesh::Synchronize() { Stopwatch s; s.Start(); { _dispatcher->Synchronize(); } s.Stop(); return s.GetElapsed(); }
double OsdMesh::Subdivide(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) { _dispatcher->BindVertexBuffer(vertex, varying); Stopwatch s; s.Start(); { _dispatcher->OnKernelLaunch(); _farMesh->Subdivide(_level+1, _exact); _dispatcher->OnKernelFinish(); } s.Stop(); _dispatcher->UnbindVertexBuffer(); return s.GetElapsed(); }
//------------------------------------------------------------------------------ static void display() { // set effect g_effect.displayStyle = g_displayStyle; g_effect.screenSpaceTess = (g_screenSpaceTess != 0); g_effect.displayPatchColor = (g_displayPatchColor != 0); // prepare view matrix float aspect = g_width/(float)g_height; float modelview[16], projection[16]; identity(modelview); translate(modelview, -g_pan[0], -g_pan[1], -g_dolly); rotate(modelview, g_rotate[1], 1, 0, 0); rotate(modelview, g_rotate[0], 0, 1, 0); rotate(modelview, -90, 1, 0, 0); translate(modelview, -g_center[0], -g_center[1], -g_center[2]); perspective(projection, 45.0f, aspect, 0.01f, 500.0f); g_effect.SetMatrix(modelview, projection); g_effect.SetTessLevel((float)(1 << g_tessLevel)); g_effect.SetLighting(); // ----------------------------------------------------------------------- // prepare draw items Stopwatch s; s.Start(); OpenSubdiv::OsdUtilDrawItem<MyDrawDelegate::EffectHandle, MyDrawContext>::Collection items; OpenSubdiv::OsdUtilDrawItem<MyDrawDelegate::EffectHandle, MyDrawContext>::Collection cachedDrawItems; int numModels = g_modelCount*g_modelCount; items.reserve(numModels); for (int i = 0; i < numModels; ++i) { // Here, client can pack arbitrary mesh and effect into drawItems. items.push_back(OpenSubdiv::OsdUtilDrawItem<MyDrawDelegate::EffectHandle, MyDrawContext>( g_batch, &g_effect, g_batch->GetPatchArrays(i))); } if (g_batching) { // create cached draw items OpenSubdiv::OsdUtil::OptimizeDrawItem(items, cachedDrawItems, &g_drawDelegate); } s.Stop(); float prepCpuTime = float(s.GetElapsed() * 1000.0f); // ----------------------------------------------------------------------- // draw items s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); // primitive counting glBeginQuery(GL_PRIMITIVES_GENERATED, g_queries[0]); #if defined(GL_VERSION_3_3) glBeginQuery(GL_TIME_ELAPSED, g_queries[1]); #endif g_drawDelegate.ResetNumDrawCalls(); if (g_displayStyle == kWire) glDisable(GL_CULL_FACE); if (g_batching) { OpenSubdiv::OsdUtil::DrawCollection(cachedDrawItems, &g_drawDelegate); } else { OpenSubdiv::OsdUtil::DrawCollection(items, &g_drawDelegate); } if (g_displayStyle == kWire) glEnable(GL_CULL_FACE); glEndQuery(GL_PRIMITIVES_GENERATED); #if defined(GL_VERSION_3_3) glEndQuery(GL_TIME_ELAPSED); #endif s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); // ----------------------------------------------------------------------- GLuint numPrimsGenerated = 0; GLuint timeElapsed = 0; glGetQueryObjectuiv(g_queries[0], GL_QUERY_RESULT, &numPrimsGenerated); #if defined(GL_VERSION_3_3) glGetQueryObjectuiv(g_queries[1], GL_QUERY_RESULT, &timeElapsed); #endif float drawGpuTime = timeElapsed / 1000.0f / 1000.0f; if (g_hud.IsVisible()) { g_fpsTimer.Stop(); g_totalTime += g_fpsTimer.GetElapsed(); double fps = 1.0/g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); g_hud.DrawString(10, -200, "Draw Calls : %d", g_drawDelegate.GetNumDrawCalls()); g_hud.DrawString(10, -180, "Tess level : %d", g_tessLevel); g_hud.DrawString(10, -160, "Primitives : %d", numPrimsGenerated); g_hud.DrawString(10, -120, "GPU Kernel : %.3f ms", g_gpuTime); g_hud.DrawString(10, -100, "CPU Kernel : %.3f ms", g_cpuTime); g_hud.DrawString(10, -80, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -60, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -40, "CPU Prep : %.3f ms", prepCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); g_hud.Flush(); } checkGLErrors("display leave"); glFinish(); }
static void updateGeom(bool forceAll) { float r = (float)sin(g_totalTime); for (int j = 0; j < g_modelCount * g_modelCount; ++j) { if (forceAll == false && j >= g_moveModels) break; int nverts = (int)g_positions[j].size()/3; std::vector<float> vertex, varying; vertex.reserve(nverts * 3); if (g_displayStyle == kVaryingColor) varying.reserve(nverts * 3); const float *p = &g_positions[j][0]; for (int i = 0; i < nverts; ++i) { float ct = cos(p[2] * r); float st = sin(p[2] * r); float v[4]; v[0] = p[0]*ct + p[1]*st; v[1] = -p[0]*st + p[1]*ct; v[2] = p[2]; v[3] = 1; apply(v, g_transforms[j].value); vertex.push_back(v[0]); vertex.push_back(v[1]); vertex.push_back(v[2]); if (g_displayStyle == kVaryingColor) { varying.push_back(p[2]); varying.push_back(p[1]); varying.push_back(p[0]); } p += 3; } g_batch->UpdateCoarseVertices(j, &vertex[0], nverts); if (g_displayStyle == kVaryingColor) { g_batch->UpdateCoarseVaryings(j, &varying[0], nverts); } } Stopwatch s; s.Start(); g_batch->FinalizeUpdate(); s.Stop(); g_cpuTime = float(s.GetElapsed() * 1000.0f); s.Start(); if (g_kernel == kCPU) Controller<OpenSubdiv::OsdCpuComputeController>::GetInstance()->Synchronize(); #ifdef OPENSUBDIV_HAS_OPENMP else if (g_kernel == kOPENMP) Controller<OpenSubdiv::OsdOmpComputeController>::GetInstance()->Synchronize(); #endif #ifdef OPENSUBDIV_HAS_OPENCL else if (g_kernel == kCL) Controller<OpenSubdiv::OsdCLComputeController>::GetInstance()->Synchronize(); #endif #ifdef OPENSUBDIV_HAS_CUDA else if (g_kernel == kCUDA) Controller<OpenSubdiv::OsdCudaComputeController>::GetInstance()->Synchronize(); #endif #ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK else if (g_kernel == kGLSL) Controller<OpenSubdiv::OsdGLSLTransformFeedbackComputeController>::GetInstance()->Synchronize(); #endif s.Stop(); g_gpuTime = float(s.GetElapsed() * 1000.0f); }
//------------------------------------------------------------------------------ static void display() { g_hud.GetFrameBuffer()->Bind(); Stopwatch s; s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); // prepare view matrix double aspect = g_width/(double)g_height; identity(g_transformData.ModelViewMatrix); translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly); rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0); rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0); rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0); translate(g_transformData.ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]); perspective(g_transformData.ProjectionMatrix, 45.0f, (float)aspect, 0.1f, 500.0f); multMatrix(g_transformData.ModelViewProjectionMatrix, g_transformData.ModelViewMatrix, g_transformData.ProjectionMatrix); glEnable(GL_DEPTH_TEST); s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); glBindVertexArray(0); glUseProgram(0); // primitive counting glBeginQuery(GL_PRIMITIVES_GENERATED, g_queries[0]); #if defined(GL_VERSION_3_3) glBeginQuery(GL_TIME_ELAPSED, g_queries[1]); #endif // Update and bind transform state --------------------- if (! g_transformUB) { glGenBuffers(1, &g_transformUB); glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(g_transformData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_transformData), &g_transformData); glBindBuffer(GL_UNIFORM_BUFFER, 0); // Update and bind lighting state ---------------------- struct Lighting { struct Light { float position[4]; float ambient[4]; float diffuse[4]; float specular[4]; } lightSource[2]; } lightingData = { {{ { 0.5, 0.2f, 1.0f, 0.0f }, { 0.1f, 0.1f, 0.1f, 1.0f }, { 0.7f, 0.7f, 0.7f, 1.0f }, { 0.8f, 0.8f, 0.8f, 1.0f } }, { { -0.8f, 0.4f, -1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 0.8f, 0.8f, 0.8f, 1.0f } }} }; if (! g_lightingUB) { glGenBuffers(1, &g_lightingUB); glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(lightingData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightingData), &lightingData); glBindBuffer(GL_UNIFORM_BUFFER, 0); // Draw stuff ------------------------------------------ // control cage edges & verts if (g_drawCageVertices) { g_base_glmesh.Draw(GLMesh::COMP_VERT, g_transformUB, g_lightingUB); } if (g_drawCageEdges) { g_base_glmesh.Draw(GLMesh::COMP_EDGE, g_transformUB, g_lightingUB); } // Hbr mesh if (g_HbrDrawMode!=kDRAW_NONE) { GLMesh::Component comp=GLMesh::COMP_VERT; switch (g_HbrDrawMode) { case kDRAW_VERTICES : comp=GLMesh::COMP_VERT; break; case kDRAW_WIREFRAME : comp=GLMesh::COMP_EDGE; break; case kDRAW_FACES : comp=GLMesh::COMP_FACE; break; default: assert(0); } g_hbr_glmesh.Draw(comp, g_transformUB, g_lightingUB); } // Vtr mesh if (g_VtrDrawMode!=kDRAW_NONE) { GLMesh::Component comp=GLMesh::COMP_VERT; switch (g_VtrDrawMode) { case kDRAW_VERTICES : comp=GLMesh::COMP_VERT; break; case kDRAW_WIREFRAME : comp=GLMesh::COMP_EDGE; break; case kDRAW_FACES : comp=GLMesh::COMP_FACE; break; default: assert(0); } g_vtr_glmesh.Draw(comp, g_transformUB, g_lightingUB); } assert(g_font); g_font->Draw(g_transformUB); // ----------------------------------------------------- g_hud.GetFrameBuffer()->ApplyImageShader(); GLuint numPrimsGenerated = 0; GLuint timeElapsed = 0; glGetQueryObjectuiv(g_queries[0], GL_QUERY_RESULT, &numPrimsGenerated); #if defined(GL_VERSION_3_3) glGetQueryObjectuiv(g_queries[1], GL_QUERY_RESULT, &timeElapsed); #endif float drawGpuTime = timeElapsed / 1000.0f / 1000.0f; if (g_hud.IsVisible()) { g_fpsTimer.Stop(); double fps = 1.0/g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); { // display selectde patch info static char const * patchTypes[11] = { "undefined", "points", "lines", "quads", "tris", "loop", "regular", "boundary", "corner", "gregory", "gregory-boundary" }; if (g_Adaptive and g_currentPatch) { g_hud.DrawString(g_width/2-100, 100, "Current Patch : %d/%d (%s - %d CVs)", g_currentPatch-1, g_numPatches, patchTypes[g_currentPatchDesc.GetType()], g_currentPatchDesc.GetNumControlVertices()); } } static char const * schemeNames[3] = { "BILINEAR", "CATMARK", "LOOP" }; g_hud.DrawString(10, -140, "Primitives : %d", numPrimsGenerated); g_hud.DrawString(10, -120, "Scheme : %s", schemeNames[ g_shapes[g_currentShape].scheme ]); g_hud.DrawString(10, -100, "GPU Kernel : %.3f ms", g_gpuTime); g_hud.DrawString(10, -80, "CPU Kernel : %.3f ms", g_cpuTime); g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); g_hud.Flush(); } glFinish(); //checkGLErrors("display leave"); }
//------------------------------------------------------------------------------ void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); double aspect = g_width/(double)g_height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, aspect, g_size*0.001f, g_size+g_dolly); 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]); glUseProgram(g_program); { // shader uniform setting GLint position = glGetUniformLocation(g_program, "lightSource[0].position"); GLint ambient = glGetUniformLocation(g_program, "lightSource[0].ambient"); GLint diffuse = glGetUniformLocation(g_program, "lightSource[0].diffuse"); GLint specular = glGetUniformLocation(g_program, "lightSource[0].specular"); glProgramUniform4f(g_program, position, 0, 0.2f, 1, 0); glProgramUniform4f(g_program, ambient, 0.4f, 0.4f, 0.4f, 1.0f); glProgramUniform4f(g_program, diffuse, 0.3f, 0.3f, 0.3f, 1.0f); glProgramUniform4f(g_program, specular, 0.2f, 0.2f, 0.2f, 1.0f); GLint otcMatrix = glGetUniformLocation(g_program, "objectToClipMatrix"); GLint oteMatrix = glGetUniformLocation(g_program, "objectToEyeMatrix"); GLfloat modelView[16], proj[16], mvp[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelView); glGetFloatv(GL_PROJECTION_MATRIX, proj); multMatrix(mvp, modelView, proj); glProgramUniformMatrix4fv(g_program, otcMatrix, 1, false, mvp); glProgramUniformMatrix4fv(g_program, oteMatrix, 1, false, modelView); } 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()); glPolygonMode(GL_FRONT_AND_BACK, g_wire==0 ? GL_LINE : GL_FILL); // glPatchParameteri(GL_PATCH_VERTICES, 4); // glDrawElements(GL_PATCHES, g_numIndices, GL_UNSIGNED_INT, 0); glDrawElements(GL_LINES_ADJACENCY, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, 0); glUseProgram(0); if (g_drawNormals) drawNormals(); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (g_ptexDebug) drawPtexLayout(g_ptexDebug-1); glColor3f(1, 1, 1); drawFmtString(10, 10, "LEVEL = %d", g_level); drawFmtString(10, 30, "# of Vertices = %d", g_osdmesh->GetFarMesh()->GetNumVertices()); drawFmtString(10, 50, "KERNEL = %s", getKernelName(g_kernel)); drawFmtString(10, 70, "CPU TIME = %.3f ms", g_cpuTime); drawFmtString(10, 90, "GPU TIME = %.3f ms", g_gpuTime); g_fpsTimer.Stop(); drawFmtString(10, 110, "FPS = %3.1f", 1.0/g_fpsTimer.GetElapsed()); g_fpsTimer.Start(); drawFmtString(10, 130, "SUBDIVISION = %s", g_scheme==0 ? "CATMARK" : "BILINEAR"); drawString(10, g_height-10, "a: ambient occlusion on/off"); drawString(10, g_height-30, "c: color on/off"); drawString(10, g_height-50, "d: displacement on/off"); drawString(10, g_height-70, "e: show normal vector"); drawString(10, g_height-90, "f: fit frame"); drawString(10, g_height-110, "w: toggle wireframe"); drawString(10, g_height-130, "m: toggle vertex moving"); drawString(10, g_height-150, "s: bilinear / catmark"); drawString(10, g_height-170, "1-7: subdivision level"); glFinish(); glutSwapBuffers(); }
static void updateGeom() { int nverts = (int)g_orgPositions.size() / 3; const float *p = &g_orgPositions[0]; float r = sin(g_frame*0.001f) * g_moveScale; float * positions = g_controlValues->BindCpuBuffer(); for (int i = 0; i < nverts; ++i) { //float move = 0.05f*cosf(p[0]*20+g_frame*0.01f); float ct = cos(p[2] * r); float st = sin(p[2] * r); positions[i*3+0] = p[0]*ct + p[1]*st; positions[i*3+1] = -p[0]*st + p[1]*ct; positions[i*3+2] = p[2]; p+=3; } Stopwatch s; s.Start(); float * ptr = g_stencilValues->BindCpuBuffer(); memset(ptr, 0, g_controlStencils->GetNumStencils() * 18 * sizeof(float)); // Uppdate random points by applying point & tangent stencils switch (g_kernel) { case kCPU: { g_evalCpuCtrl.UpdateValues<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDataDesc, g_stencilValues ); g_evalCpuCtrl.UpdateDerivs<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDuDesc, g_stencilValues, g_outputDvDesc, g_stencilValues ); } break; #if defined(OPENSUBDIV_HAS_OPENMP) case kOPENMP: { g_evalOmpCtrl.UpdateValues<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDataDesc, g_stencilValues ); g_evalOmpCtrl.UpdateDerivs<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDuDesc, g_stencilValues, g_outputDvDesc, g_stencilValues ); } break; #endif #if defined(OPENSUBDIV_HAS_TBB) case kTBB: { g_evalTbbCtrl.UpdateValues<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDataDesc, g_stencilValues ); g_evalTbbCtrl.UpdateDerivs<Osd::CpuVertexBuffer,Osd::CpuGLVertexBuffer>( g_evalCtx, g_controlDesc, g_controlValues, g_outputDuDesc, g_stencilValues, g_outputDvDesc, g_stencilValues ); } break; #endif default: return; } s.Stop(); g_evalTime = float(s.GetElapsed() * 1000.0f); assert(g_controlStencils); for (int i=0; i < g_controlStencils->GetNumStencils(); ++i, ptr+=18) { float * p = ptr, * utan = ptr + 3, * vtan = ptr + 9, * normal = ptr + 15; // copy P as starting point for each line memcpy( ptr + 6, p, 3*sizeof(float) ); memcpy( ptr + 12, p, 3*sizeof(float) ); normalize( utan ); normalize( vtan ); cross( normal, utan, vtan ); normalize(normal); // compute end point for each line (P + vec * scale) for (int j=0; j<3; ++j) { utan[j]= p[j] + utan[j]*SCALE_TAN; vtan[j]= p[j] + vtan[j]*SCALE_TAN; normal[j]= p[j] + normal[j]*SCALE_NORM; } } }
//------------------------------------------------------------------------------ static void display() { Stopwatch s; s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); double aspect = g_width/(double)g_height; identity(g_transformData.ModelViewMatrix); translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly); rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0); rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0); rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0); translate(g_transformData.ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]); perspective(g_transformData.ProjectionMatrix, 45.0f, (float)aspect, 0.01f, 500.0f); multMatrix(g_transformData.ModelViewProjectionMatrix, g_transformData.ModelViewMatrix, g_transformData.ProjectionMatrix); s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); s.Start(); glFinish(); s.Stop(); float drawGpuTime = float(s.GetElapsed() * 1000.0f); drawSamples(); if (g_drawCageEdges) drawCageEdges(); if (g_drawCageVertices) drawCageVertices(); if (g_hud.IsVisible()) { g_fpsTimer.Stop(); double fps = 1.0/g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); g_hud.DrawString(10, -120, "# Samples : (%d/%d)", g_nsamplesFound, g_Q->GetNumVertices()); g_hud.DrawString(10, -100, "Compute : %.3f ms", g_computeTime); g_hud.DrawString(10, -80, "Eval : %.3f ms", g_evalTime); g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); if (g_drawMode==kFACEVARYING and g_evalCtx->GetFVarData().empty()) { static char msg[21] = "No Face-Varying Data"; g_hud.DrawString(g_width/2-20/2*8, g_height/2, msg); } g_hud.Flush(); } glFinish(); checkGLErrors("display leave"); }
//------------------------------------------------------------------------------ static void updateGeom() { int nverts = (int)g_orgPositions.size() / 3; const float *p = &g_orgPositions[0]; float r = sin(g_frame*0.001f) * g_moveScale; for (int i = 0; i < nverts; ++i) { //float move = 0.05f*cosf(p[0]*20+g_frame*0.01f); float ct = cos(p[2] * r); float st = sin(p[2] * r); g_positions[i*3+0] = p[0]*ct + p[1]*st; g_positions[i*3+1] = -p[0]*st + p[1]*ct; g_positions[i*3+2] = p[2]; p+=3; } // Run Compute pass to pose the control vertices --------------------------- Stopwatch s; s.Start(); g_vertexData->UpdateData( &g_positions[0], 0, nverts); g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData ); s.Stop(); g_computeTime = float(s.GetElapsed() * 1000.0f); // Run Eval pass to get the samples locations ------------------------------ s.Start(); // Reset the output buffer g_nsamplesFound=0; // Bind/Unbind of the vertex buffers to the context needs to happen // outside of the parallel loop g_evalCtx->GetVertexData().Bind( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv ); // The varying data ends-up interleaved in the same g_Q output buffer because // g_Q has a stride of 6 and g_vdesc sets the offset to 3, while g_odesc sets // the offset to 0 switch (g_drawMode) { case kVARYING : g_evalCtx->GetVaryingData().Bind( g_idesc, g_varyingData, g_vdesc, g_Q ); break; case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Bind( g_fvidesc, g_fvodesc, g_Q ); case kUV : default : g_evalCtx->GetVaryingData().Unbind(); break; } #define USE_OPENMP #if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP) #pragma omp parallel for #endif for (int i=0; i<(int)g_coords.size(); ++i) { int n = g_evalCtrl.EvalLimitSample<OsdCpuVertexBuffer,OsdCpuGLVertexBuffer>( g_coords[i], g_evalCtx, i ); if (n) { // point colors switch (g_drawMode) { case kUV : { float * color = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements() + 3; color[0] = g_coords[i].u; color[1] = 0.0f; color[2] = g_coords[i].v; } break; case kVARYING : break; case kFACEVARYING : break; default : break; } #if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP) #pragma omp atomic #endif g_nsamplesFound += n; } else { // "hide" unfound samples (hole tags...) as a black dot at the origin float * sample = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements(); memset(sample, 0, g_Q->GetNumElements() * sizeof(float)); } } g_evalCtx->GetVertexData().Unbind(); switch (g_drawMode) { case kVARYING : g_evalCtx->GetVaryingData().Unbind(); break; case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Unbind(); break; default : break; } g_Q->BindVBO(); s.Stop(); g_evalTime = float(s.GetElapsed() * 1000.0f); }
//------------------------------------------------------------------------------ static void display() { Stopwatch s; s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); g_hud.FillBackground(); double aspect = g_width/(double)g_height; identity(g_transformData.ModelViewMatrix); translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly); rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0); rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0); rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0); translate(g_transformData.ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]); perspective(g_transformData.ProjectionMatrix, 45.0f, (float)aspect, 0.01f, 500.0f); multMatrix(g_transformData.ModelViewProjectionMatrix, g_transformData.ModelViewMatrix, g_transformData.ProjectionMatrix); glEnable(GL_DEPTH_TEST); s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); s.Start(); glFinish(); s.Stop(); float drawGpuTime = float(s.GetElapsed() * 1000.0f); drawSamples(); // draw the control mesh g_controlMeshDisplay.Draw( g_evalOutput->BindSourceData(), 3*sizeof(float), g_transformData.ModelViewProjectionMatrix); if (g_hud.IsVisible()) { g_fpsTimer.Stop(); double elapsed = g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); double fps = 1.0/elapsed; if (g_animParticles) g_currentTime += (float)elapsed; int nPatchCoords = (int)g_particles->GetPatchCoords().size(); g_hud.DrawString(10, -150, "Particle Speed ([) (]): %.1f", g_particles->GetSpeed()); g_hud.DrawString(10, -120, "# Samples : (%d / %d)", nPatchCoords, g_nParticles); g_hud.DrawString(10, -100, "Compute : %.3f ms", g_computeTime); g_hud.DrawString(10, -80, "Eval : %.3f ms", g_evalTime * 1000.f); g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); if (g_drawMode==kFACEVARYING) { static char msg[] = "ERROR: Face-varying interpolation hasn't been supported yet."; g_hud.DrawString(g_width/4, g_height/4, 1, 0, 0, msg); } if (g_endCap != kEndCapBSplineBasis && (g_kernel != kCPU && g_kernel != kOPENMP && g_kernel != kTBB)) { static char msg[] = "ERROR: This kernel only supports BSpline basis patches."; g_hud.DrawString(g_width/4, g_height/4+20, 1, 0, 0, msg); } g_hud.Flush(); } glFinish(); GLUtils::CheckGLErrors("display leave"); }
//------------------------------------------------------------------------------ static void updateGeom() { int nverts = (int)g_orgPositions.size() / 3; const float *p = &g_orgPositions[0]; float r = sin(g_frame*0.1f) * g_moveScale; for (int i = 0; i < nverts; ++i) { //float move = 0.05f*cosf(p[0]*20+g_frame*0.01f); float ct = cos(p[2] * r); float st = sin(p[2] * r); g_positions[i*3+0] = p[0]*ct + p[1]*st; g_positions[i*3+1] = -p[0]*st + p[1]*ct; g_positions[i*3+2] = p[2]; p+=3; } // Run Compute pass to pose the control vertices --------------------------- Stopwatch s; s.Start(); // update coarse vertices g_evalOutput->UpdateData(&g_positions[0], 0, nverts); // update coarse varying if (g_drawMode == kVARYING) { g_evalOutput->UpdateVaryingData(&g_varyingColors[0], 0, nverts); } // Refine g_evalOutput->Refine(); s.Stop(); g_computeTime = float(s.GetElapsed() * 1000.0f); // Run Eval pass to get the samples locations ------------------------------ s.Start(); // Apply 'dynamics' update assert(g_particles); float elapsed = g_currentTime - g_prevTime; g_particles->Update(elapsed); g_prevTime = g_currentTime; std::vector<OpenSubdiv::Osd::PatchCoord> const &patchCoords = g_particles->GetPatchCoords(); // update patchcoord to be evaluated g_evalOutput->UpdatePatchCoords(patchCoords); // Evaluate the positions of the samples on the limit surface if (g_drawMode == kNORMAL || g_drawMode == kSHADE) { // evaluate positions and derivatives g_evalOutput->EvalPatchesWithDerivatives(); } else { // evaluate positions g_evalOutput->EvalPatches(); } // color if (g_drawMode == kVARYING) { // XXX: is this really varying? g_evalOutput->EvalPatchesVarying(); } s.Stop(); g_evalTime = float(s.GetElapsed()); }