|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Glew include
|
|
Toshihiro Shimizu |
890ddd |
#include <gl glew.h=""></gl>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qcoreapplication></qcoreapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qthread></qthread>
|
|
Toshihiro Shimizu |
890ddd |
#include <qdatetime></qdatetime>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
#include <qopenglframebufferobject></qopenglframebufferobject>
|
|
Jeremy Bullock |
d165bb |
#include <qopenglshaderprogram></qopenglshaderprogram>
|
|
tomosu |
ac0809 |
#include <qopenglcontext></qopenglcontext>
|
|
Jeremy Bullock |
d165bb |
#include <qoffscreensurface></qoffscreensurface>
|
|
Jeremy Bullock |
d165bb |
#include <qopenglwidget></qopenglwidget>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include <map></map>
|
|
Toshihiro Shimizu |
890ddd |
#include <memory></memory>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx/shadingcontext.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local Namespace stuff
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
typedef std::unique_ptr<qopenglcontext> QOpenGLContextP;</qopenglcontext>
|
|
Jeremy Bullock |
d165bb |
typedef std::unique_ptr<qopenglframebufferobject> QOpenGLFramebufferObjectP;</qopenglframebufferobject>
|
|
Jeremy Bullock |
d165bb |
typedef std::unique_ptr<qopenglshaderprogram> QOpenGLShaderProgramP;</qopenglshaderprogram>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct CompiledShader {
|
|
Jeremy Bullock |
d165bb |
QOpenGLShaderProgramP m_program;
|
|
Shinya Kitaoka |
120a6e |
QDateTime m_lastModified;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
CompiledShader() {}
|
|
Shinya Kitaoka |
120a6e |
CompiledShader(const CompiledShader &) { assert(!m_program.get()); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
TQOpenGLWidget::TQOpenGLWidget() {}
|
|
Jeremy Bullock |
d165bb |
|
|
Jeremy Bullock |
d165bb |
void TQOpenGLWidget::initializeGL() {
|
|
shun_iwasawa |
339330 |
QOffscreenSurface *surface = new QOffscreenSurface();
|
|
shun_iwasawa |
339330 |
// context()->create();
|
|
shun_iwasawa |
339330 |
// context()->makeCurrent(surface);
|
|
Jeremy Bullock |
d165bb |
}
|
|
Jeremy Bullock |
d165bb |
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// ShadingContext::Imp definition
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct ShadingContext::Imp {
|
|
shun_iwasawa |
339330 |
QOpenGLContextP m_context; //!< OpenGL context.
|
|
shun_iwasawa |
339330 |
QOpenGLFramebufferObjectP m_fbo; //!< Output buffer.
|
|
Jeremy Bullock |
d165bb |
QOffscreenSurface *m_surface;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::map
|
|
Shinya Kitaoka |
120a6e |
CompiledShader>
|
|
Shinya Kitaoka |
120a6e |
m_shaderPrograms; //!< Shader Programs stored in the context.
|
|
Shinya Kitaoka |
2a7129 |
//! \warning Values have \p unique_ptr members.
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
static QSurfaceFormat format();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void initMatrix(int lx, int ly);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// Not copyable
|
|
Shinya Kitaoka |
120a6e |
Imp(const Imp &);
|
|
Shinya Kitaoka |
120a6e |
Imp &operator=(const Imp &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
339330 |
ShadingContext::Imp::Imp() : m_context(new QOpenGLContext()), m_surface() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
QSurfaceFormat ShadingContext::Imp::format() {
|
|
Jeremy Bullock |
d165bb |
QSurfaceFormat fmt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Shinya Kitaoka |
120a6e |
fmt.setVersion(3, 2);
|
|
Jeremy Bullock |
5b52af |
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fmt;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::Imp::initMatrix(int lx, int ly) {
|
|
Shinya Kitaoka |
120a6e |
glViewport(0, 0, lx, ly);
|
|
Shinya Kitaoka |
120a6e |
glMatrixMode(GL_PROJECTION);
|
|
Shinya Kitaoka |
120a6e |
glLoadIdentity();
|
|
Shinya Kitaoka |
120a6e |
gluOrtho2D(0, lx, 0, ly);
|
|
Shinya Kitaoka |
120a6e |
glMatrixMode(GL_MODELVIEW);
|
|
Shinya Kitaoka |
120a6e |
glLoadIdentity();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// ShadingContext implementation
|
|
Toshihiro Shimizu |
890ddd |
//*****************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
339330 |
ShadingContext::ShadingContext(QOffscreenSurface *surface) : m_imp(new Imp) {
|
|
shun_iwasawa |
339330 |
m_imp->m_surface = surface;
|
|
shun_iwasawa |
339330 |
m_imp->m_surface->create();
|
|
shun_iwasawa |
339330 |
QSurfaceFormat format;
|
|
shun_iwasawa |
339330 |
m_imp->m_context->setFormat(format);
|
|
shun_iwasawa |
339330 |
m_imp->m_context->create();
|
|
shun_iwasawa |
339330 |
m_imp->m_context->makeCurrent(m_imp->m_surface);
|
|
shun_iwasawa |
339330 |
|
|
shun_iwasawa |
339330 |
// m_imp->m_pixelBuffer->context()->create();
|
|
shun_iwasawa |
339330 |
// m_imp->m_fbo(new QOpenGLFramebufferObject(1, 1));
|
|
Shinya Kitaoka |
120a6e |
makeCurrent();
|
|
Shinya Kitaoka |
120a6e |
glewExperimental = GL_TRUE;
|
|
Shinya Kitaoka |
120a6e |
glewInit();
|
|
Shinya Kitaoka |
120a6e |
doneCurrent();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
tomosu |
ac0809 |
ShadingContext::~ShadingContext() {
|
|
shun-iwasawa |
27b0cf |
// Destructor of QGLPixelBuffer calls QOpenGLContext::makeCurrent()
|
|
shun-iwasawa |
27b0cf |
// internally,
|
|
tomosu |
ac0809 |
// so the current thread must be the owner of QGLPixelBuffer context,
|
|
tomosu |
ac0809 |
// when the destructor of m_imp->m_context is called.
|
|
![](https://seccdn.libravatar.org/avatar/2e5dd0bee1e7e619066117de357c8458fc7e847f4345b0cb8a7a5413aa2a45a0?d=retro&s=16) |
1213cf |
m_imp->m_context->moveToThread(QThread::currentThread());
|
|
tomosu |
ac0809 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ShadingContext::Support ShadingContext::support() {
|
|
shun_iwasawa |
339330 |
// return !QGLPixelBuffer::hasOpenGLPbuffers()
|
|
Jeremy Bullock |
d165bb |
// ? NO_PIXEL_BUFFER
|
|
shun_iwasawa |
339330 |
// : !QOpenGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS :
|
|
shun_iwasawa |
339330 |
// OK;
|
|
shun_iwasawa |
339330 |
return !QOpenGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : OK;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
bool ShadingContext::isValid() const { return m_imp->m_context->isValid(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
QGLFormat ShadingContext::defaultFormat(int channelsSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QGL::FormatOptions opts =
|
|
Toshihiro Shimizu |
890ddd |
QGL::SingleBuffer |
|
|
Toshihiro Shimizu |
890ddd |
QGL::NoAccumBuffer |
|
|
Shinya Kitaoka |
120a6e |
QGL::NoDepthBuffer | // I guess it could be
|
|
Shinya Kitaoka |
120a6e |
necessary to let at least
|
|
Shinya Kitaoka |
120a6e |
QGL::NoOverlay | // the depth buffer
|
|
Shinya Kitaoka |
120a6e |
enabled... Fragment shaders could
|
|
Toshihiro Shimizu |
890ddd |
QGL::NoSampleBuffers | // use it...
|
|
Toshihiro Shimizu |
890ddd |
QGL::NoStencilBuffer |
|
|
Toshihiro Shimizu |
890ddd |
QGL::NoStereoBuffers;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QGLFormat fmt(opts);
|
|
Shinya Kitaoka |
120a6e |
fmt.setDirectRendering(true); // Just to be explicit -
|
|
Shinya Kitaoka |
120a6e |
USE HARDWARE ACCELERATION
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fmt.setRedBufferSize(channelsSize);
|
|
Toshihiro Shimizu |
890ddd |
fmt.setGreenBufferSize(channelsSize);
|
|
Toshihiro Shimizu |
890ddd |
fmt.setBlueBufferSize(channelsSize);
|
|
Toshihiro Shimizu |
890ddd |
fmt.setAlphaBufferSize(channelsSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TODO: 64-bit mode should be settable here
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return fmt;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
tomosu |
ac0809 |
void ShadingContext::makeCurrent() {
|
|
shun_iwasawa |
339330 |
m_imp->m_context->moveToThread(QThread::currentThread());
|
|
![](https://seccdn.libravatar.org/avatar/2e5dd0bee1e7e619066117de357c8458fc7e847f4345b0cb8a7a5413aa2a45a0?d=retro&s=16) |
1213cf |
m_imp->m_context.reset(new QOpenGLContext());
|
|
shun_iwasawa |
339330 |
QSurfaceFormat format;
|
|
shun_iwasawa |
339330 |
m_imp->m_context->setFormat(format);
|
|
shun_iwasawa |
339330 |
m_imp->m_context->create();
|
|
shun_iwasawa |
339330 |
m_imp->m_context->makeCurrent(m_imp->m_surface);
|
|
tomosu |
ac0809 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
tomosu |
ac0809 |
void ShadingContext::doneCurrent() {
|
|
![](https://seccdn.libravatar.org/avatar/2e5dd0bee1e7e619066117de357c8458fc7e847f4345b0cb8a7a5413aa2a45a0?d=retro&s=16) |
1213cf |
m_imp->m_context->moveToThread(0);
|
|
Jeremy Bullock |
d165bb |
m_imp->m_context->doneCurrent();
|
|
tomosu |
ac0809 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::resize(int lx, int ly,
|
|
Jeremy Bullock |
d165bb |
const QOpenGLFramebufferObjectFormat &fmt) {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_fbo.get() && m_imp->m_fbo->width() == lx &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_fbo->height() == ly && m_imp->m_fbo->format() == fmt)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (lx == 0 || ly == 0) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_fbo.reset(0);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
shun_iwasawa |
339330 |
bool get = m_imp->m_fbo.get();
|
|
shun_iwasawa |
339330 |
QOpenGLContext *currContext = m_imp->m_context->currentContext();
|
|
shun_iwasawa |
339330 |
bool yes = false;
|
|
shun_iwasawa |
339330 |
if (currContext) bool yes = true;
|
|
shun_iwasawa |
339330 |
while (!currContext) currContext = m_imp->m_context->currentContext();
|
|
shun_iwasawa |
339330 |
m_imp->m_fbo.reset(new QOpenGLFramebufferObject(lx, ly, fmt));
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_fbo->isValid());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_fbo->bind();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
QOpenGLFramebufferObjectFormat ShadingContext::format() const {
|
|
Jeremy Bullock |
d165bb |
QOpenGLFramebufferObject *fbo = m_imp->m_fbo.get();
|
|
Jeremy Bullock |
d165bb |
return fbo ? m_imp->m_fbo->format() : QOpenGLFramebufferObjectFormat();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDimension ShadingContext::size() const {
|
|
Jeremy Bullock |
d165bb |
QOpenGLFramebufferObject *fbo = m_imp->m_fbo.get();
|
|
Shinya Kitaoka |
120a6e |
return fbo ? TDimension(fbo->width(), fbo->height()) : TDimension();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::addShaderProgram(const QString &shaderName,
|
|
Jeremy Bullock |
d165bb |
QOpenGLShaderProgram *program) {
|
|
Shinya Kitaoka |
120a6e |
std::map<qstring, compiledshader="">::iterator st =</qstring,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_shaderPrograms
|
|
Shinya Kitaoka |
120a6e |
.insert(std::make_pair(shaderName, CompiledShader()))
|
|
Shinya Kitaoka |
120a6e |
.first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
st->second.m_program.reset(program);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::addShaderProgram(const QString &shaderName,
|
|
Jeremy Bullock |
d165bb |
QOpenGLShaderProgram *program,
|
|
Shinya Kitaoka |
120a6e |
const QDateTime &lastModified) {
|
|
Shinya Kitaoka |
120a6e |
std::map<qstring, compiledshader="">::iterator st =</qstring,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_shaderPrograms
|
|
Shinya Kitaoka |
120a6e |
.insert(std::make_pair(shaderName, CompiledShader()))
|
|
Shinya Kitaoka |
120a6e |
.first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
st->second.m_program.reset(program);
|
|
Shinya Kitaoka |
120a6e |
st->second.m_lastModified = lastModified;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool ShadingContext::removeShaderProgram(const QString &shaderName) {
|
|
Shinya Kitaoka |
120a6e |
return (m_imp->m_shaderPrograms.erase(shaderName) > 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
QOpenGLShaderProgram *ShadingContext::shaderProgram(
|
|
Shinya Kitaoka |
120a6e |
const QString &shaderName) const {
|
|
Shinya Kitaoka |
120a6e |
std::map<qstring, compiledshader="">::iterator st =</qstring,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_shaderPrograms.find(shaderName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (st != m_imp->m_shaderPrograms.end()) ? st->second.m_program.get() : 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QDateTime ShadingContext::lastModified(const QString &shaderName) const {
|
|
Shinya Kitaoka |
120a6e |
std::map<qstring, compiledshader="">::iterator st =</qstring,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_shaderPrograms.find(shaderName);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (st != m_imp->m_shaderPrograms.end()) ? st->second.m_lastModified
|
|
Shinya Kitaoka |
120a6e |
: QDateTime();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
d165bb |
std::pair<qopenglshaderprogram *,="" qdatetime=""> ShadingContext::shaderData(</qopenglshaderprogram>
|
|
Shinya Kitaoka |
120a6e |
const QString &shaderName) const {
|
|
Shinya Kitaoka |
120a6e |
std::map<qstring, compiledshader="">::iterator st =</qstring,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_shaderPrograms.find(shaderName);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (st != m_imp->m_shaderPrograms.end())
|
|
Shinya Kitaoka |
120a6e |
? std::make_pair(st->second.m_program.get(),
|
|
Shinya Kitaoka |
120a6e |
st->second.m_lastModified)
|
|
Jeremy Bullock |
d165bb |
: std::make_pair((QOpenGLShaderProgram *)0, QDateTime());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLuint ShadingContext::loadTexture(const TRasterP &src, GLuint texUnit) {
|
|
Shinya Kitaoka |
120a6e |
glActiveTexture(GL_TEXTURE0 + texUnit);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLuint texId;
|
|
Shinya Kitaoka |
120a6e |
glGenTextures(1, &texId);
|
|
Shinya Kitaoka |
120a6e |
glBindTexture(GL_TEXTURE_2D, texId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
|
Shinya Kitaoka |
120a6e |
GL_CLAMP); // These must be used on a bound texture,
|
|
Shinya Kitaoka |
120a6e |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
|
Shinya Kitaoka |
120a6e |
GL_CLAMP); // and are remembered in the OpenGL context.
|
|
Shinya Kitaoka |
120a6e |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
Shinya Kitaoka |
120a6e |
GL_NEAREST); // They can be set here, no need for
|
|
Shinya Kitaoka |
120a6e |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
Shinya Kitaoka |
120a6e |
GL_NEAREST); // the user to do it.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPixelStorei(GL_UNPACK_ROW_LENGTH, src->getWrap());
|
|
Shinya Kitaoka |
120a6e |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLenum chanType = TRaster32P(src) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glTexImage2D(GL_TEXTURE_2D,
|
|
Shinya Kitaoka |
120a6e |
0, // one level only
|
|
Shinya Kitaoka |
120a6e |
GL_RGBA, // pixel channels count
|
|
Shinya Kitaoka |
120a6e |
src->getLx(), // width
|
|
Shinya Kitaoka |
120a6e |
src->getLy(), // height
|
|
Shinya Kitaoka |
120a6e |
0, // border size
|
|
Shinya Kitaoka |
120a6e |
TGL_FMT, // pixel format
|
|
Shinya Kitaoka |
120a6e |
chanType, // channel data type
|
|
Shinya Kitaoka |
120a6e |
(GLvoid *)src->getRawData());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == GL_NO_ERROR);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return texId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::unloadTexture(GLuint texId) {
|
|
Shinya Kitaoka |
120a6e |
glDeleteTextures(1, &texId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::draw(const TRasterP &dst) {
|
|
Shinya Kitaoka |
120a6e |
assert("ShadingContext::resize() must be invoked at least once before this" &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_fbo.get());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int lx = dst->getLx(),
|
|
Shinya Kitaoka |
120a6e |
ly = dst->getLy(); // NOTE: We're not using m_imp->m_fbo's size, since
|
|
Shinya Kitaoka |
120a6e |
// it could be possibly greater than the required
|
|
Shinya Kitaoka |
120a6e |
// destination surface.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->initMatrix(lx, ly); // This call sets the OpenGL viewport to this
|
|
Shinya Kitaoka |
120a6e |
// size - and matches (1, 1) to dst's (lx, ly)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_QUADS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glVertex2f(0.0, 0.0);
|
|
Shinya Kitaoka |
120a6e |
glVertex2f(lx, 0.0);
|
|
Shinya Kitaoka |
120a6e |
glVertex2f(lx, ly);
|
|
Shinya Kitaoka |
120a6e |
glVertex2f(0.0, ly);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPixelStorei(GL_PACK_ROW_LENGTH, dst->getWrap());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Read the fbo to dst
|
|
Shinya Kitaoka |
120a6e |
if (TRaster32P ras32 = dst)
|
|
Shinya Kitaoka |
120a6e |
glReadPixels(0, 0, lx, ly, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
|
|
Shinya Kitaoka |
120a6e |
dst->getRawData());
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
assert(TRaster64P(dst));
|
|
Shinya Kitaoka |
120a6e |
glReadPixels(0, 0, lx, ly, GL_BGRA_EXT, GL_UNSIGNED_SHORT,
|
|
Shinya Kitaoka |
120a6e |
dst->getRawData());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == GL_NO_ERROR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ShadingContext::transformFeedback(int varyingsCount,
|
|
Shinya Kitaoka |
120a6e |
const GLsizeiptr *varyingSizes,
|
|
Shinya Kitaoka |
120a6e |
GLvoid **bufs) {
|
|
Shinya Kitaoka |
120a6e |
// Generate buffer objects
|
|
Shinya Kitaoka |
120a6e |
std::vector<gluint> bufferObjectNames(varyingsCount, 0);</gluint>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glGenBuffers(varyingsCount, &bufferObjectNames[0]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int v = 0; v != varyingsCount; ++v) {
|
|
Shinya Kitaoka |
120a6e |
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNames[v]);
|
|
Shinya Kitaoka |
120a6e |
glBufferData(GL_ARRAY_BUFFER, varyingSizes[v], bufs[v], GL_STATIC_READ);
|
|
Shinya Kitaoka |
120a6e |
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, v, bufferObjectNames[v]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw
|
|
Shinya Kitaoka |
120a6e |
GLuint Query = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glGenQueries(1, &Query);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// Disable rasterization, vertices processing only!
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_RASTERIZER_DISCARD);
|
|
Shinya Kitaoka |
120a6e |
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, Query);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBeginTransformFeedback(GL_POINTS);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_POINTS);
|
|
Shinya Kitaoka |
120a6e |
glVertex2f(0.0f, 0.0f);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glEndTransformFeedback();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_RASTERIZER_DISCARD);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLint count = 0;
|
|
Shinya Kitaoka |
120a6e |
glGetQueryObjectiv(Query, GL_QUERY_RESULT, &count);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glDeleteQueries(1, &Query);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve transformed data
|
|
Shinya Kitaoka |
120a6e |
for (int v = 0; v != varyingsCount; ++v) {
|
|
Shinya Kitaoka |
120a6e |
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNames[v]);
|
|
Shinya Kitaoka |
120a6e |
glGetBufferSubData(GL_ARRAY_BUFFER, 0, varyingSizes[v], bufs[v]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Delete buffer objects
|
|
Shinya Kitaoka |
120a6e |
glDeleteBuffers(varyingsCount, &bufferObjectNames[0]);
|
|
Toshihiro Shimizu |
890ddd |
}
|