LINUX.ORG.RU

QOpenGLWidget

 ,


0

2

Пытаюсь осилить QOpenGLWidget (буду наглядно рисовать углы наклона ИНС). Унаследовал от этого класса свой виджет и переопределил необходимые методы:

class ImuStateWidget : public QOpenGLWidget
{
	public:
		ImuStateWidget(QWidget *parent);
		~ImuStateWidget();

	protected:
		void initializeGL();
		void paintGL();
		void resizeGL(int w, int h);

	private:
		GLuint vertex_buffer;
};

ImuStateWidget::ImuStateWidget(QWidget *parent = 0) : QOpenGLWidget(parent)
{
	// Nothing to do
}

ImuStateWidget::~ImuStateWidget()
{
	// Nothing to do
}

void ImuStateWidget::initializeGL() {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glClearColor(0.0, 0.0, 0.0, 1.0);
	static const GLfloat vertex_buffer_data[] = {
		0.0, 0.8, 0.0,
		-0.8, -0.8, 0.0,
		0.8, -0.8, 0.0
	};
	f->glGenBuffers(1, &vertex_buffer);
	f->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	f->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW);
}

void ImuStateWidget::resizeGL(int w, int h) {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glViewport(0, 0, w, h);
}

void ImuStateWidget::paintGL() {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	f->glEnableVertexAttribArray(0);
	f->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	f->glDrawArrays(GL_TRIANGLES, 0, 3);
	f->glDisableVertexAttribArray(0);
}

Ожидаю увидеть треугольник - получаю чёрный виджет. Если, например, менять значения glClearColor, то цвет виджета меняется, так что мои методы вызываются, но что-то я делаю не так. Вполне возможно потому что я никогда раньше не работал с OpenGL 3.0, а рисовал все треугольники с помощью glVertex.

★★★★★

glEnableVertexAttribArray и glVertexAttribPointer без шейдеров не должены работать.
Для FFP надо юзать glEnableClientState + glVertexPointer если я ничего не забыл.

oh-la-la ()
Ответ на: комментарий от oh-la-la

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-trian...

Вот тут рисуют треугольник именно этими функциями, при этом шейдеры применяются только во второй части, когда уже добавляют настройку цвета. А glEnableClientState и glVertexPointer нет в структуре QOpenGLFunctions.

KivApple ★★★★★ ()
Ответ на: комментарий от KivApple

QOpenGLFunctions расчитан на подмножество функций OpenGL ES 2.0, а там шейдеры обязтаельны. По ссылке написано кстате

If you’re on lucky, you can see the result (don’t panic if you don’t)

Так что, раз ты расчитываешь на OpenGL 3, прикручивай шейдеры.

То что, там у кого-то отображается это скорее всего UB.
На будущее используй http://doc.qt.io/qt-5/qopengldebuglogger.html или напрямую https://www.opengl.org/registry/specs/KHR/debug.txt И да если будешь использовать OpenGL 3.3 core не забудь про VAO, а то тоже ничего рисоваться не будет =)

oh-la-la ()
Последнее исправление: oh-la-la (всего исправлений: 1)
Ответ на: комментарий от oh-la-la

Добавил шейдеры, они не компилировались, потому что конкретно OpenGL 3.3 оно не хотело, только другие версии. Изменил версию OpenGL в шейдере на OpenGL 3.0 ES, оно начало ругаться, что не указана точность для vec3 в фрагментном шейдере. Поставил точность meduim. И наконец-то получился красный треугольник. Код получился таким:

class ImuStateWidget : public QOpenGLWidget
{
	public:
		ImuStateWidget(QWidget *parent);
		~ImuStateWidget();

	protected:
		void initializeGL();
		void paintGL();
		void resizeGL(int w, int h);

	private:
		GLuint vertex_buffer;
		GLuint program;
};

ImuStateWidget::ImuStateWidget(QWidget *parent = 0) : QOpenGLWidget(parent)
{
	// Nothing to do
}

ImuStateWidget::~ImuStateWidget()
{
	// Nothing to do
}

void ImuStateWidget::initializeGL() {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glClearColor(0.0, 0.0, 0.0, 1.0);

	GLuint vertex_shader = f->glCreateShader(GL_VERTEX_SHADER);
	GLuint fragment_shader = f->glCreateShader(GL_FRAGMENT_SHADER);
	static const char vertex_shader_src[] = "#version 300 es\nlayout(location = 0) in vec3 vertexPosition_modelspace;\nvoid main(){\ngl_Position.xyz = vertexPosition_modelspace;\ngl_Position.w = 1.0;\n}\n";
	static const char fragment_shader_src[] = "#version 300 es\nout mediump vec3 color;\nvoid main(){\ncolor = vec3(1,0,0);\n}\n";
	static const char *vertex_shader_src_ptr = vertex_shader_src;
	static const char *fragment_shader_src_ptr = fragment_shader_src;
	f->glShaderSource(vertex_shader, 1, &vertex_shader_src_ptr, NULL);
	f->glCompileShader(vertex_shader);
	{
		GLint len;
		f->glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &len);
		char log[len];
		f->glGetShaderInfoLog(vertex_shader, len, NULL, log);
		qDebug() << "Vertex shader compile log:";
		qDebug() << log;
	}
	f->glShaderSource(fragment_shader, 1, &fragment_shader_src_ptr, NULL);
	f->glCompileShader(fragment_shader);
	{
		GLint len;
		f->glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &len);
		char log[len];
		f->glGetShaderInfoLog(fragment_shader, len, NULL, log);
		qDebug() << "Fragment shader compile log:";
		qDebug() << log;
	}
	program = f->glCreateProgram();
	f->glAttachShader(program, vertex_shader);
	f->glAttachShader(program, fragment_shader);
	f->glLinkProgram(program);
	{
		GLint len;
		f->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
		char log[len];
		f->glGetProgramInfoLog(program, len, NULL, log);
		qDebug() << "Program compile log:";
		qDebug() << log;
	}
	f->glDeleteShader(vertex_shader);
	f->glDeleteShader(fragment_shader);

	static const GLfloat vertex_buffer_data[] = {
		0.0, 0.8, 0.0,
		-0.8, -0.8, 0.0,
		0.8, -0.8, 0.0
	};
	f->glGenBuffers(1, &vertex_buffer);
	f->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	f->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW);
}

void ImuStateWidget::resizeGL(int w, int h) {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glViewport(0, 0, w, h);
}

void ImuStateWidget::paintGL() {
	QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
	f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	f->glUseProgram(program);
	f->glEnableVertexAttribArray(0);
	f->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	f->glDrawArrays(GL_TRIANGLES, 0, 3);
	f->glDisableVertexAttribArray(0);
}

Конечно, теперь я в некотором замешательстве после моего прошлого опыта работы с OpenGL, когда мне хватало glBegin, glEnd, glColor и glVertex.

KivApple ★★★★★ ()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

Добавил шейдеры, они не компилировались, потому что конкретно OpenGL 3.3 оно не хотело, только другие версии. Изменил версию OpenGL в шейдере на OpenGL 3.0 ES

Не очень понятно здесь. Возможно несоответсвие версии созданного opengl контектса.

oh-la-la ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.