//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void OverlayItems::createAddOverlayTextBox(OverlayItem::AnchorCorner corner, OverlayItem::LayoutScheme scheme, Font* font, const String& textString) { ref<OverlayTextBox> tb = new OverlayTextBox(font); String text = textString; switch (corner) { case OverlayItem::TOP_LEFT: text += "\nTopLeft"; break; case OverlayItem::TOP_RIGHT: text += "\nTopRight"; break; case OverlayItem::BOTTOM_LEFT: text += "\nBottomLeft"; break; case OverlayItem::BOTTOM_RIGHT: text += "\nBottomLeft"; break; default: CVF_FAIL_MSG("Unhandled"); } switch (scheme) { case OverlayItem::HORIZONTAL: text += "\nHorizontal"; break; case OverlayItem::VERTICAL: text += "\nVertical"; break; default: CVF_FAIL_MSG("Unhandled"); } tb->setText(text); tb->setSizeToFitText(); tb->setLayout(scheme, corner); m_renderSequence->firstRendering()->addOverlayItem(tb.p()); }
//-------------------------------------------------------------------------------------------------- /// Sort the render queue using the configured strategy //-------------------------------------------------------------------------------------------------- void RenderQueueSorterBasic::sort(RenderQueue* renderQueue) const { std::vector<RenderItem*>* renderItems = renderQueue->renderItemsForSorting(); CVF_TIGHT_ASSERT(renderItems); bool useTBB = TBBControl::isEnabled(); SortAlgorithms sa(useTBB); if (m_strategy == MINIMAL) { sa.sort(renderItems->begin(), renderItems->end(), ComparatorMinimal()); } else if (m_strategy == EFFECT_ONLY) { sa.sort(renderItems->begin(), renderItems->end(), ComparatorEffectOnly()); } else if (m_strategy == STANDARD) { sa.sort(renderItems->begin(), renderItems->end(), ComparatorStandard()); } else if (m_strategy == BACK_TO_FRONT) { sa.sort(renderItems->begin(), renderItems->end(), ComparatorBackToFront()); } else { CVF_FAIL_MSG("Unsupported sort strategy"); } }
//-------------------------------------------------------------------------------------------------- /// Static helper to configure polygon offset render state from enum //-------------------------------------------------------------------------------------------------- cvf::ref<cvf::RenderStatePolygonOffset> EffectGenerator::createAndConfigurePolygonOffsetRenderState(PolygonOffset polygonOffset) { cvf::ref<cvf::RenderStatePolygonOffset> rs = new cvf::RenderStatePolygonOffset; if (polygonOffset == PO_NONE) { return rs; } rs->enableFillMode(true); switch (polygonOffset) { case PO_1: rs->setFactor(1.0f); rs->setUnits(1.0f); break; case PO_2: rs->setFactor(2.0f); rs->setUnits(2.0f); break; case PO_NEG_LARGE: rs->setFactor(-1.0f); rs->setUnits(-30.0f); break; default: CVF_FAIL_MSG("Unhandled polygon offset enum"); } return rs; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const { CVF_ASSERT(normal && upVector && rightVector); switch (face) { case NCF_X_POS: *normal = Vec3f::X_AXIS; break; case NCF_X_NEG: *normal = -Vec3f::X_AXIS; break; case NCF_Y_POS: *normal = Vec3f::Y_AXIS; break; case NCF_Y_NEG: *normal = -Vec3f::Y_AXIS; break; case NCF_Z_POS: *normal = Vec3f::Z_AXIS; break; case NCF_Z_NEG: *normal = -Vec3f::Z_AXIS; break; case NCF_NONE: CVF_FAIL_MSG("Illegal nav cube face"); break; } if ((*normal)*m_upVector == 0.0) { if (*normal == m_upVector) *upVector = -m_frontVector; else *upVector = m_frontVector; } else { *upVector = m_upVector; } *rightVector = *upVector^*normal; normal->normalize(); upVector->normalize(); rightVector->normalize(); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool Texture::isBound(OpenGLContext* /*oglContext*/) const { GLint currentTextureBinding = 0; switch (m_textureType) { case TEXTURE_2D: glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTextureBinding); break; case TEXTURE_RECTANGLE: #ifndef CVF_OPENGL_ES glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE, ¤tTextureBinding); break; #else CVF_FAIL_MSG("Not supported on iOS"); break; #endif case TEXTURE_CUBE_MAP: glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, ¤tTextureBinding); break; } if (currentTextureBinding != 0) { if (static_cast<OglId>(currentTextureBinding) == OglRc::safeOglId(m_oglRcTexture.p())) { return true; } } return false; }
//-------------------------------------------------------------------------------------------------- /// Render the geometry using fixed function style of specifying the arrays. /// /// The main difference between this render path and that of render() is that this path will /// specify all client arrays or buffer objects using 'old style' glVertexArray(), glNormalArray() etc /// /// \warning Requires at least OpenGL 1.5 since it uses buffer objects. //-------------------------------------------------------------------------------------------------- void DrawableGeo::renderFixedFunction(OpenGLContext* oglContext, const MatrixState&) { CVF_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext)); #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else size_t numPrimitiveSets = m_primitiveSets.size(); if (numPrimitiveSets == 0 || m_vertexBundle->vertexCount() == 0) { return; } // Setup good old 'vertex arrays' for use with fixed function drawing VertexBundleUsage bundleUsage; m_vertexBundle->useBundleFixedFunction(oglContext, &bundleUsage); size_t i; for (i = 0; i < numPrimitiveSets; i++) { PrimitiveSet* primSet = m_primitiveSets[i].p(); CVF_TIGHT_ASSERT(primSet); primSet->render(oglContext); } CVF_CHECK_OGL(oglContext); m_vertexBundle->finishUseBundle(oglContext, &bundleUsage); #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// Draw the axis using immediate mode OpenGL //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else m_axis->renderImmediateMode(oglContext, matrixState); #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool ShaderSourceRepository::rawShaderSource(ShaderIdent shaderIdent, CharArray* rawSource) { #define CVF_SOURCE_HANDLE_CASE(THE_ENUM) case THE_ENUM: *rawSource = CharArray(THE_ENUM##_inl); return true; switch (shaderIdent) { CVF_SOURCE_HANDLE_CASE(calcClipDistances); CVF_SOURCE_HANDLE_CASE(calcShadowCoord); CVF_SOURCE_HANDLE_CASE(src_Color); CVF_SOURCE_HANDLE_CASE(src_TwoSidedColor); CVF_SOURCE_HANDLE_CASE(src_Texture); CVF_SOURCE_HANDLE_CASE(src_TextureGlobalAlpha); CVF_SOURCE_HANDLE_CASE(src_TextureFromPointCoord); CVF_SOURCE_HANDLE_CASE(src_TextureRectFromFragCoord_v33); CVF_SOURCE_HANDLE_CASE(src_VaryingColorGlobalAlpha); CVF_SOURCE_HANDLE_CASE(light_Phong); CVF_SOURCE_HANDLE_CASE(light_PhongDual); CVF_SOURCE_HANDLE_CASE(light_SimpleHeadlight); CVF_SOURCE_HANDLE_CASE(light_Headlight); CVF_SOURCE_HANDLE_CASE(checkDiscard_ClipDistances); CVF_SOURCE_HANDLE_CASE(vs_Standard); CVF_SOURCE_HANDLE_CASE(vs_EnvironmentMapping); CVF_SOURCE_HANDLE_CASE(vs_FullScreenQuad); CVF_SOURCE_HANDLE_CASE(vs_Minimal); CVF_SOURCE_HANDLE_CASE(vs_MinimalTexture); CVF_SOURCE_HANDLE_CASE(vs_VectorDrawer); CVF_SOURCE_HANDLE_CASE(vs_DistanceScaledPoints); CVF_SOURCE_HANDLE_CASE(vs_ParticleTraceComets); CVF_SOURCE_HANDLE_CASE(fs_Standard); CVF_SOURCE_HANDLE_CASE(fs_Shadow_v33); CVF_SOURCE_HANDLE_CASE(fs_Unlit); CVF_SOURCE_HANDLE_CASE(fs_Void); CVF_SOURCE_HANDLE_CASE(fs_FixedColorMagenta); CVF_SOURCE_HANDLE_CASE(fs_Text); CVF_SOURCE_HANDLE_CASE(fs_VectorDrawer); CVF_SOURCE_HANDLE_CASE(fs_CenterLitSpherePoints); CVF_SOURCE_HANDLE_CASE(fs_ParticleTraceComets); CVF_SOURCE_HANDLE_CASE(fs_GradientTopBottom); CVF_SOURCE_HANDLE_CASE(fs_GradientTopMiddleBottom); CVF_SOURCE_HANDLE_CASE(fs_HighlightStencilBlur_v33); CVF_SOURCE_HANDLE_CASE(fs_HighlightStencilDraw); CVF_SOURCE_HANDLE_CASE(fs_HighlightStencilMix_v33); CVF_SOURCE_HANDLE_CASE(fs_GaussianBlur); CVF_SOURCE_HANDLE_CASE(fs_HighlightMix); CVF_SOURCE_HANDLE_CASE(gs_PassThroughTriangle_v33); } CVF_FAIL_MSG("Unhandled shader source ident"); return false; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RenderStateMaterial_FF::RenderStateMaterial_FF(MaterialIdent materialIdent) : RenderState(MATERIAL_FF), m_specular(0, 0, 0), m_emission(0, 0, 0), m_alpha(1.0f), m_shininess(0), m_enableColorMaterial(false) { switch (materialIdent) { case PURE_WHITE: m_ambient.set(1.0f, 1.0f, 1.0f); m_diffuse.set(1.0f, 1.0f, 1.0f); break; case PURE_BLACK: m_ambient.set(0.0f, 0.0f, 0.0f); m_diffuse.set(0.0f, 0.0f, 0.0f); break; case PURE_RED: m_ambient.set(1.0f, 0.0f, 0.0f); m_diffuse.set(1.0f, 0.0f, 0.0f); break; case PURE_GREEN: m_ambient.set(0.0f, 1.0f, 0.0f); m_diffuse.set(0.0f, 1.0f, 0.0f); break; case PURE_BLUE: m_ambient.set(0.0f, 0.0f, 1.0f); m_diffuse.set(0.0f, 0.0f, 1.0f); break; case PURE_YELLOW: m_ambient.set(1.0f, 1.0f, 0.0f); m_diffuse.set(1.0f, 1.0f, 0.0f); break; case PURE_MAGENTA: m_ambient.set(1.0f, 0.0f, 1.0f); m_diffuse.set(1.0f, 0.0f, 1.0f); break; case PURE_CYAN: m_ambient.set(0.0f, 1.0f, 1.0f); m_diffuse.set(0.0f, 1.0f, 1.0f); break; case BRASS: m_ambient.set(0.329412f, 0.223529f, 0.027451f); m_diffuse.set(0.780392f, 0.568627f, 0.113725f); m_specular.set(0.992157f, 0.941176f, 0.807843f); m_alpha = 1.00f; m_shininess = 27.8974f; break; case BRONZE: m_ambient.set(0.212500f, 0.127500f, 0.054000f); m_diffuse.set(0.714000f, 0.428400f, 0.181440f); m_specular.set(0.393548f, 0.271906f, 0.166721f); m_alpha = 1.00f; m_shininess = 25.6000f; break; case POLISHED_BRONZE: m_ambient.set(0.250000f, 0.148000f, 0.064750f); m_diffuse.set(0.400000f, 0.236800f, 0.103600f); m_specular.set(0.774597f, 0.458561f, 0.200621f); m_alpha = 1.00f; m_shininess = 76.8000f; break; case CHROME: m_ambient.set(0.250000f, 0.250000f, 0.250000f); m_diffuse.set(0.400000f, 0.400000f, 0.400000f); m_specular.set(0.774597f, 0.774597f, 0.774597f); m_alpha = 1.00f; m_shininess = 76.8000f; break; case COPPER: m_ambient.set(0.191250f, 0.073500f, 0.022500f); m_diffuse.set(0.703800f, 0.270480f, 0.082800f); m_specular.set(0.256777f, 0.137622f, 0.086014f); m_alpha = 1.00f; m_shininess = 12.8000f; break; case POLISHED_COPPER: m_ambient.set(0.229500f, 0.088250f, 0.027500f); m_diffuse.set(0.550800f, 0.211800f, 0.066000f); m_specular.set(0.580594f, 0.223257f, 0.069570f); m_alpha = 1.00f; m_shininess = 51.2000f; break; case GOLD: m_ambient.set(0.247250f, 0.199500f, 0.074500f); m_diffuse.set(0.751640f, 0.606480f, 0.226480f); m_specular.set(0.628281f, 0.555802f, 0.366065f); m_alpha = 1.00f; m_shininess = 51.2000f; break; case POLISHED_GOLD: m_ambient.set(0.247250f, 0.224500f, 0.064500f); m_diffuse.set(0.346150f, 0.314300f, 0.090300f); m_specular.set(0.797357f, 0.723991f, 0.208006f); m_alpha = 1.00f; m_shininess = 83.2000f; break; case PEWTER: m_ambient.set(0.105882f, 0.058824f, 0.113725f); m_diffuse.set(0.427451f, 0.470588f, 0.541176f); m_specular.set(0.333333f, 0.333333f, 0.521569f); m_alpha = 1.00f; m_shininess = 9.8462f; break; case SILVER: m_ambient.set(0.192250f, 0.192250f, 0.192250f); m_diffuse.set(0.507540f, 0.507540f, 0.507540f); m_specular.set(0.508273f, 0.508273f, 0.508273f); m_alpha = 1.00f; m_shininess = 51.2000f; break; case POLISHED_SILVER: m_ambient.set(0.231250f, 0.231250f, 0.231250f); m_diffuse.set(0.277500f, 0.277500f, 0.277500f); m_specular.set(0.773911f, 0.773911f, 0.773911f); m_alpha = 1.00f; m_shininess = 89.6000f; break; case EMERALD: m_ambient.set(0.021500f, 0.174500f, 0.021500f); m_diffuse.set(0.075680f, 0.614240f, 0.075680f); m_specular.set(0.633000f, 0.727811f, 0.633000f); m_alpha = 0.55f; m_shininess = 76.8000f; break; case JADE: m_ambient.set(0.135000f, 0.222500f, 0.157500f); m_diffuse.set(0.540000f, 0.890000f, 0.630000f); m_specular.set(0.316228f, 0.316228f, 0.316228f); m_alpha = 0.95f; m_shininess = 12.8000f; break; case OBSIDIAN: m_ambient.set(0.053750f, 0.050000f, 0.066250f); m_diffuse.set(0.182750f, 0.170000f, 0.225250f); m_specular.set(0.332741f, 0.328634f, 0.346435f); m_alpha = 0.82f; m_shininess = 38.4000f; break; case PEARL: m_ambient.set(0.250000f, 0.207250f, 0.207250f); m_diffuse.set(1.000000f, 0.829000f, 0.829000f); m_specular.set(0.296648f, 0.296648f, 0.296648f); m_alpha = 0.92f; m_shininess = 11.2640f; break; case RUBY: m_ambient.set(0.174500f, 0.011750f, 0.011750f); m_diffuse.set(0.614240f, 0.041360f, 0.041360f); m_specular.set(0.727811f, 0.626959f, 0.626959f); m_alpha = 0.55f; m_shininess = 76.8000f; break; case TURQUOISE: m_ambient.set(0.100000f, 0.187250f, 0.174500f); m_diffuse.set(0.396000f, 0.741510f, 0.691020f); m_specular.set(0.297254f, 0.308290f, 0.306678f); m_alpha = 0.80f; m_shininess = 12.8000f; break; case BLACK_PLASTIC: m_ambient.set(0.000000f, 0.000000f, 0.000000f); m_diffuse.set(0.010000f, 0.010000f, 0.010000f); m_specular.set(0.500000f, 0.500000f, 0.500000f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case CYAN_PLASTIC: m_ambient.set(0.000000f, 0.100000f, 0.060000f); m_diffuse.set(0.000000f, 0.509804f, 0.509804f); m_specular.set(0.501961f, 0.501961f, 0.501961f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case GREEN_PLASTIC: m_ambient.set(0.000000f, 0.000000f, 0.000000f); m_diffuse.set(0.100000f, 0.350000f, 0.100000f); m_specular.set(0.450000f, 0.550000f, 0.450000f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case RED_PLASTIC: m_ambient.set(0.000000f, 0.000000f, 0.000000f); m_diffuse.set(0.500000f, 0.000000f, 0.000000f); m_specular.set(0.700000f, 0.600000f, 0.600000f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case WHITE_PLASTIC: m_ambient.set(0.000000f, 0.000000f, 0.000000f); m_diffuse.set(0.550000f, 0.550000f, 0.550000f); m_specular.set(0.700000f, 0.700000f, 0.700000f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case YELLOW_PLASTIC: m_ambient.set(0.000000f, 0.000000f, 0.000000f); m_diffuse.set(0.500000f, 0.500000f, 0.000000f); m_specular.set(0.600000f, 0.600000f, 0.500000f); m_alpha = 1.00f; m_shininess = 32.0000f; break; case BLACK_RUBBER: m_ambient.set(0.020000f, 0.020000f, 0.020000f); m_diffuse.set(0.010000f, 0.010000f, 0.010000f); m_specular.set(0.400000f, 0.400000f, 0.400000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; case CYAN_RUBBER: m_ambient.set(0.000000f, 0.050000f, 0.050000f); m_diffuse.set(0.400000f, 0.500000f, 0.500000f); m_specular.set(0.040000f, 0.700000f, 0.700000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; case GREEN_RUBBER: m_ambient.set(0.000000f, 0.050000f, 0.000000f); m_diffuse.set(0.400000f, 0.500000f, 0.400000f); m_specular.set(0.040000f, 0.700000f, 0.040000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; case RED_RUBBER: m_ambient.set(0.050000f, 0.000000f, 0.000000f); m_diffuse.set(0.500000f, 0.400000f, 0.400000f); m_specular.set(0.700000f, 0.040000f, 0.040000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; case WHITE_RUBBER: m_ambient.set(0.050000f, 0.050000f, 0.050000f); m_diffuse.set(0.500000f, 0.500000f, 0.500000f); m_specular.set(0.700000f, 0.700000f, 0.700000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; case YELLOW_RUBBER: m_ambient.set(0.050000f, 0.050000f, 0.000000f); m_diffuse.set(0.500000f, 0.500000f, 0.400000f); m_specular.set(0.700000f, 0.700000f, 0.040000f); m_alpha = 1.00f; m_shininess = 10.0000f; break; default: CVF_FAIL_MSG("Unhandled MaterialIdent"); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- String ProgramOptions::prefixString() const { switch (m_optionPrefix) { case DOUBLE_DASH: return "--"; case SINGLE_DASH: return "-"; case SLASH: return "/"; default: CVF_FAIL_MSG("Unhandled option prefix type"); return "UNKNOWN"; } }
//-------------------------------------------------------------------------------------------------- /// Do immediate mode rendering //-------------------------------------------------------------------------------------------------- void DrawableGeo::renderImmediateMode(OpenGLContext* oglContext, const MatrixState&) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else CVF_ASSERT(oglContext); const Vec3fArray* vertexArr = m_vertexBundle->vertexArray(); const Vec3fArray* normalArr = m_vertexBundle->normalArray(); const Vec2fArray* texCoordArr = m_vertexBundle->textureCoordArray(); const Color3ubArray* colorArr = m_vertexBundle->colorArray(); size_t numPrimitiveSets = m_primitiveSets.size(); size_t ip; for (ip = 0; ip < numPrimitiveSets; ip++) { const PrimitiveSet* primitiveSet = m_primitiveSets.at(ip); CVF_TIGHT_ASSERT(primitiveSet); glBegin(primitiveSet->primitiveTypeOpenGL()); size_t numIndices = primitiveSet->indexCount(); size_t i; for (i = 0; i < numIndices; i++) { uint index = primitiveSet->index(i); if (normalArr) { glNormal3fv((const float*)&normalArr->get(index)); } if (colorArr) { glColor3ubv((const ubyte*)&colorArr->get(index)); } if (texCoordArr) { glTexCoord2fv((const float*)&texCoordArr->get(index)); } glVertex3fv((float*)&vertexArr->get(index)); } glEnd(); } #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const char* ShaderSourceRepository::shaderIdentString(ShaderIdent shaderIdent) { #define CVF_IDENT_HANDLE_CASE(THE_ENUM) case THE_ENUM: return #THE_ENUM; switch (shaderIdent) { CVF_IDENT_HANDLE_CASE(calcClipDistances); CVF_IDENT_HANDLE_CASE(calcShadowCoord); CVF_IDENT_HANDLE_CASE(src_Color); CVF_IDENT_HANDLE_CASE(src_Texture); CVF_IDENT_HANDLE_CASE(src_TextureGlobalAlpha); CVF_IDENT_HANDLE_CASE(src_TextureFromPointCoord); CVF_IDENT_HANDLE_CASE(src_TextureRectFromFragCoord_v33); CVF_IDENT_HANDLE_CASE(light_Phong); CVF_IDENT_HANDLE_CASE(light_PhongDual); CVF_IDENT_HANDLE_CASE(light_SimpleHeadlight); CVF_IDENT_HANDLE_CASE(light_SimpleHeadlight_spec_uniform); CVF_IDENT_HANDLE_CASE(light_AmbientDiffuse); CVF_IDENT_HANDLE_CASE(checkDiscard_ClipDistances); CVF_IDENT_HANDLE_CASE(vs_Standard); CVF_IDENT_HANDLE_CASE(vs_EnvironmentMapping); CVF_IDENT_HANDLE_CASE(vs_FullScreenQuad); CVF_IDENT_HANDLE_CASE(vs_Minimal); CVF_IDENT_HANDLE_CASE(vs_MinimalTexture); CVF_IDENT_HANDLE_CASE(vs_VectorDrawer); CVF_IDENT_HANDLE_CASE(vs_DistanceScaledPoints); CVF_IDENT_HANDLE_CASE(vs_ParticleTraceComets); CVF_IDENT_HANDLE_CASE(fs_Standard); CVF_IDENT_HANDLE_CASE(fs_Shadow_v33); CVF_IDENT_HANDLE_CASE(fs_Unlit); CVF_IDENT_HANDLE_CASE(fs_Void); CVF_IDENT_HANDLE_CASE(fs_FixedColorMagenta); CVF_IDENT_HANDLE_CASE(fs_Text); CVF_IDENT_HANDLE_CASE(fs_VectorDrawer); CVF_IDENT_HANDLE_CASE(fs_CenterLitSpherePoints); CVF_IDENT_HANDLE_CASE(fs_ParticleTraceComets); CVF_IDENT_HANDLE_CASE(fs_GradientTopBottom); CVF_IDENT_HANDLE_CASE(fs_GradientTopMiddleBottom); CVF_IDENT_HANDLE_CASE(gs_PassThroughTriangle_v33); } CVF_FAIL_MSG("Unhandled shader ident"); return NULL; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLenum Texture::textureTypeOpenGL() const { switch(m_textureType) { case TEXTURE_2D: return GL_TEXTURE_2D; #ifndef CVF_OPENGL_ES case TEXTURE_RECTANGLE: return GL_TEXTURE_RECTANGLE; #endif case TEXTURE_CUBE_MAP: return GL_TEXTURE_CUBE_MAP; } CVF_FAIL_MSG("Illegal texture type"); return GL_TEXTURE_2D; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLint Texture2D_FF::filterTypeOpenGL(Filter filter) const { switch (filter) { case NEAREST: return GL_NEAREST; case LINEAR: return GL_LINEAR; case NEAREST_MIPMAP_NEAREST: return GL_NEAREST_MIPMAP_NEAREST; case NEAREST_MIPMAP_LINEAR: return GL_NEAREST_MIPMAP_LINEAR; case LINEAR_MIPMAP_NEAREST: return GL_LINEAR_MIPMAP_NEAREST; case LINEAR_MIPMAP_LINEAR: return GL_LINEAR_MIPMAP_LINEAR; } CVF_FAIL_MSG("Unhandled filter enum"); return GL_LINEAR; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t PrimitiveSet::faceCount() const { switch (m_primitiveType) { case PT_POINTS: return indexCount(); case PT_LINES: return indexCount()/2; case PT_LINE_LOOP: return indexCount(); case PT_LINE_STRIP: return indexCount() - 1; case PT_TRIANGLES: return triangleCount(); case PT_TRIANGLE_STRIP: return indexCount() - 2; case PT_TRIANGLE_FAN: return indexCount() - 2; default: CVF_FAIL_MSG("Unhandled primitive type"); } return 0; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLenum RenderStateBlending::blendEquationOpenGL(Equation eq) const { switch (eq) { case FUNC_ADD: return GL_FUNC_ADD; case FUNC_SUBTRACT: return GL_FUNC_SUBTRACT; case FUNC_REVERSE_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT; #ifndef CVF_OPENGL_ES case MIN: return GL_MIN; case MAX: return GL_MAX; #endif } CVF_FAIL_MSG("Unhandled blend equation"); return 0; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLenum PrimitiveSet::primitiveTypeOpenGL() const { switch (m_primitiveType) { case PT_POINTS: return GL_POINTS; case PT_LINES: return GL_LINES; case PT_LINE_LOOP: return GL_LINE_LOOP; case PT_LINE_STRIP: return GL_LINE_STRIP; case PT_TRIANGLES: return GL_TRIANGLES; case PT_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; case PT_TRIANGLE_FAN: return GL_TRIANGLE_FAN; default: CVF_FAIL_MSG("Unhandled primitive type"); } return UNDEFINED_UINT; }
//-------------------------------------------------------------------------------------------------- /// Convert ClearMode to corresponding OpenGL GLbitfield //-------------------------------------------------------------------------------------------------- cvfGLbitfield Viewport::clearFlagsOpenGL(ClearMode clearMode) { switch (clearMode) { case DO_NOT_CLEAR: return 0; case CLEAR_COLOR: return GL_COLOR_BUFFER_BIT; case CLEAR_DEPTH: return GL_DEPTH_BUFFER_BIT; case CLEAR_STENCIL: return GL_STENCIL_BUFFER_BIT; case CLEAR_COLOR_DEPTH: return (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); case CLEAR_COLOR_STENCIL: return (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); case CLEAR_DEPTH_STENCIL: return (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); case CLEAR_COLOR_DEPTH_STENCIL: return (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); default: CVF_FAIL_MSG("Unhandled clear mode"); } return 0; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::cvfGLenum RenderStateStencil::functionOpenGL(Function func) { switch (func) { case NEVER: return GL_NEVER; case LESS: return GL_LESS; case LEQUAL: return GL_LEQUAL; case GREATER: return GL_GREATER; case GEQUAL: return GL_GEQUAL; case EQUAL: return GL_EQUAL; case NOTEQUAL: return GL_NOTEQUAL; case ALWAYS: return GL_ALWAYS; } CVF_FAIL_MSG("Unhandled stencil func"); return 0; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::cvfGLenum RenderStateStencil::operationOpenGL(Operation op) { switch (op) { case KEEP: return GL_KEEP; case ZERO: return GL_ZERO; case REPLACE: return GL_REPLACE; case INCR: return GL_INCR; case INCR_WRAP: return GL_INCR_WRAP; case DECR: return GL_DECR; case DECR_WRAP: return GL_DECR_WRAP; case INVERT: return GL_INVERT; } CVF_FAIL_MSG("Unhandled stencil operation"); return 0; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void DrawableVectors::renderImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else CVF_ASSERT(oglContext); CVF_ASSERT(m_vertexArray->size() == m_vectorArray->size()); CVF_ASSERT(m_vectorGlyph.notNull()); glEnable(GL_NORMALIZE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); if (m_colorArray.isNull()) { glColor3fv(m_singleColor.ptr()); } float vectorMat[16]; size_t numVectors = m_vectorArray->size(); size_t i; for (i = 0; i < numVectors; i++) { // Compute/retrieve "matrix" vectorMatrix(i, vectorMat); glPushMatrix(); glMultMatrixf(vectorMat); if (m_colorArray.notNull()) { glColor3fv(m_colorArray->get(i).ptr()); } // Draw the geometry m_vectorGlyph->renderImmediateMode(oglContext, matrixState); glPopMatrix(); } glDisable(GL_NORMALIZE); CVF_CHECK_OGL(oglContext); #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLint Texture::internalFormatOpenGL() const { switch(m_internalFormat) { case RGBA: return GL_RGBA; case DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16; #ifndef CVF_OPENGL_ES case RGBA32F: return GL_RGBA32F; case R32F: return GL_R32F; case DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24; case DEPTH_COMPONENT32: return GL_DEPTH_COMPONENT32; case DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8; #endif } CVF_FAIL_MSG("Illegal texture internal format"); return GL_RGBA; }
//-------------------------------------------------------------------------------------------------- /// Add an XML element representing the variant to \a parent /// /// Note that invalid variants will not be added //-------------------------------------------------------------------------------------------------- XmlElement* PropertyXmlSerializer::createAddXmlElementFromVariant(const Variant& variant, XmlElement* parent) { CVF_ASSERT(variant.isValid()); CVF_ASSERT(parent); Variant::Type variantType = variant.type(); switch (variantType) { case Variant::INT: return parent->addChildElement("Int", String(variant.getInt())); case Variant::UINT: return parent->addChildElement("UInt", String(variant.getUInt())); case Variant::DOUBLE: return parent->addChildElement("Double", String::number(variant.getDouble())); case Variant::FLOAT: return parent->addChildElement("Float", String::number(variant.getFloat())); case Variant::BOOL: return parent->addChildElement("Bool", variant.getBool() ? "true" : "false"); case Variant::VEC3D: return parent->addChildElement("Vec3d", valueTextFromVec3dVariant(variant)); case Variant::COLOR3F: return parent->addChildElement("Color3f", valueTextFromColor3fVariant(variant)); case Variant::STRING: return parent->addChildElement("String", variant.getString()); case Variant::ARRAY: return createAddXmlElementFromArrayVariant(variant, parent); case Variant::INVALID: return NULL; } CVF_FAIL_MSG("Unhandled variant type"); return NULL; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvfGLenum RenderStateBlending::blendFuncOpenGL(Function func) const { switch (func) { case ZERO: return GL_ZERO; case ONE: return GL_ONE; case SRC_COLOR: return GL_SRC_COLOR; case ONE_MINUS_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR; case DST_COLOR: return GL_DST_COLOR; case ONE_MINUS_DST_COLOR: return GL_ONE_MINUS_DST_COLOR; case SRC_ALPHA: return GL_SRC_ALPHA; case ONE_MINUS_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA; case DST_ALPHA: return GL_DST_ALPHA; case ONE_MINUS_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA; case CONSTANT_COLOR: return GL_CONSTANT_COLOR; case ONE_MINUS_CONSTANT_COLOR: return GL_ONE_MINUS_CONSTANT_COLOR; case CONSTANT_ALPHA: return GL_CONSTANT_ALPHA; case ONE_MINUS_CONSTANT_ALPHA: return GL_ONE_MINUS_CONSTANT_ALPHA; case SRC_ALPHA_SATURATE: return GL_SRC_ALPHA_SATURATE; } CVF_FAIL_MSG("Unhandled blend func"); return 0; }
//-------------------------------------------------------------------------------------------------- /// Static factory method //-------------------------------------------------------------------------------------------------- QSRPropGuiBinding* QSRPropGuiBinding::createGuiBindingForProperty(cvfu::Property* property) { if (dynamic_cast<cvfu::PropertyBool*>(property)) { return new QSRPropGuiBindingBool(dynamic_cast<cvfu::PropertyBool*>(property)); } else if (dynamic_cast<cvfu::PropertyInt*>(property)) { return new QSRPropGuiBindingInt(dynamic_cast<cvfu::PropertyInt*>(property)); } else if (dynamic_cast<cvfu::PropertyDouble*>(property)) { return new QSRPropGuiBindingDouble(dynamic_cast<cvfu::PropertyDouble*>(property)); } else if (dynamic_cast<cvfu::PropertyEnum*>(property)) { return new QSRPropGuiBindingEnum(dynamic_cast<cvfu::PropertyEnum*>(property)); } else { CVF_FAIL_MSG("Unhandled property class"); return NULL; } }
//-------------------------------------------------------------------------------------------------- /// Explicitly generate mipmaps /// /// \warning Requires the GENERATE_MIPMAP_FUNC capability. Will assert if this requirement is not met. //-------------------------------------------------------------------------------------------------- void Texture::generateMipmap(OpenGLContext* oglContext) { CVF_CALLSITE_OPENGL(oglContext); CVF_ASSERT(oglContext->capabilities()->hasCapability(OpenGLCapabilities::GENERATE_MIPMAP_FUNC)); bind(oglContext); if (m_textureType == TEXTURE_2D) { glGenerateMipmap(GL_TEXTURE_2D); m_hasMipmaps = true; } else if (m_textureType == TEXTURE_CUBE_MAP) { glGenerateMipmap(GL_TEXTURE_CUBE_MAP); m_hasMipmaps = true; } else { CVF_FAIL_MSG("Mipmap generation not supported for this texture type"); } CVF_CHECK_OGL(oglContext); }
//-------------------------------------------------------------------------------------------------- /// Setup and bind texture //-------------------------------------------------------------------------------------------------- void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software) { // Short path first if everything is in place if (m_textureBindings.notNull()) { RenderState::Type renderStateType = m_textureBindings->type(); if (software) { #ifndef CVF_OPENGL_ES if (renderStateType == RenderState::TEXTURE_MAPPING_FF) { RenderStateTextureMapping_FF* texMapping = static_cast<RenderStateTextureMapping_FF*>(m_textureBindings.p()); texMapping->setupTexture(oglContext); texMapping->applyOpenGL(oglContext); return; } #else CVF_FAIL_MSG("Not supported on OpenGL ES"); #endif } else { if (renderStateType == RenderState::TEXTURE_BINDINGS) { RenderStateTextureBindings* texBindings = static_cast<RenderStateTextureBindings*>(m_textureBindings.p()); texBindings->setupTextures(oglContext); texBindings->applyOpenGL(oglContext); return; } } } m_textureBindings = NULL; if (m_textureBindings.isNull()) { // TODO // Revisit the code that sets up the texture image // The code below ends up modifying the stored texture image // Is this intentional - there is an external getter for the image!! CVF_TIGHT_ASSERT(0 < m_textureImage->width()); CVF_TIGHT_ASSERT(0 < m_textureImage->height()); uint pow2Width = Math::roundUpPow2(m_width); uint pow2Height = Math::roundUpPow2(m_height); TextureImage* pow2Image = new TextureImage; pow2Image->allocate(pow2Width, pow2Height); pow2Image->fill(Color4ub(255, 255, 255, 0)); uint i, j; for (j = 0; j < m_height; j++) { for (i = 0; i < m_width; i++) { pow2Image->setPixel(i, j, m_textureImage->pixel(i, j)); } } float textureCoordinateMaxX = static_cast<float>(m_width) / static_cast<float>(pow2Width); float textureCoordinateMaxY = static_cast<float>(m_height) / static_cast<float>(pow2Height); // Lower left m_textureCoordinates->set(0, 0.0f); m_textureCoordinates->set(1, 0.0f); // Lower right m_textureCoordinates->set(2, textureCoordinateMaxX); m_textureCoordinates->set(3, 0.0f); // Upper right m_textureCoordinates->set(4, textureCoordinateMaxX); m_textureCoordinates->set(5, textureCoordinateMaxY); // Upper left m_textureCoordinates->set(6, 0.0f); m_textureCoordinates->set(7, textureCoordinateMaxY); m_textureImage = pow2Image; if (software) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else // Use fixed function texture setup ref<Texture2D_FF> texture = new Texture2D_FF(m_textureImage.p()); texture->setWrapMode(Texture2D_FF::CLAMP); if (m_minFilter == NEAREST) { texture->setMinFilter(Texture2D_FF::NEAREST); } else { texture->setMinFilter(Texture2D_FF::LINEAR); } if (m_magFilter == NEAREST) { texture->setMagFilter(Texture2D_FF::NEAREST); } else { texture->setMagFilter(Texture2D_FF::LINEAR); } ref<RenderStateTextureMapping_FF> textureMapping = new RenderStateTextureMapping_FF(texture.p()); textureMapping->setTextureFunction(RenderStateTextureMapping_FF::MODULATE); textureMapping->setupTexture(oglContext); m_textureBindings = textureMapping; #endif } else { ref<Sampler> sampler = new Sampler; sampler->setWrapMode(Sampler::CLAMP_TO_EDGE); if (m_minFilter == NEAREST) { sampler->setMinFilter(Sampler::NEAREST); } else { sampler->setMinFilter(Sampler::LINEAR); } if (m_magFilter == NEAREST) { sampler->setMagFilter(Sampler::NEAREST); } else { sampler->setMagFilter(Sampler::LINEAR); } ref<Texture> texture = new Texture(m_textureImage.p()); RenderStateTextureBindings* textureBindings = new RenderStateTextureBindings(texture.p(), sampler.p(), "dummy"); textureBindings->setupTextures(oglContext); m_textureBindings = textureBindings; } } if (m_textureBindings.notNull()) { m_textureBindings->applyOpenGL(oglContext); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) { m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size()); // Spread fault idx'es on the cells from the faults for (size_t fIdx = 0 ; fIdx < m_faults.size(); ++fIdx) { m_faults[fIdx]->accumulateFaultsPrCell(m_faultsPrCellAcc.p(), static_cast<int>(fIdx)); } // Find the geometrical faults that is in addition: Has no user defined (eclipse) fault assigned. // Separate the grid faults that has an inactive cell as member RigFault* unNamedFault = new RigFault; unNamedFault->setName(RimDefines::undefinedGridFaultName()); int unNamedFaultIdx = static_cast<int>(m_faults.size()); m_faults.push_back(unNamedFault); RigFault* unNamedFaultWithInactive = new RigFault; unNamedFaultWithInactive->setName(RimDefines::undefinedGridFaultWithInactiveName()); int unNamedFaultWithInactiveIdx = static_cast<int>(m_faults.size()); m_faults.push_back(unNamedFaultWithInactive); const std::vector<cvf::Vec3d>& vxs = m_mainGrid->nodes(); for (int gcIdx = 0 ; gcIdx < static_cast<int>(m_cells.size()); ++gcIdx) { if ( m_cells[gcIdx].isInvalid()) { continue; } size_t neighborReservoirCellIdx; size_t neighborGridCellIdx; size_t i, j, k; RigGridBase* hostGrid = NULL; bool firstNO_FAULTFaceForCell = true; bool isCellActive = true; for (char faceIdx = 0; faceIdx < 6; ++faceIdx) { cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::FaceType(faceIdx); // For faces that has no used defined Fault assigned: if (m_faultsPrCellAcc->faultIdx(gcIdx, face) == RigFaultsPrCellAccumulator::NO_FAULT) { // Find neighbor cell if (firstNO_FAULTFaceForCell) // To avoid doing this for every face, and only when detecting a NO_FAULT { hostGrid = m_cells[gcIdx].hostGrid(); hostGrid->ijkFromCellIndex(m_cells[gcIdx].gridLocalCellIndex(), &i,&j, &k); isCellActive = activeCellInfo->isActive(gcIdx); firstNO_FAULTFaceForCell = false; } if(!hostGrid->cellIJKNeighbor(i, j, k, face, &neighborGridCellIdx)) { continue; } neighborReservoirCellIdx = hostGrid->reservoirCellIndex(neighborGridCellIdx); if (m_cells[neighborReservoirCellIdx].isInvalid()) { continue; } bool isNeighborCellActive = activeCellInfo->isActive(neighborReservoirCellIdx); double tolerance = 1e-6; caf::SizeTArray4 faceIdxs; m_cells[gcIdx].faceIndices(face, &faceIdxs); caf::SizeTArray4 nbFaceIdxs; m_cells[neighborReservoirCellIdx].faceIndices(StructGridInterface::oppositeFace(face), &nbFaceIdxs); bool sharedFaceVertices = true; if (sharedFaceVertices && vxs[faceIdxs[0]].pointDistance(vxs[nbFaceIdxs[0]]) > tolerance ) sharedFaceVertices = false; if (sharedFaceVertices && vxs[faceIdxs[1]].pointDistance(vxs[nbFaceIdxs[3]]) > tolerance ) sharedFaceVertices = false; if (sharedFaceVertices && vxs[faceIdxs[2]].pointDistance(vxs[nbFaceIdxs[2]]) > tolerance ) sharedFaceVertices = false; if (sharedFaceVertices && vxs[faceIdxs[3]].pointDistance(vxs[nbFaceIdxs[1]]) > tolerance ) sharedFaceVertices = false; if (sharedFaceVertices) { continue; } // To avoid doing this calculation for the opposite face int faultIdx = unNamedFaultIdx; if (!(isCellActive && isNeighborCellActive)) faultIdx = unNamedFaultWithInactiveIdx; m_faultsPrCellAcc->setFaultIdx(gcIdx, face, faultIdx); m_faultsPrCellAcc->setFaultIdx(neighborReservoirCellIdx, StructGridInterface::oppositeFace(face), faultIdx); // Add as fault face only if the grid index is less than the neighbors if (static_cast<size_t>(gcIdx) < neighborReservoirCellIdx) { RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborReservoirCellIdx); if(isCellActive && isNeighborCellActive) { unNamedFault->faultFaces().push_back(ff); } else { unNamedFaultWithInactive->faultFaces().push_back(ff); } } else { CVF_FAIL_MSG("Found fault with global neighbor index less than the native index. "); // Should never occur. because we flag the opposite face in the faultsPrCellAcc } } } } distributeNNCsToFaults(); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const int* Uniform::intPtr() const { CVF_FAIL_MSG("Must be implemented in derived class"); return NULL; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rendering::calculateOverlayItemLayout(OverlayItemRectMap* itemRectMap, OverlayItem::LayoutCorner corner, OverlayItem::LayoutDirection direction) { const int border = 3; const Vec2i vpSize = Vec2i(static_cast<int>(m_camera->viewport()->width()), static_cast<int>(m_camera->viewport()->height())); const Vec2i vpPos = Vec2i(m_camera->viewport()->x(), m_camera->viewport()->y()); Vec2i cursor(0,0); switch (corner) { case OverlayItem::TOP_LEFT: cursor.set(border, vpSize.y() - border); break; case OverlayItem::TOP_RIGHT: cursor.set(vpSize.x() - border, vpSize.y() - border); break; case OverlayItem::BOTTOM_LEFT: cursor.set(border, border); break; case OverlayItem::BOTTOM_RIGHT: cursor.set(vpSize.x() - border, border); break; default: cursor.set(border,border); } cursor += vpPos; // Adjust based on other already placed items OverlayItemRectMap::iterator it; for (it = itemRectMap->begin(); it != itemRectMap->end(); ++it) { Recti rect = it->second; if (rect.contains(cursor) && (direction == OverlayItem::VERTICAL)) { if (corner == OverlayItem::BOTTOM_LEFT || corner == OverlayItem::BOTTOM_RIGHT) { cursor.y() += rect.height() + border; } else { cursor.y() -= rect.height() + border; } } } size_t numOverlayItems = m_overlayItems.size(); size_t i; for (i = 0; i < numOverlayItems; i++) { OverlayItemLayout item = m_overlayItems.at(i); if ((item.corner == corner) && (item.direction == direction)) { CVF_ASSERT(item.overlayItem.notNull()); // Find this position and size Vec2i position = cursor; Vec2ui size = item.overlayItem->sizeHint(); if ((corner == OverlayItem::TOP_RIGHT) || (corner == OverlayItem::BOTTOM_RIGHT)) { position.x() -= size.x(); } if ((corner == OverlayItem::TOP_LEFT) || (corner == OverlayItem::TOP_RIGHT)) { position.y() -= size.y(); } // Store the position in the map Recti rect(position.x(), position.y(), static_cast<int>(size.x()), static_cast<int>(size.y())); (*itemRectMap)[item.overlayItem.p()] = rect; // Find next position, moving the cursor if (direction == OverlayItem::HORIZONTAL) { if ((corner == OverlayItem::TOP_LEFT) || (corner == OverlayItem::BOTTOM_LEFT)) { cursor.x() += (size.x() + border); } else { cursor.x() -= (size.x() + border); } } else if (direction == OverlayItem::VERTICAL) { if ((corner == OverlayItem::BOTTOM_LEFT) || (corner == OverlayItem::BOTTOM_RIGHT)) { cursor.y() += (size.y() + border); } else { cursor.y() -= (size.y() + border); } } else { CVF_FAIL_MSG("Unhandled OverlayItem::LayoutDirection"); } } } }