Tessellation QShader Support
-
Perhaps it's included in Qt/3d?
-
-
I might be tired but it looks like VAOs are not supported in regular Qt?
I was coding an example for tessellation I found on the web to use with the shaders added so I could test it. It seems from the Qt source files the functionality mapped for VAOs but I haven't been able to dig through the #define guards yet.
Any advice?
-
That's interesting, thank you. The problem I'm having is a compile error. All of the identifiers are defined in Qt headers but they are surrounded by preprocessor guards I haven't tracked down yet.
1>.\gltarget.cpp(119) : error C3861: 'glGenVertexArrays': identifier not found
1>.\gltarget.cpp(120) : error C3861: 'glBindVertexArray': identifier not found
1>.\gltarget.cpp(125) : error C3861: 'glGenBuffers': identifier not found
1>.\gltarget.cpp(126) : error C2065: 'GL_ARRAY_BUFFER' : undeclared identifier
1>.\gltarget.cpp(126) : error C3861: 'glBindBuffer': identifier not found
1>.\gltarget.cpp(127) : error C2065: 'GL_ARRAY_BUFFER' : undeclared identifier
1>.\gltarget.cpp(127) : error C2065: 'GL_STATIC_DRAW' : undeclared identifier
1>.\gltarget.cpp(127) : error C3861: 'glBufferData': identifier not found
1>.\gltarget.cpp(128) : error C2065: 'PositionSlot' : undeclared identifier
1>.\gltarget.cpp(128) : error C3861: 'glEnableVertexAttribArray': identifier not found
1>.\gltarget.cpp(129) : error C2065: 'PositionSlot' : undeclared identifier
1>.\gltarget.cpp(129) : error C3861: 'glVertexAttribPointer': identifier not found
1>.\gltarget.cpp(133) : error C3861: 'glGenBuffers': identifier not found
1>.\gltarget.cpp(134) : error C2065: 'GL_ELEMENT_ARRAY_BUFFER' : undeclared identifier
1>.\gltarget.cpp(134) : error C3861: 'glBindBuffer': identifier not found
1>.\gltarget.cpp(135) : error C2065: 'GL_ELEMENT_ARRAY_BUFFER' : undeclared identifier
1>.\gltarget.cpp(135) : error C2065: 'GL_STATIC_DRAW' : undeclared identifier
1>.\gltarget.cpp(135) : error C3861: 'glBufferData': identifier not found -
Here's some code. I know you shouldn't create shaders in your paint call but I was doing this only to test that I could use the ones I added.
Keep in mind this code was made for that purpose and is only half-written and it's scattered (it's R&D code).
I think I can use QGLBuffer to duplicate the buffer code.
@#include "gltarget.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <QGLShaderProgram>glTarget::glTarget(const QGLFormat& format, QWidget* parent) : QGLWidget(format,parent)
,m_shaderProgram(this)
{}
glTarget::~glTarget()
{}
void glTarget::initializeGL()
{glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glm::perspective(60.0f, (float)800 / (float)600, 0.1f, 100.f);}
void glTarget::resizeGL(int w, int h)
{
glViewport(0,0, (GLint)w, (GLint)h);
}void glTarget::paintGL()
{bool result = false;
QGLShader* vertexPassThrough = new QGLShader(QGLShader::Vertex, this);
result = vertexPassThrough->compileSourceFile("vertexpassthrough.glsl");
m_vertexShaders["PassThrough"] = vertexPassThrough;
result = m_shaderProgram.addShader(vertexPassThrough);QGLShader* fragmentPassThrough = new QGLShader(QGLShader::Fragment, this);
result = fragmentPassThrough->compileSourceFile("fragmentpassthrough.glsl");
m_fragmentShaders["PassThrough"] = fragmentPassThrough;
result = m_shaderProgram.addShader(fragmentPassThrough);QGLShader* geometry = new QGLShader(QGLShader::Geometry, this);
result = geometry->compileSourceFile("geometry.glsl");
m_shaderProgram.addShader(geometry);QGLShader* tessControl = new QGLShader(QGLShader::TessControl, this);
result = tessControl->compileSourceFile("tesscontrol.glsl");
m_shaderProgram.addShader(tessControl);QGLShader* tessEval = new QGLShader(QGLShader::TessEvaluation, this);
result = tessEval->compileSourceFile("tesseval.glsl");
m_shaderProgram.addShader(tessEval); //Just added this because I noticed it missing from post (tested it too)m_shaderProgram.link();
m_shaderProgram.bind();glViewport(0, 0, 800, 600); // Set the viewport size to fill the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffersviewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.f)); // Create our view matrix
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); // Create our model matrixm_shaderProgram.release();
}void glTarget::CreateIcosahedron()
{
const int Faces[] = {
2, 1, 0,
3, 2, 0,
4, 3, 0,
5, 4, 0,
1, 5, 0,11, 6, 7, 11, 7, 8, 11, 8, 9, 11, 9, 10, 11, 10, 6, 1, 2, 6, 2, 3, 7, 3, 4, 8, 4, 5, 9, 5, 1, 10, 2, 7, 6, 3, 8, 7, 4, 9, 8, 5, 10, 9, 1, 6, 10 }; const float Verts[] = { 0.000f, 0.000f, 1.000f, 0.894f, 0.000f, 0.447f, 0.276f, 0.851f, 0.447f, -0.724f, 0.526f, 0.447f, -0.724f, -0.526f, 0.447f, 0.276f, -0.851f, 0.447f, 0.724f, 0.526f, -0.447f, -0.276f, 0.851f, -0.447f, -0.894f, 0.000f, -0.447f, -0.276f, -0.851f, -0.447f, 0.724f, -0.526f, -0.447f, 0.000f, 0.000f, -1.000f };
// IndexCount = sizeof(Faces) / sizeof(Faces[0]);
QGLWidget::makeCurrent();
// Create the VAO:
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);// Create the VBO for positions: GLuint positions; GLsizei stride = 3 * sizeof(float); glGenBuffers(1, &positions); glBindBuffer(GL_ARRAY_BUFFER, positions); glBufferData(GL_ARRAY_BUFFER, sizeof(Verts), Verts, GL_STATIC_DRAW); glEnableVertexAttribArray(PositionSlot); glVertexAttribPointer(PositionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0); // Create the VBO for indices: GLuint indices; glGenBuffers(1, &indices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Faces), Faces, GL_STATIC_DRAW);
}
Header
#ifndef GLTARGET_H
#define GLTARGET_H#include <QGLWidget>
#include <QGLFormat>
#include <QGLShaderProgram>
#include <QGLShader>
#include <QHash>
#include <glm/gtc/matrix_transform.hpp>class glTarget : public QGLWidget
{
Q_OBJECT
public:
glTarget(const QGLFormat& format, QWidget* parent = 0);
~glTarget();void CreateIcosahedron();
protected:
glm::mat4 projectionMatrix; // Store the projection matrix
glm::mat4 viewMatrix; // Store the view matrix
glm::mat4 modelMatrix; // Store the model matrixQGLShaderProgram m_shaderProgram;
QHash<QString, QGLShader*> m_vertexShaders;
QHash<QString, QGLShader*> m_fragmentShaders;
QHash<QString, QGLShader*> m_geometryShaders;void initializeGL();
void resizeGL(int w, int h);
void paintGL();
};
#endif
Finally, how I set up the format.
QGLFormat format;
format.setVersion(4,0);
format.setProfile(QGLFormat::CoreProfile);
QGLFormat::setDefaultFormat(format);
QGLContext* context = new QGLContext(format);
bool test = context->isValid();m_target = new glTarget(format, parent);
this->setCentralWidget(m_target);@
-
OK, you need to add the glew header to the very top of your .cpp file:
@
#include <GL/glew.h>#include "gltarget.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <QGLShaderProgram>
...
@It needs to be included before <QGLWidget> (ie before GL/gl.h) otherwise you will get a compile error.
You can then also call glewInit() and check that OpenGL 3.0 is supported or not:
@
if ( glewInit() != GLEW_OK )
qDebug() << "Can't initialize glew";
if ( ! GLEW_VERSION_3_0 )
{
qDebug() << "OpenGL version 3 is not supported";
exit( 1 );
}
@Hopefully that willl get you going.
-
Hi,
[quote author="Michael Goddard" date="1300234191"]Perhaps it's included in Qt/3d?
http://qt.gitorious.org/qt-labs/qt3d
[/quote]
We don't have support for TC or TE shaders in Qt3D. We do have a lot of plans for future development but we have to look at things that have broad support on platforms.
[quote author="Hornsj2" date="1300273855"]It looks to be implied that there may be some plan to merge Qt/3D with Qt. I base that only on the language they use when describing Qt/3D, so that may be totally bogus.[/quote]
QGLShaderProgram originally came from Qt3D and was brought over with some other classes into Qt proper. There should be a few more classes like this - our so called "Enablers". But at present, despite our earlier plans, it looks doubtful that we will merge large parts of Qt3D into Qt. Mostly this is because of the "modularisation effort in Qt":http://labs.qt.nokia.com/2011/01/21/status-of-qt-modularization/
Qt's QGLShader* classes now support geometry shaders, but in reality they don't get much use - I don't think anything in Qt uses them, and I don't see any examples or demos there. We mostly focus on OpenGL 2 and ES 2 as the lowest common denominator - and of course OpenGL ES 1.x is still popular and supported.
Qt3D does help you out a lot with VBO's and also with the resolving of extensions. We do support calling gl functions as well. Check "the documentation":http://doc.qt.nokia.com/qt3d-snapshot/ for details.
If TE and TC shader support was going to be added, it probably really ought to be done in Qt rather than Qt3D. Then Qt3D would really need to have some changes to its VBO support to make it easier to work with the control data and so on. Its not a big thing to do. You could request it as a suggestion on "the bug system":http://bugreports.qt.nokia.com.
-
I added it in Qt. I'm pretty confident it works because the shaders compile and link. However, I haven't had time to get a test harness working. I haven't touched OpenGL since before 3 so I'm learning the shader only model & writing the harness.
Like I say above, I can post the source files with the changes somewhere if someone wants to build them into their QtOpengl project and write a harness.
I will hopefully have tested it by this weekend.