void GLFont::String::draw(const GLFont::Vector& origin,GLContextData& contextData) const { /* Retrieve the context data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Render a textured quad: */ glPushAttrib(GL_TEXTURE_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId); glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::BLEND); glTexEnvColor(GLTexEnvEnums::TEXTURE_ENV,foregroundColor); glColor(backgroundColor); Box offsetBox=box.offset(origin); glBegin(GL_QUADS); glNormal3f(0.0,0.0,1.0); glTexCoord(texCoord.getCorner(0)); glVertex(offsetBox.getCorner(0)); glTexCoord(texCoord.getCorner(1)); glVertex(offsetBox.getCorner(1)); glTexCoord(texCoord.getCorner(3)); glVertex(offsetBox.getCorner(3)); glTexCoord(texCoord.getCorner(2)); glVertex(offsetBox.getCorner(2)); glEnd(); glBindTexture(GL_TEXTURE_2D,0); glPopAttrib(); }
void QuadSetNode::glRenderAction(GLRenderState& renderState) const { /* Bail out if there are less than 4 points: */ if(coord.getValue()==0||coord.getValue()->point.getNumValues()<4) return; /* Set up OpenGL state: */ renderState.enableCulling(GL_BACK); /* Render the quad set: */ size_t numPoints=coord.getValue()->point.getNumValues(); glBegin(GL_QUADS); std::vector<Vector>::const_iterator qnIt=quadNormals.begin(); for(size_t q=0;q+4<=numPoints;q+=4,++qnIt) { /* Get the quad's four corner points in counter-clockwise order: */ Point ps[4]; if(ccw.getValue()) { for(size_t i=0;i<4;++i) ps[i]=coord.getValue()->point.getValue(q+i); } else { for(size_t i=0;i<4;++i) ps[i]=coord.getValue()->point.getValue(q+3-i); } if(pointTransform.getValue()!=0) { /* Transform the quad's corner points: */ for(int i=0;i<4;++i) ps[i]=pointTransform.getValue()->transformPoint(ps[i]); } /* Draw the quad's front: */ glNormal(*qnIt); for(int i=0;i<4;++i) { glTexCoord(quadTexCoords[i]); glVertex(ps[i]); } if(!solid.getValue()) { /* Draw the quad's back: */ glNormal(-*qnIt); for(int i=3;i>=0;--i) { glTexCoord(quadTexCoords[i]); glVertex(ps[i]); } } } glEnd(); }
void GLLabel::draw(GLContextData& contextData) const { /* Try listing the label with a deferred renderer: */ if(DeferredRenderer::addLabel(this)) return; /* Retrieve the context data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Save and set up OpenGL state: */ GLbitfield attribPushMask=GL_TEXTURE_BIT; bool lightingOn=glIsEnabled(GL_LIGHTING); if(lightingOn) attribPushMask|=GL_LIGHTING_BIT; glPushAttrib(attribPushMask); glEnable(GL_TEXTURE_2D); if(lightingOn) { glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::MODULATE); } else glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::REPLACE); /* Bind the label texture: */ glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId); /* Check if the texture object needs to be updated: */ if(dataItem->version!=version) { /* Upload the string's texture image: */ font->uploadStringTexture(*this,background,foreground); /* Update the texture version number: */ dataItem->version=version; } /* Draw a textured quad: */ glColor4f(1.0f,1.0f,1.0f,background[3]); glBegin(GL_QUADS); glNormal3f(0.0f,0.0f,1.0f); glTexCoord(textureBox.getCorner(0)); glVertex(labelBox.getCorner(0)); glTexCoord(textureBox.getCorner(1)); glVertex(labelBox.getCorner(1)); glTexCoord(textureBox.getCorner(3)); glVertex(labelBox.getCorner(3)); glTexCoord(textureBox.getCorner(2)); glVertex(labelBox.getCorner(2)); glEnd(); /* Reset OpenGL state: */ glBindTexture(GL_TEXTURE_2D,0); glPopAttrib(); }
void MouseCursorFaker::glRenderActionTransparent(GLContextData& contextData) const { /* Get the data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Calculate the device's ray equation: */ Ray deviceRay(device->getPosition(),device->getRayDirection()); /* Find the nearest screen intersected by the device ray: */ std::pair<VRScreen*,Scalar> fsResult=findScreen(deviceRay); if(fsResult.first!=0) { /* Calculate the cursor position on the screen: */ Point cursorPos=deviceRay(fsResult.second); Vector x=fsResult.first->getScreenTransformation().getDirection(0)*cursorSize[0]; Vector y=fsResult.first->getScreenTransformation().getDirection(1)*cursorSize[1]; cursorPos-=x*cursorHotspot[0]; cursorPos-=y*cursorHotspot[1]; /* Draw the mouse cursor: */ glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT); GLdouble depthRange[2]; glGetDoublev(GL_DEPTH_RANGE,depthRange); glDepthRange(0.0,0.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GEQUAL,0.5f); glDisable(GL_BLEND); glDepthMask(GL_TRUE); glBegin(GL_QUADS); glTexCoord(cursorTexCoordBox.getVertex(0)); glVertex(cursorPos); glTexCoord(cursorTexCoordBox.getVertex(1)); cursorPos+=x; glVertex(cursorPos); glTexCoord(cursorTexCoordBox.getVertex(3)); cursorPos+=y; glVertex(cursorPos); glTexCoord(cursorTexCoordBox.getVertex(2)); cursorPos-=x; glVertex(cursorPos); glEnd(); glBindTexture(GL_TEXTURE_2D,0); glDepthRange(depthRange[0],depthRange[1]); glPopAttrib(); } }
void TextNode::glRenderAction(VRMLRenderState& renderState) const { /* Retrieve the data item from the context: */ DataItem* dataItem=renderState.contextData.retrieveDataItem<DataItem>(this); /* Set up OpenGL state: */ glEnable(GL_TEXTURE_2D); glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::MODULATE); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GEQUAL,0.5f); glDisable(GL_CULL_FACE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); /* Draw the strings as texture-mapped quads: */ for(size_t i=0; i<string.size(); ++i) { glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectIds[i]); glBegin(GL_QUADS); glNormal3f(0.0f,0.0f,1.0f); glTexCoord(stringTexBox[i].getCorner(0)); glVertex(stringBox[i].getCorner(0)); glTexCoord(stringTexBox[i].getCorner(1)); glVertex(stringBox[i].getCorner(1)); glTexCoord(stringTexBox[i].getCorner(3)); glVertex(stringBox[i].getCorner(3)); glTexCoord(stringTexBox[i].getCorner(2)); glVertex(stringBox[i].getCorner(2)); glEnd(); } /* Protect the texture objects: */ glBindTexture(GL_TEXTURE_2D,0); /* Reset OpenGL state: */ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); glEnable(GL_CULL_FACE); glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); }
// Send out a normal, texture coordinate, vertex coordinate, and an optional custom attribute. void TParametricSurface::Vertex(vec2 domain) { vec3 p0, p1, p2, p3; vec3 normal; float u = domain.u; float v = domain.v; Eval(domain, p0); vec2 z1(u + du/2, v); Eval(z1, p1); vec2 z2(u + du/2 + du, v); Eval(z2, p3); if (flipped) { vec2 z3(u + du/2, v - dv); Eval(z3, p2); } else { vec2 z4(u + du/2, v + dv); Eval(z4, p2); } const float epsilon = 0.00001f; vec3 tangent = p3 - p1; vec3 binormal = p2 - p1; normal = cross(tangent, binormal); if (normal.magnitude() < epsilon) normal = p0; normal.unitize(); if (tangentLoc != -1) { if (tangent.magnitude() < epsilon) tangent = cross(binormal, normal); tangent.unitize(); glVertexAttrib(tangentLoc, tangent); } if (binormalLoc != -1) { binormal.unitize(); glVertexAttrib(binormalLoc, -binormal); } if (CustomAttributeLocation() != -1) glVertexAttrib1f(CustomAttributeLocation(), CustomAttributeValue(domain)); glNormal(normal); glTexCoord(domain); glVertex(p0); }
void GLFont::drawString(const GLFont::Vector& origin,const char* string) const { /* Calculate the string's texel width: */ GLsizei stringWidth=calcStringWidth(string); /* Calculate the string's bounding box: */ Box stringBox=calcStringBox(stringWidth); stringBox.doOffset(origin); /* Calculate the texture width: */ GLsizei textureWidth; for(textureWidth=1;textureWidth<stringWidth;textureWidth<<=1) ; /* Calculate the string's texture coordinates: */ TBox stringTexCoord=calcStringTexCoords(stringWidth,textureWidth); /* Upload the string's texture image: */ uploadStringTexture(string,backgroundColor,foregroundColor,stringWidth,textureWidth); /* Render a textured quad: */ glPushAttrib(GL_TEXTURE_BIT); glEnable(GL_TEXTURE_2D); glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::MODULATE); glColor4f(1.0f,1.0f,1.0f,backgroundColor[3]); glBegin(GL_QUADS); glNormal3f(0.0,0.0,1.0); glTexCoord(stringTexCoord.getCorner(0)); glVertex(stringBox.getCorner(0)); glTexCoord(stringTexCoord.getCorner(1)); glVertex(stringBox.getCorner(1)); glTexCoord(stringTexCoord.getCorner(3)); glVertex(stringBox.getCorner(3)); glTexCoord(stringTexCoord.getCorner(2)); glVertex(stringBox.getCorner(2)); glEnd(); glPopAttrib(); }
void GLLabel::DeferredRenderer::draw(void) { /* Bail out if no labels were gathered: */ if(gatheredLabels.empty()) return; /* Save and set up OpenGL state: */ GLbitfield attribPushMask=GL_TEXTURE_BIT; bool lightingOn=glIsEnabled(GL_LIGHTING); if(lightingOn) attribPushMask|=GL_LIGHTING_BIT; glPushAttrib(attribPushMask); glEnable(GL_TEXTURE_2D); if(lightingOn) { glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::MODULATE); } else glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::REPLACE); /* Draw each gathered label: */ for(std::vector<const GLLabel*>::iterator lIt=gatheredLabels.begin();lIt!=gatheredLabels.end();++lIt) { const GLLabel* l=*lIt; /* Retrieve the context data item: */ GLLabel::DataItem* dataItem=contextData.retrieveDataItem<GLLabel::DataItem>(*lIt); /* Bind the label texture: */ glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId); /* Check if the texture object needs to be updated: */ if(dataItem->version!=l->version) { /* Upload the string's texture image: */ l->font->uploadStringTexture(*l,l->background,l->foreground); /* Update the texture version number: */ dataItem->version=l->version; } /* Draw a textured quad: */ glColor4f(1.0f,1.0f,1.0f,l->background[3]); glBegin(GL_QUADS); glNormal3f(0.0f,0.0f,1.0f); glTexCoord(l->textureBox.getCorner(0)); glVertex(l->labelBox.getCorner(0)); glTexCoord(l->textureBox.getCorner(1)); glVertex(l->labelBox.getCorner(1)); glTexCoord(l->textureBox.getCorner(3)); glVertex(l->labelBox.getCorner(3)); glTexCoord(l->textureBox.getCorner(2)); glVertex(l->labelBox.getCorner(2)); glEnd(); } /* Reset OpenGL state: */ glBindTexture(GL_TEXTURE_2D,0); glPopAttrib(); /* Clear the list of labels: */ gatheredLabels.clear(); }
void IndexedFaceSetNode::glRenderAction(VRMLRenderState& renderState) const { /* Retrieve the data item from the context: */ DataItem* dataItem=renderState.contextData.retrieveDataItem<DataItem>(this); const TextureCoordinateNode* texCoordNode=dynamic_cast<const TextureCoordinateNode*>(texCoord.getPointer()); const ColorNode* colorNode=dynamic_cast<const ColorNode*>(color.getPointer()); const NormalNode* normalNode=dynamic_cast<const NormalNode*>(normal.getPointer()); const CoordinateNode* coordNode=dynamic_cast<const CoordinateNode*>(coord.getPointer()); /* Set up OpenGL: */ if(ccw) glFrontFace(GL_CCW); else glFrontFace(GL_CW); if(solid) { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); } else { glDisable(GL_CULL_FACE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); } if(dataItem->vertexBufferObjectId!=0&&dataItem->indexBufferObjectId!=0) { /* Determine which parts of the vertex array to enable: */ int vertexPartsMask=0; if(texCoordNode!=0) vertexPartsMask|=GLVertexArrayParts::TexCoord; if(colorNode!=0) vertexPartsMask|=GLVertexArrayParts::Color; if(normalNode!=0) vertexPartsMask|=GLVertexArrayParts::Normal; vertexPartsMask|=GLVertexArrayParts::Position; /* Draw the indexed triangle set: */ GLVertexArrayParts::enable(vertexPartsMask); glBindBufferARB(GL_ARRAY_BUFFER_ARB,dataItem->vertexBufferObjectId); glVertexPointer(vertexPartsMask,static_cast<const Vertex*>(0)); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,dataItem->indexBufferObjectId); glDrawElements(GL_TRIANGLES,dataItem->numTriangles*3,GL_UNSIGNED_INT,static_cast<const GLuint*>(0)); glBindBufferARB(GL_ARRAY_BUFFER_ARB,0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); GLVertexArrayParts::disable(vertexPartsMask); } else { /* Process all faces: */ std::vector<int>::const_iterator texCoordIt=texCoordIndices.empty()?coordIndices.begin():texCoordIndices.begin(); std::vector<int>::const_iterator colorIt=colorIndices.empty()?coordIndices.begin():colorIndices.begin(); int colorCounter=0; std::vector<int>::const_iterator normalIt=normalIndices.empty()?coordIndices.begin():normalIndices.begin(); int normalCounter=0; std::vector<int>::const_iterator coordIt=coordIndices.begin(); while(coordIt!=coordIndices.end()) { glBegin(GL_POLYGON); while(*coordIt>=0) { if(texCoordNode!=0) glTexCoord(texCoordNode->getPoint(*texCoordIt)); if(colorNode!=0) { if(!colorPerVertex&&colorIndices.empty()) glColor(colorNode->getColor(colorCounter)); else glColor(colorNode->getColor(*colorIt)); } if(normalNode!=0) { if(!normalPerVertex&&normalIndices.empty()) glNormal(normalNode->getVector(normalCounter)); else glNormal(normalNode->getVector(*normalIt)); } glVertex(coordNode->getPoint(*coordIt)); ++texCoordIt; if(colorPerVertex) ++colorIt; if(normalPerVertex) ++normalIt; ++coordIt; } glEnd(); ++texCoordIt; if(!colorPerVertex&&colorIndices.empty()) ++colorCounter; else ++colorIt; if(!normalPerVertex&&normalIndices.empty()) ++normalCounter; else ++normalIt; ++coordIt; } } /* Reset OpenGL state: */ if(!ccw) glFrontFace(GL_CCW); if(!solid) { glEnable(GL_CULL_FACE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); } }
void MouseNavigationTool::display(GLContextData& contextData) const { bool gotoScreenCoords=factory->showMouseCursor||(factory->showScreenCenter&&navigationMode!=IDLE&&navigationMode!=WIDGETING); const VRScreen* screen=0; ONTransform screenT; if(gotoScreenCoords) { /* Get a pointer to the screen the mouse is on: */ if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0) screen=mouseAdapter->getWindow()->getVRScreen(); else screen=getMainScreen(); screenT=screen->getScreenTransformation(); /* Save and set up OpenGL state: */ glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT|GL_TEXTURE_BIT); glDisable(GL_LIGHTING); /* Go to screen coordinates: */ glPushMatrix(); glMultMatrix(screenT); } if(factory->showScreenCenter&&navigationMode!=IDLE&&navigationMode!=WIDGETING) { /* Determine the screen containing the input device and find its center: */ Scalar centerPos[2]; if(mouseAdapter!=0) mouseAdapter->getWindow()->getWindowCenterPos(centerPos); else { centerPos[0]=getMainScreen()->getWidth()*Scalar(0.5); centerPos[1]=getMainScreen()->getHeight()*Scalar(0.5); } /* Calculate the endpoints of the screen's crosshair lines in screen coordinates: */ Point l=Point(Scalar(0),centerPos[1],Scalar(0)); Point r=Point(screen->getWidth(),centerPos[1],Scalar(0)); Point b=Point(centerPos[0],Scalar(0),Scalar(0)); Point t=Point(centerPos[0],screen->getHeight(),Scalar(0)); /* Determine the crosshair colors: */ Color bgColor=getBackgroundColor(); Color fgColor; for(int i=0; i<3; ++i) fgColor[i]=1.0f-bgColor[i]; fgColor[3]=bgColor[3]; /* Draw the screen crosshairs: */ glDepthFunc(GL_LEQUAL); glLineWidth(3.0f); glColor(bgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); glLineWidth(1.0f); glColor(fgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); } if(factory->showMouseCursor) { /* Get the data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Calculate the mouse position: */ Point mousePos=screenT.inverseTransform(currentPos); for(int i=0; i<2; ++i) mousePos[i]-=factory->mouseCursorHotspot[i]*factory->mouseCursorSize[i]; /* Draw the mouse cursor: */ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GEQUAL,0.5f); glBegin(GL_QUADS); glTexCoord(mouseCursorTexCoordBox.getVertex(0)); glVertex(mousePos[0],mousePos[1]); glTexCoord(mouseCursorTexCoordBox.getVertex(1)); glVertex(mousePos[0]+factory->mouseCursorSize[0],mousePos[1]); glTexCoord(mouseCursorTexCoordBox.getVertex(3)); glVertex(mousePos[0]+factory->mouseCursorSize[0],mousePos[1]+factory->mouseCursorSize[1]); glTexCoord(mouseCursorTexCoordBox.getVertex(2)); glVertex(mousePos[0],mousePos[1]+factory->mouseCursorSize[1]); glEnd(); glBindTexture(GL_TEXTURE_2D,0); } if(gotoScreenCoords) { /* Go back to physical coordinates: */ glPopMatrix(); /* Restore OpenGL state: */ glPopAttrib(); } }
void ColorBar::draw(GLContextData& contextData) const { /* Retrieve the context data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Draw parent class decorations: */ Widget::draw(contextData); /* Draw the widget margin: */ glColor(backgroundColor); glBegin(GL_TRIANGLE_FAN); glNormal3f(0.0f,0.0f,1.0f); glVertex(getInterior().getCorner(0)); glVertex(getInterior().getCorner(1)); for(int i=numTickMarks-1;i>=0;--i) { glVertex(tickMarks[i].labelBox.getCorner(1)); glVertex(tickMarks[i].labelBox.getCorner(0)); } glVertex(tickMarks[0].labelBox.getCorner(2)); glVertex(tickMarkLabelBox.getCorner(2)); glVertex(colorBarBox.getCorner(0)); glVertex(colorBarBox.getCorner(2)); glVertex(getInterior().getCorner(2)); glEnd(); glBegin(GL_TRIANGLE_FAN); glVertex(getInterior().getCorner(3)); glVertex(getInterior().getCorner(2)); glVertex(colorBarBox.getCorner(2)); glVertex(colorBarBox.getCorner(3)); glVertex(colorBarBox.getCorner(1)); glVertex(tickMarkLabelBox.getCorner(3)); glVertex(tickMarks[numTickMarks-1].labelBox.getCorner(3)); glVertex(tickMarks[numTickMarks-1].labelBox.getCorner(1)); glVertex(getInterior().getCorner(1)); glEnd(); /* Draw the spaces between the tick mark labels: */ glBegin(GL_QUADS); for(int i=1;i<numTickMarks;++i) { glVertex(tickMarks[i-1].labelBox.getCorner(3)); glVertex(tickMarks[i-1].labelBox.getCorner(1)); glVertex(tickMarks[i].labelBox.getCorner(0)); glVertex(tickMarks[i].labelBox.getCorner(2)); } glEnd(); /* Draw the border between tick marks and tick mark labels: */ glBegin(GL_QUAD_STRIP); GLfloat tickBot=tickMarkLabelBox.origin[1]+tickMarkLabelBox.size[1]; glVertex(tickMarkLabelBox.getCorner(2)); glVertex(tickMarks[0].labelBox.getCorner(2)); glVertex3f(tickMarkLabelBox.origin[0]+tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); glVertex(tickMarks[0].labelBox.getCorner(3)); for(int i=1;i<numTickMarks-1;++i) { GLfloat x=colorBarBox.origin[0]+colorBarBox.size[0]*GLfloat(i)/GLfloat(numTickMarks-1); glVertex3f(x-tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); glVertex(tickMarks[i].labelBox.getCorner(2)); glVertex3f(x+tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); glVertex(tickMarks[i].labelBox.getCorner(3)); } glVertex3f(tickMarkLabelBox.origin[0]+tickMarkLabelBox.size[0]-tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); glVertex(tickMarks[numTickMarks-1].labelBox.getCorner(2)); glVertex(tickMarkLabelBox.getCorner(3)); glVertex(tickMarks[numTickMarks-1].labelBox.getCorner(3)); glEnd(); /* Draw the spaces between tick marks: */ glBegin(GL_QUADS); GLfloat tickTop=colorBarBox.origin[1]; glVertex(colorBarBox.getCorner(0)); glVertex3f(tickMarkLabelBox.origin[0]+tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); for(int i=1;i<numTickMarks-1;++i) { GLfloat x=colorBarBox.origin[0]+colorBarBox.size[0]*GLfloat(i)/GLfloat(numTickMarks-1); glVertex3f(x-tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); glVertex3f(x,tickTop,colorBarBox.origin[2]); glVertex3f(x,tickTop,colorBarBox.origin[2]); glVertex3f(x+tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); } glVertex3f(tickMarkLabelBox.origin[0]+tickMarkLabelBox.size[0]-tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); glVertex(colorBarBox.getCorner(1)); glEnd(); /* Draw the tick marks: */ glBegin(GL_TRIANGLES); glColor(foregroundColor); glVertex(tickMarkLabelBox.getCorner(2)); glVertex3f(tickMarkLabelBox.origin[0]+tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); glVertex(colorBarBox.getCorner(0)); for(int i=1;i<numTickMarks-1;++i) { GLfloat x=colorBarBox.origin[0]+colorBarBox.size[0]*GLfloat(i)/GLfloat(numTickMarks-1); glVertex3f(x-tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); glVertex3f(x+tickMarkWidth*0.5f,tickBot,tickMarkLabelBox.origin[2]); glVertex3f(x,tickTop,colorBarBox.origin[2]); } glVertex3f(tickMarkLabelBox.origin[0]+tickMarkLabelBox.size[0]-tickMarkWidth,tickBot,tickMarkLabelBox.origin[2]); glVertex(tickMarkLabelBox.getCorner(3)); glVertex(colorBarBox.getCorner(1)); glEnd(); /* Set up OpenGL state for color bar rendering: */ GLboolean lightingEnabled=glIsEnabled(GL_LIGHTING); if(lightingEnabled) glDisable(GL_LIGHTING); GLboolean texture1DEnabled=glIsEnabled(GL_TEXTURE_1D); if(!texture1DEnabled) glEnable(GL_TEXTURE_1D); GLboolean texture2DEnabled=glIsEnabled(GL_TEXTURE_2D); if(texture2DEnabled) glDisable(GL_TEXTURE_2D); GLboolean texture3DEnabled=glIsEnabled(GL_TEXTURE_3D); if(texture3DEnabled) glDisable(GL_TEXTURE_3D); /* Upload the color map as a 1D texture: */ glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_BASE_LEVEL,0); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAX_LEVEL,0); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexImage1D(GL_TEXTURE_1D,0,GL_RGBA8,256,0,GL_RGBA,GL_FLOAT,colorMap->getColors()); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); GLint matrixMode; glGetIntegerv(GL_MATRIX_MODE,&matrixMode); if(matrixMode!=GL_TEXTURE) glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); glScaled(1.0/(valueMax-valueMin),1.0,1.0); glTranslated(-valueMin,0.0,0.0); /* Draw the color bar: */ glBegin(GL_TRIANGLE_FAN); glColor4f(1.0f,1.0f,1.0f,1.0f); glTexCoord1d(valueMin); glVertex(colorBarBox.getCorner(2)); glVertex(colorBarBox.getCorner(0)); for(int i=1;i<numTickMarks-1;++i) { GLfloat x=colorBarBox.origin[0]+colorBarBox.size[0]*GLfloat(i)/GLfloat(numTickMarks-1); glTexCoord1d(valueMin+(valueMax-valueMin)*double(i)/double(numTickMarks-1)); glVertex3f(x,tickTop,colorBarBox.origin[2]); } glTexCoord1d(valueMax); glVertex(colorBarBox.getCorner(1)); glVertex(colorBarBox.getCorner(3)); glEnd(); /* Reset OpenGL state: */ glPopMatrix(); if(matrixMode!=GL_TEXTURE) glMatrixMode(matrixMode); if(texture3DEnabled) glEnable(GL_TEXTURE_3D); if(texture2DEnabled) glEnable(GL_TEXTURE_2D); if(!texture1DEnabled) glDisable(GL_TEXTURE_1D); if(lightingEnabled) glEnable(GL_LIGHTING); /* Draw the tick mark labels: */ glPushAttrib(GL_TEXTURE_BIT); GLint lightModelColorControl; glGetIntegerv(GL_LIGHT_MODEL_COLOR_CONTROL,&lightModelColorControl); glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); glEnable(GL_TEXTURE_2D); for(int i=0;i<numTickMarks;++i) { glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectIds[i]); if(dataItem->tickMarksVersion!=tickMarksVersion) // Have the tick marks changed? { /* Upload the tick mark label string texture again: */ font->uploadStringTexture(tickMarks[i].label,backgroundColor,foregroundColor); } glTexEnvMode(GLTexEnvEnums::TEXTURE_ENV,GLTexEnvEnums::MODULATE); glColor4f(1.0f,1.0f,1.0f,backgroundColor[3]); glBegin(GL_QUADS); glNormal3f(0.0f,0.0f,1.0f); glTexCoord(tickMarks[i].labelTexCoords.getCorner(0)); glVertex(tickMarks[i].labelBox.getCorner(0)); glTexCoord(tickMarks[i].labelTexCoords.getCorner(1)); glVertex(tickMarks[i].labelBox.getCorner(1)); glTexCoord(tickMarks[i].labelTexCoords.getCorner(3)); glVertex(tickMarks[i].labelBox.getCorner(3)); glTexCoord(tickMarks[i].labelTexCoords.getCorner(2)); glVertex(tickMarks[i].labelBox.getCorner(2)); glEnd(); } dataItem->tickMarksVersion=tickMarksVersion; glBindTexture(GL_TEXTURE_2D,0); glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,lightModelColorControl); glPopAttrib(); }