Answer the question
In order to leave comments, you need to log in
OpenGL is not rendered in the program when launched from QtCreator and on another computer, but is rendered when launched from Explorer - Why?
Trying to work with OpenGL via QOpenGLWidget and QOpenGLFunctions_3_3_core - wrote a small test program. When launched from QtCreator and from someone else's computer, a window and an unfilled rectangle are displayed, and it does not "blink" as it should according to the program:
#pragma once
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <glm/glm.hpp>
#include "GL/Program.h"
#include "GL/VAO.h"
class OGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
Q_OBJECT
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int width, int height) override;
private:
GL::VAO* _current_vao;
GL::Program* _current_program;
float _uniform;
void clear_color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 1.0);
public:
OGLWidget(QWidget* parent = nullptr);
~OGLWidget();
void timerEvent(QTimerEvent*) override;
public slots:
};
#include "oglwidget.h"
OGLWidget::OGLWidget(QWidget* parent)
: QOpenGLWidget(parent)
{
_uniform = 0.0f;
this->startTimer(10);
}
OGLWidget::~OGLWidget()
{
delete _current_vao;
delete _current_program;
}
void OGLWidget::initializeGL()
{
if(!initializeOpenGLFunctions())
{
throw std::runtime_error("Could not initialize QOpenGLFunctions!");
}
auto* functions = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
_current_vao = new GL::VAO(functions);
_current_program = new GL::Program(functions, "first");
//Vertices
_current_vao->add_VBO(
{
{-0.5f, 0.5f, 0.f},
{-0.5f, -0.5f, 0.f},
{ 0.5f, 0.5f, 0.f},
{ 0.5f, -0.5f, 0.f},
});
_current_vao->add_vertices(
{
0, 1, 2,
2, 1, 3
});
//Colors
_current_vao->add_VBO(
{
{ 1, 0, 0},
{ 0, 0, 1},
{ 0, 1, 0},
{ 1, 0, 0},
});
_current_program->bind_attribute(0, "position");
_current_program->bind_attribute(1, "color");
_current_program->link();
_current_program->use();
}
void OGLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
}
void OGLWidget::paintGL()
{
_uniform += 0.05f;
_current_program->set_float("animation", glm::sin(_uniform) * 0.5f + 0.5f);
clear_color(50, 50, 50);
glClear(GL_COLOR_BUFFER_BIT);
_current_vao->draw(GL_TRIANGLES);
}
void OGLWidget::timerEvent(QTimerEvent*)
{
repaint();
}
void OGLWidget::clear_color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
glClearColor((GLclampf)(red / 255.0),
(GLclampf)(green / 255.0),
(GLclampf)(blue / 255.0),
(GLclampf)(alpha / 255.0));
}
#pragma once
#include <string>
#include <QOpenGLFunctions_3_3_Core>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
namespace GL
{
class Program
{
private:
QOpenGLFunctions_3_3_Core* _functions;
GLuint _program;
GLuint _vertex_shader;
GLuint _fragment_shader;
GLint get_location(const std::string &name);
GLuint load_shader(const std::string &path, GLenum shader_type);
public:
Program(QOpenGLFunctions_3_3_Core* functions, const std::string &name);
~Program();
void link();
void bind_attribute(GLuint index, const std::string &name);
void use();
void set_float(const std::string &name, const float &value);
void set_matrix(const std::string &name, const glm::mat4 &matrix);
};
}
#include "Program.h"
#include <iostream>
#include <fstream>
GL::Program::Program(QOpenGLFunctions_3_3_Core* functions, const std::string &name)
{
_functions = functions;
_program = _functions->glCreateProgram();
_vertex_shader = load_shader("res/glsl/" + name + ".vert", GL_VERTEX_SHADER);
_fragment_shader = load_shader("res/glsl/" + name + ".frag", GL_FRAGMENT_SHADER);
if (_vertex_shader == 0 || _fragment_shader == 0)
{
throw std::runtime_error("Failed to create shaders!");
}
}
GL::Program::~Program()
{
_functions->glDetachShader(_program, _vertex_shader);
_functions->glDetachShader(_program, _fragment_shader);
_functions->glDeleteShader(_vertex_shader);
_functions->glDeleteShader(_fragment_shader);
_functions->glDeleteProgram(_program);
}
void GL::Program::link()
{
_functions->glAttachShader(_program, _vertex_shader);
_functions->glAttachShader(_program, _fragment_shader);
_functions->glLinkProgram(_program);
}
void GL::Program::bind_attribute(GLuint index, const std::string &name)
{
_functions->glBindAttribLocation(_program, index, name.c_str());
}
void GL::Program::use()
{
_functions->glUseProgram(_program);
}
void GL::Program::set_float(const std::string &name, const float &value)
{
_functions->glUniform1f(get_location(name), value);
}
void GL::Program::set_matrix(const std::string &name, const glm::mat4 &matrix)
{
_functions->glUniformMatrix4fv(get_location(name), 1, GL_FALSE, glm::value_ptr(matrix));
}
GLint GL::Program::get_location(const std::string &name)
{
return _functions->glGetUniformLocation(_program, name.c_str());
}
GLuint GL::Program::load_shader(const std::string &path, GLenum shader_type)
{
GLuint shader = _functions->glCreateShader(shader_type);
std::ifstream fis(path);
std::string shaderCode = {std::istreambuf_iterator<char>(fis), std::istreambuf_iterator<char>()};
const char *c = shaderCode.c_str();
_functions->glShaderSource(shader, 1, &c, nullptr);
GLint status;
_functions->glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
char buf[0x1000];
GLsizei length;
_functions->glGetShaderInfoLog(shader, sizeof(buf), &length, buf);
if (length > 0)
{
std::cerr << "Failed to comile shader " << path << std::endl << buf << std::endl;
return 0;
}
return shader;
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question