Add a GLPainter class to do all the OpenGL drawing stuff

This commit is contained in:
wmayer 2013-04-27 19:24:39 +02:00
parent adaa3716dd
commit 420d10face
10 changed files with 346 additions and 244 deletions

View File

@ -576,6 +576,7 @@ SOURCE_GROUP("Widget\\iisTaskPanel\\Mocs" FILES ${iis_MOC_SRCS})
# The 3d view
SET(View3D_CPP_SRCS
Flag.cpp
GLPainter.cpp
MouseSelection.cpp
NavigationStyle.cpp
InventorNavigationStyle.cpp
@ -592,6 +593,7 @@ SET(View3D_CPP_SRCS
SET(View3D_SRCS
${View3D_CPP_SRCS}
Flag.h
GLPainter.h
MouseSelection.h
NavigationStyle.h
SplitView3DInventor.h

View File

@ -27,6 +27,8 @@
# include <QMouseEvent>
#endif
#include <Inventor/SbVec2s.h>
#include "View3DInventorViewer.h"
#include "GLPainter.h"
#include "Flag.h"
@ -192,7 +194,7 @@ const SbVec3f& Flag::getOrigin() const
return this->coord;
}
void Flag::drawLine (int tox, int toy)
void Flag::drawLine (View3DInventorViewer* v, int tox, int toy)
{
if (!isVisible())
return;
@ -204,50 +206,17 @@ void Flag::drawLine (int tox, int toy)
int fromy = pos().y() + height()/2;
if (false) fromx += width();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, view[0], 0, view[1], -1, 1);
// Store GL state
glPushAttrib(GL_ALL_ATTRIB_BITS);
GLfloat depthrange[2];
glGetFloatv(GL_DEPTH_RANGE, depthrange);
GLdouble projectionmatrix[16];
glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDepthRange(0,0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glColor4f(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, view[0], view[1]);
GLPainter p;
p.begin(v);
p.setDrawBuffer(GL_BACK);
// the line
glLineWidth(1.0f);
glBegin(GL_LINE_LOOP);
glVertex3i(fromx, view[1]-fromy, 0);
glVertex3i(tox , view[1]-toy , 0);
glEnd();
glPointSize(3.0f);
glBegin(GL_POINTS);
glVertex3i(tox , view[1]-toy , 0);
glEnd();
glFlush();
// Reset original state
glDepthRange(depthrange[0], depthrange[1]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionmatrix);
glPopAttrib();
glPopMatrix();
p.setLineWidth(1.0f);
p.drawLine(fromx, fromy, tox, toy);
// the point
p.setPointSize(3.0f);
p.drawPoint(tox, toy);
p.end();
}
void Flag::setText(const QString& t)

View File

@ -31,7 +31,7 @@
#include <Inventor/SbVec3f.h>
namespace Gui {
class View3DInventorViewer;
/**
* @author Werner Mayer
*/
@ -47,7 +47,7 @@ public:
QSize sizeHint() const;
void setOrigin(const SbVec3f&);
const SbVec3f& getOrigin() const;
void drawLine(int tox, int toy);
void drawLine(Gui::View3DInventorViewer*, int tox, int toy);
void setText(const QString&);
protected:

184
src/Gui/GLPainter.cpp Normal file
View File

@ -0,0 +1,184 @@
/***************************************************************************
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "GLPainter.h"
#include "View3DInventorViewer.h"
using namespace Gui;
GLPainter::GLPainter() : viewer(0), logicOp(false), lineStipple(false)
{
}
GLPainter::~GLPainter()
{
end();
}
bool GLPainter::begin(View3DInventorViewer* v)
{
if (viewer)
return false;
viewer = v;
// Make current context
SbVec2s view = viewer->getGLSize();
this->width = view[0];
this->height = view[1];
viewer->glLockNormal();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, this->width, 0, this->height, -1, 1);
// Store GL state
glPushAttrib(GL_ALL_ATTRIB_BITS);
glGetFloatv(GL_DEPTH_RANGE, this->depthrange);
glGetDoublev(GL_PROJECTION_MATRIX, this->projectionmatrix);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDepthRange(0,0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glLineWidth(1.0f);
glColor4f(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, this->width, this->height);
glDrawBuffer(GL_FRONT);
return true;
}
bool GLPainter::end()
{
if (!viewer)
return false;
glFlush();
if (this->logicOp) {
this->logicOp = false;
glDisable(GL_COLOR_LOGIC_OP);
}
if (this->lineStipple) {
this->lineStipple = false;
glDisable(GL_LINE_STIPPLE);
}
// Reset original state
glDepthRange(this->depthrange[0], this->depthrange[1]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(this->projectionmatrix);
glPopAttrib();
glPopMatrix();
// Release the context
viewer->glUnlockNormal();
viewer = 0;
return true;
}
bool GLPainter::isActive() const
{
return viewer != 0;
}
void GLPainter::setLineWidth(float w)
{
glLineWidth(w);
}
void GLPainter::setPointSize(float s)
{
glPointSize(s);
}
void GLPainter::setColor(float r, float g, float b, float a)
{
glColor4f(r, g, b, a);
}
void GLPainter::setLogicOp(GLenum mode)
{
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(mode);
this->logicOp = true;
}
void GLPainter::setDrawBuffer(GLenum mode)
{
glDrawBuffer(mode);
}
void GLPainter::setLineStipple(GLint factor, GLushort pattern)
{
glEnable(GL_LINE_STIPPLE);
glLineStipple(factor, pattern);
this->lineStipple = true;
}
// Draw routines
void GLPainter::drawRect(int x1, int y1, int x2, int y2)
{
if (!viewer)
return;
glBegin(GL_LINE_LOOP);
glVertex3i(x1, this->height-y1, 0);
glVertex3i(x2, this->height-y1, 0);
glVertex3i(x2, this->height-y2, 0);
glVertex3i(x1, this->height-y2, 0);
glEnd();
}
void GLPainter::drawLine (int x1, int y1, int x2, int y2)
{
if (!viewer)
return;
glBegin(GL_LINES);
glVertex3i(x1, this->height-y1, 0);
glVertex3i(x2, this->height-y2, 0);
glEnd();
}
void GLPainter::drawPoint(int x, int y)
{
if (!viewer)
return;
glBegin(GL_POINTS);
glVertex3i(x, this->height-y, 0);
glEnd();
}

77
src/Gui/GLPainter.h Normal file
View File

@ -0,0 +1,77 @@
/***************************************************************************
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_GLPAINTER_H
#define GUI_GLPAINTER_H
#ifdef FC_OS_WIN32
#include <windows.h>
#endif
#ifdef FC_OS_MACOSX
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
namespace Gui {
class View3DInventorViewer;
class GuiExport GLPainter
{
public:
GLPainter();
virtual ~GLPainter();
bool begin(View3DInventorViewer*);
bool end();
bool isActive() const;
/** @name Setter methods */
//@{
void setLineWidth(float);
void setPointSize(float);
void setColor(float, float, float, float=0);
void setLogicOp(GLenum);
void setDrawBuffer(GLenum);
void setLineStipple(GLint factor, GLushort pattern);
//@}
/** @name Draw routines */
//@{
void drawRect (int x, int y, int w, int h);
void drawLine (int x1, int y1, int x2, int y2);
void drawPoint(int x, int y);
//@}
private:
View3DInventorViewer* viewer;
GLfloat depthrange[2];
GLdouble projectionmatrix[16];
GLint width, height;
bool logicOp;
bool lineStipple;
};
} // namespace Gui
#endif // GUI_GLPAINTER_H

View File

@ -41,6 +41,7 @@
#include "MouseSelection.h"
#include "View3DInventor.h"
#include "View3DInventorViewer.h"
#include "GLPainter.h"
using namespace Gui;
@ -263,10 +264,15 @@ void PolyPickerSelection::draw ()
if (mustRedraw){
if (_cNodeVector.size() > 1) {
QPoint start = _cNodeVector.front();
GLPainter p;
p.begin(_pcView3D);
p.setColor(1.0f,1.0f,1.0f);
p.setLogicOp(GL_XOR);
for (std::vector<QPoint>::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) {
_pcView3D->drawLine(start.x(),start.y(),it->x(), it->y() );
p.drawLine(start.x(),start.y(),it->x(), it->y());
start = *it;
}
p.end();
}
// recursive call, but no infinite loop
@ -279,15 +285,25 @@ void PolyPickerSelection::draw ()
if (_cNodeVector.size() > 2) {
QPoint start = _cNodeVector.front();
_pcView3D->drawLine(m_iXnew,m_iYnew,start.x(), start.y() );
GLPainter p;
p.begin(_pcView3D);
p.setColor(1.0f,1.0f,1.0f);
p.setLogicOp(GL_XOR);
p.drawLine(m_iXnew,m_iYnew,start.x(), start.y());
p.end();
}
}
else {
_pcView3D->drawLine(m_iXnew,m_iYnew,m_iXold,m_iYold);
GLPainter p;
p.begin(_pcView3D);
p.setColor(1.0f,1.0f,1.0f);
p.setLogicOp(GL_XOR);
p.drawLine(m_iXnew,m_iYnew,m_iXold,m_iYold);
if (_cNodeVector.size() > 1) {
QPoint start = _cNodeVector.front();
_pcView3D->drawLine(m_iXnew,m_iYnew,start.x(), start.y());
p.drawLine(m_iXnew,m_iYnew,start.x(), start.y());
}
p.end();
}
}
}
@ -494,11 +510,15 @@ void BrushSelection::draw ()
if (mustRedraw){
if (_cNodeVector.size() > 1) {
QPoint start = _cNodeVector.front();
GLPainter p;
p.begin(_pcView3D);
p.setLineWidth(this->l);
p.setColor(this->r, this->g, this->b, this->a);
for (std::vector<QPoint>::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) {
_pcView3D->drawLine(start.x(),start.y(),it->x(), it->y(),
this->l, this->r, this->g, this->b, this->a);
p.drawLine(start.x(),start.y(),it->x(), it->y());
start = *it;
}
p.end();
}
// recursive call, but no infinite loop
@ -506,8 +526,12 @@ void BrushSelection::draw ()
draw();
}
if (m_bWorking) {
_pcView3D->drawLine(m_iXnew, m_iYnew, m_iXold, m_iYold,
this->l, this->r, this->g, this->b, this->a);
GLPainter p;
p.begin(_pcView3D);
p.setLineWidth(this->l);
p.setColor(this->r, this->g, this->b, this->a);
p.drawLine(m_iXnew, m_iYnew, m_iXold, m_iYold);
p.end();
}
}
@ -664,8 +688,16 @@ void RectangleSelection::terminate()
void RectangleSelection::draw ()
{
if (m_bWorking)
_pcView3D->drawRect(m_iXold, m_iYold, m_iXnew, m_iYnew);
if (m_bWorking) {
GLPainter p;
p.begin(_pcView3D);
p.setColor(1.0, 1.0, 0.0, 0.0);
p.setLogicOp(GL_XOR);
p.setLineWidth(3.0f);
p.setLineStipple(2, 0x3F3F);
p.drawRect(m_iXold, m_iYold, m_iXnew, m_iYnew);
p.end();
}
}
int RectangleSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos )

View File

@ -87,6 +87,19 @@ void Thumbnail::SaveDocFile (Base::Writer &writer) const
QImage img;
try {
this->viewer->savePicture(this->size, this->size, View3DInventorViewer::Current, img);
// Alternative way of off-screen rendering
#if 0
QGLFramebufferObject fbo(this->size, this->size,QGLFramebufferObject::Depth);
fbo.bind();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthRange(0.1,1.0);
glEnable(GL_LINE_SMOOTH);
SoGLRenderAction gl(SbViewportRegion(this->size,this->size));
gl.apply(this->viewer->getSceneManager()->getSceneGraph());
fbo.release();
img = fbo.toImage();
#endif
}
catch (...) {
return; // offscreen rendering failed

View File

@ -948,7 +948,7 @@ void View3DInventorViewer::actualRedraw(void)
vv.projectToScreen(pt, pt);
int tox = (int)(pt[0] * size[0]);
int toy = (int)((1.0f-pt[1]) * size[1]);
flag->drawLine(tox, toy);
flag->drawLine(this, tox, toy);
}
}
}
@ -1506,181 +1506,6 @@ void View3DInventorViewer::viewSelection()
root->unref();
}
// Draw routines
void View3DInventorViewer::drawRect(int x1, int y1, int x2, int y2)
{
// Make current context
SbVec2s view = this->getGLSize();
this->glLockNormal();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, view[0], 0, view[1], -1, 1);
// Store GL state
glPushAttrib(GL_ALL_ATTRIB_BITS);
GLfloat depthrange[2];
glGetFloatv(GL_DEPTH_RANGE, depthrange);
GLdouble projectionmatrix[16];
glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDepthRange(0,0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
glDrawBuffer(GL_FRONT);
glLineWidth(3.0f);
glEnable(GL_LINE_STIPPLE);
glLineStipple(2, 0x3F3F);
glColor4f(1.0, 1.0, 0.0, 0.0);
glViewport(0, 0, view[0], view[1]);
glBegin(GL_LINE_LOOP);
glVertex3i(x1, view[1]-y1, 0);
glVertex3i(x2, view[1]-y1, 0);
glVertex3i(x2, view[1]-y2, 0);
glVertex3i(x1, view[1]-y2, 0);
glEnd();
glFlush();
glDisable(GL_LINE_STIPPLE);
glDisable(GL_COLOR_LOGIC_OP);
// Reset original state
glDepthRange(depthrange[0], depthrange[1]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionmatrix);
glPopAttrib();
glPopMatrix();
// Release the context
this->glUnlockNormal();
}
void View3DInventorViewer::drawLine (int x1, int y1, int x2, int y2)
{
// Make current context
SbVec2s view = this->getGLSize();
this->glLockNormal();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, view[0], 0, view[1], -1, 1);
// Store GL state
glPushAttrib(GL_ALL_ATTRIB_BITS);
GLfloat depthrange[2];
glGetFloatv(GL_DEPTH_RANGE, depthrange);
GLdouble projectionmatrix[16];
glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDepthRange(0,0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glLineWidth(1.0f);
glColor4f(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, view[0], view[1]);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
glDrawBuffer(GL_FRONT);
glBegin(GL_LINES);
glVertex3i(x1, view[1]-y1, 0);
glVertex3i(x2, view[1]-y2, 0);
glEnd();
glFlush();
glLogicOp(GL_COPY);
glDisable(GL_COLOR_LOGIC_OP);
// Reset original state
glDepthRange(depthrange[0], depthrange[1]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionmatrix);
glPopAttrib();
glPopMatrix();
// Release the context
this->glUnlockNormal();
}
void View3DInventorViewer::drawLine (int x1, int y1, int x2, int y2, GLfloat line,
GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha,
GLenum op)
{
// Make current context
SbVec2s view = this->getGLSize();
this->glLockNormal();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, view[0], 0, view[1], -1, 1);
// Store GL state
glPushAttrib(GL_ALL_ATTRIB_BITS);
GLfloat depthrange[2];
glGetFloatv(GL_DEPTH_RANGE, depthrange);
GLdouble projectionmatrix[16];
glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_TRUE);
glDepthRange(0,0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_BLEND);
glLineWidth(line);
glColor4f(red, green, blue, alpha);
glViewport(0, 0, view[0], view[1]);
if (op > 0) {
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(op);
}
glDrawBuffer(GL_FRONT);
glBegin(GL_LINES);
glVertex3i(x1, view[1]-y1, 0);
glVertex3i(x2, view[1]-y2, 0);
glEnd();
glFlush();
if (op) {
glLogicOp(GL_COPY);
glDisable(GL_COLOR_LOGIC_OP);
}
// Reset original state
glDepthRange(depthrange[0], depthrange[1]);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionmatrix);
glPopAttrib();
glPopMatrix();
// Release the context
this->glUnlockNormal();
}
/*!
Decide if it should be possible to start a spin animation of the
model in the viewer by releasing the mouse button while dragging.

View File

@ -252,15 +252,6 @@ public:
*/
void viewSelection();
/** @name Draw routines */
//@{
void drawRect (int x, int y, int w, int h);
void drawLine (int x1, int y1, int x2, int y2);
void drawLine (int x1, int y1, int x2, int y2,
GLfloat line, GLfloat red, GLfloat green,
GLfloat blue, GLfloat alpha, GLenum op=0);
//@}
void setGradientBackgroud(bool b);
void setGradientBackgroudColor(const SbColor& fromColor,
const SbColor& toColor);
@ -331,6 +322,7 @@ private:
// friends
friend class NavigationStyle;
friend class GLPainter;
};
} // namespace Gui

View File

@ -80,6 +80,7 @@
#include <Gui/Document.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/GLPainter.h>
#include <Gui/Selection.h>
#include <Gui/Utilities.h>
#include <Gui/MainWindow.h>
@ -931,10 +932,17 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
case STATUS_SKETCH_UseRubberBand: {
// a redraw is required in order to clear any previous rubberband
draw(true);
viewer->drawRect(prvCursorPos.getValue()[0],
viewer->getGLWidget()->height() - prvCursorPos.getValue()[1],
cursorPos.getValue()[0],
viewer->getGLWidget()->height() - cursorPos.getValue()[1]);
Gui::GLPainter p;
p.begin(viewer);
p.setColor(1.0, 1.0, 0.0, 0.0);
p.setLogicOp(GL_XOR);
p.setLineWidth(3.0f);
p.setLineStipple(2, 0x3F3F);
p.drawRect(prvCursorPos.getValue()[0],
viewer->getGLWidget()->height() - prvCursorPos.getValue()[1],
cursorPos.getValue()[0],
viewer->getGLWidget()->height() - cursorPos.getValue()[1]);
p.end();
return true;
}
default: