code is all clean now (but still broken)

This commit is contained in:
ccolin 2021-10-02 22:51:20 +02:00
parent d74f80530b
commit 7601caaada
9 changed files with 124 additions and 173 deletions

6
resources.qrc Normal file
View File

@ -0,0 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="shader.vert">src/shader.vert</file>
<file alias="shader.frag">src/shader.frag</file>
</qresource>
</RCC>

View File

@ -8,9 +8,11 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
using namespace std; using namespace std;
QSurfaceFormat format; QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::RenderableType::OpenGL); format.setRenderableType(QSurfaceFormat::OpenGL);
format.setMajorVersion(2); #ifndef QT_DEBUG
format.setMinorVersion(1); qDebug("Debug build");
format.setOption(QSurfaceFormat::DebugContext);
#endif
QSurfaceFormat::setDefaultFormat(format); QSurfaceFormat::setDefaultFormat(format);
QApplication app(argc, argv); QApplication app(argc, argv);
MeshProcessor *mesh_processor = nullptr; MeshProcessor *mesh_processor = nullptr;

View File

@ -1,14 +1,12 @@
#include "mesh_view.h" #include "mesh_view.h"
#include <QOpenGLFunctions_2_1> #include <QOpenGLContext>
MeshView::MeshView(QOpenGLExtraFunctions *glf, const MyMesh &mesh, MeshView::MeshView(const MyMesh &mesh, QOpenGLShaderProgram &program)
int pos_attr, int col_attr) : buffer(QOpenGLBuffer::VertexBuffer),
: glf(glf),
mesh(mesh) { mesh(mesh) {
GLfloat *verts = new GLfloat[mesh.n_faces() * 3 * 6]; GLfloat *verts = new GLfloat[mesh.n_faces() * 3 * 6];
size_t i = 0; size_t i = 0;
for (const FaceHandle face : mesh.faces()) { for (const FaceHandle face : mesh.faces()) {
for (const VertexHandle vec : mesh.fv_range(face)) { for (const VertexHandle vec : mesh.fv_range(face)) {
verts[6*i + 0] = mesh.point(vec)[0]; verts[6*i + 0] = mesh.point(vec)[0];
@ -21,53 +19,50 @@ MeshView::MeshView(QOpenGLExtraFunctions *glf, const MyMesh &mesh,
} }
} }
delete[] verts; vao.create();
{QOpenGLVertexArrayObject::Binder binder(&vao);
GLuint vao, vbo; buffer.create();
glf->glGenVertexArrays(1, &vao); buffer.bind();
glf->glGenBuffers(1, &vbo); buffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
buffer.allocate(verts, nverts * 6 * sizeof (GLfloat));
glf->glBindVertexArray(vao); delete[] verts;
glf->glBindBuffer(GL_ARRAY_BUFFER, vbo); program.setAttributeBuffer("pos", GL_FLOAT, 0, 3, 6 * sizeof (GLfloat));
glf->glBufferData(GL_ARRAY_BUFFER, nverts * 6 * sizeof (GLfloat), verts, GL_DYNAMIC_DRAW); program.enableAttributeArray("pos");
glf->glVertexAttribPointer(pos_attr, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (GLfloat), 0); program.setAttributeBuffer("col", GL_FLOAT, 3 * sizeof (GLfloat), 3, 6 * sizeof (GLfloat));
glf->glEnableVertexAttribArray(pos_attr); program.enableAttributeArray("col");
glf->glVertexAttribPointer(col_attr, 3, GL_FLOAT, GL_FALSE, 6 * sizeof (GLfloat), }
(const void *) (3 * sizeof (GLfloat)));
glf->glEnableVertexAttribArray(col_attr);
glf->glBindVertexArray(0);
} }
MeshView::~MeshView() { MeshView::~MeshView() {
glf->glDeleteVertexArrays(1, &vao); vao.destroy();
glf->glDeleteBuffers(1, &vbo); buffer.destroy();
} }
void MeshView::paint(QOpenGLContext *ctx, void MeshView::paint(QOpenGLShaderProgram &program) {
int model_attr, int wireframe_attr) const { QOpenGLContext *ctx = QOpenGLContext::currentContext();
QOpenGLExtraFunctions *glf = ctx->extraFunctions();
void (*glPolygonMode)(GLenum, GLenum) = nullptr; void (*glPolygonMode)(GLenum, GLenum) = nullptr;
glPolygonMode = (typeof glPolygonMode) ctx->getProcAddress("glPolygonMode"); glPolygonMode = (typeof glPolygonMode) ctx->getProcAddress("glPolygonMode");
if (!glPolygonMode) if (!glPolygonMode)
qWarning("glPolygonMode not available"); qWarning("glPolygonMode not available");
glf->glUniformMatrix4fv(model_attr, 1, GL_FALSE, program.setUniformValue("model", mesh.transform);
mesh.transform.constData());
/* Mesh */ {QOpenGLVertexArrayObject::Binder binder(&vao);
glf->glBindVertexArray(vao); /* Mesh */
glf->glEnable(GL_POLYGON_OFFSET_FILL); glf->glEnable(GL_POLYGON_OFFSET_FILL);
glf->glPolygonOffset(1.0, 2); glf->glPolygonOffset(1.0, 2);
glf->glDrawArrays(GL_TRIANGLES, 0, nverts); glf->glDrawArrays(GL_TRIANGLES, 0, nverts);
if (glPolygonMode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (glPolygonMode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glf->glDisable(GL_POLYGON_OFFSET_FILL); glf->glDisable(GL_POLYGON_OFFSET_FILL);
/* Wireframe */ /* Wireframe */
glf->glUniform1f(wireframe_attr, 1); program.setUniformValue("wireframe", 1);
glf->glDrawArrays(GL_TRIANGLES, 0, nverts); glf->glDrawArrays(GL_TRIANGLES, 0, nverts);
if (glPolygonMode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (glPolygonMode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glf->glLineWidth(3); glf->glLineWidth(3);
glf->glUniform1f(wireframe_attr, 0); program.setUniformValue("wireframe", 1);
}
} }

View File

@ -3,23 +3,22 @@
#include "my_mesh.h" #include "my_mesh.h"
#include <QOpenGLExtraFunctions> #include <QOpenGLExtraFunctions>
#include <QOpenGLContext> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
class MeshView { class MeshView {
GLuint vao; QOpenGLVertexArrayObject vao;
GLuint vbo; QOpenGLBuffer buffer;
size_t nverts; size_t nverts;
QOpenGLExtraFunctions *glf;
public: public:
const MyMesh &mesh; const MyMesh &mesh;
MeshView(QOpenGLExtraFunctions *glf, const MyMesh &mesh, MeshView(const MyMesh &mesh, QOpenGLShaderProgram &program);
int pos_attr, int col_attr);
~MeshView(); ~MeshView();
void paint(QOpenGLContext *ctx, void paint(QOpenGLShaderProgram &program);
int model_attr, int wireframe_attr) const;
}; };

View File

@ -1,40 +1,9 @@
#include "mesh_viewer.h" #include "mesh_viewer.h"
#include <tgmath.h> #include <tgmath.h>
#include <algorithm> #include <QOpenGLShader>
#include <QOpenGLDebugLogger>
#include <QtGlobal>
const GLchar *vertex_shader_source = R"glsl(
attribute vec3 pos;
attribute vec3 col;
varying vec3 frag_col;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model;
void main() {
gl_Position = proj * view * model * vec4(pos, 1.0);
frag_col = col;
}
)glsl";
const GLchar *fragment_shader_source = R"glsl(
varying vec3 frag_col;
uniform vec3 wf_col;
uniform bool wireframe;
uniform float alpha;
void main() {
if (!wireframe)
// gl_FragColor = vec4(wf_col, alpha);
gl_FragColor = vec4(.5, .5, .5, 1);
else
gl_FragColor = vec4(frag_col, alpha);
}
)glsl";
MeshViewer::MeshViewer(QWidget *parent) : QOpenGLWidget(parent) { MeshViewer::MeshViewer(QWidget *parent) : QOpenGLWidget(parent) {
@ -48,96 +17,49 @@ QSize MeshViewer::sizeHint() const {
} }
void GLAPIENTRY
opengl_debug_cb(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam) {
(void) source;
(void) type;
(void) id;
(void) severity;
(void) length;
(void) userParam;
qDebug() << "OpenGL debug output:" << message;
}
void MeshViewer::initializeGL() { void MeshViewer::initializeGL() {
// initializeOpenGLFunctions(); QOpenGLFunctions *glf = context()->functions();
#ifdef QT_DEBUG
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this);
if (!logger->initialize()) {
qDebug("OpenGL debug output unavailable");
}
connect(logger, &QOpenGLDebugLogger::messageLogged,
[](const QOpenGLDebugMessage &message) {
qDebug() << "OpenGL: " << message.message();
});
logger->startLogging();
#endif
qDebug("OpenGL version %d.%d", QOpenGLShader vertex_shader(QOpenGLShader::Vertex);
context()->format().majorVersion(), if (!vertex_shader.compileSourceFile(":/shader.vert")) {
context()->format().minorVersion()); qCritical() << vertex_shader.log();
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(opengl_debug_cb, 0);
/* Compile the vertex shader. */
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
GLint status;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char log[1024];
glGetShaderInfoLog(vertex_shader, sizeof log, NULL, log);
fprintf(stderr, "Failed to compile the vertex shader: %s\n", log);
exit(1);
} }
/* Compile the fragment shader. */ QOpenGLShader fragment_shader(QOpenGLShader::Fragment);
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); if (fragment_shader.compileSourceFile(":/shader.frag")) {
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); qCritical() << fragment_shader.log();
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char log[1024];
glGetShaderInfoLog(fragment_shader, sizeof log, NULL, log);
fprintf(stderr, "Failed to compile the fragment shader: %s\n", log);
exit(1);
} }
if (!program.addShader(&vertex_shader)) {
/* Link the shader program. */ qCritical() << program.log();
GLuint shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glBindFragDataLocation(shader_program, 0, "out_color");
glLinkProgram(shader_program);
glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
char log[1024];
glGetProgramInfoLog(shader_program, sizeof log, NULL, log);
fprintf(stderr, "Failed to link the shader program: %s\n", log);
exit(1);
} }
if (!program.addShader(&fragment_shader)) {
qCritical() << program.log();
}
if (!program.link()) {
qCritical() << program.log();
}
program.bind();
/* Use it. */ program.setUniformValue("alpha", (GLfloat) 1);
glUseProgram(shader_program); program.setUniformValue("wf_col", WIREFRAME_COLOR);
/* Get the position attribute. */ glf->glClearColor(1, 1, 1, 0);
pos_attr = glGetAttribLocation(shader_program, "pos");
col_attr = glGetAttribLocation(shader_program, "col");
proj_attr = glGetUniformLocation(shader_program, "proj"); glf->glEnable(GL_DEPTH_TEST);
view_attr = glGetUniformLocation(shader_program, "view"); glf->glEnable(GL_MULTISAMPLE);
model_attr = glGetUniformLocation(shader_program, "model");
wf_col_attr = glGetUniformLocation(shader_program, "wf_col");
wireframe_attr = glGetUniformLocation(shader_program, "wireframe");
alpha_attr = glGetUniformLocation(shader_program, "alpha");
glUniform1f(alpha_attr, 1); qDebug("Mesh viewer: initialization complete");
glUniform3f(wf_col_attr, WIREFRAME_COLOR);
glClearColor(1, 1, 1, 0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
qDebug("Mesh viewer initialized");
emit initialized(); emit initialized();
} }
@ -145,7 +67,7 @@ void MeshViewer::initializeGL() {
void MeshViewer::resizeGL(int w, int h) { void MeshViewer::resizeGL(int w, int h) {
QMatrix4x4 projection; QMatrix4x4 projection;
projection.perspective(FOV, (float) w/h, .01, 100); projection.perspective(FOV, (float) w/h, .01, 100);
glUniformMatrix4fv(proj_attr, 1, GL_FALSE, projection.data()); program.setUniformValue("proj", projection);
} }
@ -154,17 +76,17 @@ void MeshViewer::paintGL() {
QMatrix4x4 trans; QMatrix4x4 trans;
trans.translate(0, 0, -cam_dist); trans.translate(0, 0, -cam_dist);
QMatrix4x4 view = trans * rot; QMatrix4x4 view = trans * rot;
glUniformMatrix4fv(view_attr, 1, GL_FALSE, view.data()); program.setUniformValue("view", view);
for (const MeshView m : meshes) { for (MeshView &m : meshes) {
m.paint(context(), model_attr, wireframe_attr); m.paint(program);
} }
} }
void MeshViewer::addMesh(const MyMesh &mesh) { void MeshViewer::addMesh(const MyMesh &mesh) {
Q_ASSERT(isValid());
makeCurrent(); makeCurrent();
meshes.emplace_back(context()->extraFunctions(), mesh, meshes.emplace_back(mesh, program);
pos_attr, col_attr);
doneCurrent(); doneCurrent();
update(); update();
} }

View File

@ -25,8 +25,7 @@ class MeshViewer : public QOpenGLWidget {
Q_OBJECT Q_OBJECT
std::list<MeshView> meshes; std::list<MeshView> meshes;
GLint pos_attr, col_attr, proj_attr, view_attr, model_attr; QOpenGLShaderProgram program;
GLint wf_col_attr, wireframe_attr, alpha_attr;
QMatrix4x4 proj; QMatrix4x4 proj;
QMatrix4x4 rot, rot_start; QMatrix4x4 rot, rot_start;
GLfloat cam_dist = 1; GLfloat cam_dist = 1;

13
src/shader.frag Normal file
View File

@ -0,0 +1,13 @@
varying vec3 frag_col;
uniform vec3 wf_col;
uniform bool wireframe;
uniform float alpha;
void main() {
if (!wireframe)
// gl_FragColor = vec4(wf_col, alpha);
gl_FragColor = vec4(.5, .5, .5, 1);
else
gl_FragColor = vec4(frag_col, alpha);
}

13
src/shader.vert Normal file
View File

@ -0,0 +1,13 @@
attribute vec3 pos;
attribute vec3 col;
varying vec3 frag_col;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model;
void main() {
gl_Position = proj * view * model * vec4(pos, 1.0);
frag_col = col;
}

2
tp.pro
View File

@ -16,6 +16,8 @@ win32 {
LIBS += $$PWD/libs/OpenMesh/libwin/OpenMeshCore.lib LIBS += $$PWD/libs/OpenMesh/libwin/OpenMeshCore.lib
} }
RESOURCES = resources.qrc
HEADERS += src/my_mesh.h HEADERS += src/my_mesh.h
HEADERS += src/main_window.h HEADERS += src/main_window.h
HEADERS += src/mesh_viewer.h HEADERS += src/mesh_viewer.h