I give you my examples how to draw a cube with simple diffuse lighting and how to draw a texture. I hope it will help you to start. I use a free version of Qt: Download Qt | Develop Desktop & Embedded Systems | Qt
Drawing a cube: Cube_OpenGL33_Qt5Cpp, C++ (gcc) - rextester
// Add this line to .pro:
// win32: LIBS += -lopengl32
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
class OpenGLWidget : public QOpenGLWidget {
Q_OBJECT
public:
OpenGLWidget(QWidget *parent = nullptr)
: QOpenGLWidget(parent)
, m_indexBuffer(QOpenGLBuffer::IndexBuffer)
{
setWindowTitle("Qt C++, OpenGL");
resize(268, 268);
}
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertPosBuffer;
QOpenGLBuffer m_normalBuffer;
QOpenGLBuffer m_indexBuffer;
QMatrix4x4 m_projMatrix;
QMatrix4x4 m_viewMatrix;
QMatrix4x4 m_modelMatrix;
int m_amountOfVertices;
void initializeGL() override {
glClearColor(0.5f, 0.8f, 0.7f, 1.f);
glEnable(GL_DEPTH_TEST);
const char *vertShaderSrc =
"#version 330 core\n"
"in vec3 aPosition;"
"in vec4 aNormal;"
"uniform mat4 uMvpMatrix;"
"uniform mat4 uNormalMatrix;"
"out vec4 vColor;"
"void main()"
"{"
" gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
" vec3 lightDirection = normalize(vec3(0.0, 0.5, 0.7));"
" vec4 color = vec4(1.0, 0.4, 0.0, 1.0);"
" vec3 normal = normalize((uNormalMatrix * aNormal).xyz);"
" float nDotL = max(dot(normal, lightDirection), 0.0);"
" vColor = vec4(color.rgb * nDotL + vec3(0.1), color.a);"
"}";
const char *fragShaderSrc =
"#version 330 core\n"
"in vec4 vColor;"
"out vec4 fragColor;"
"void main()"
"{"
" fragColor = vColor;"
"}";
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
m_program.link();
m_program.bind();
m_amountOfVertices = initVertexBuffers();
m_viewMatrix.lookAt(
QVector3D(20.f, 15.f, 30.f), // eye position
QVector3D(0.f, 0.f, 0.f), // center
QVector3D(0.f, 1.f, 0.f)); // up
m_modelMatrix.translate(QVector3D(0.f, 0.f, 0.f));
m_modelMatrix.rotate(0.f, QVector3D(0.f, 1.f, 0.f));
m_modelMatrix.scale(7.f, 7.f, 7.f);
}
void paintGL() override {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawBox();
}
void drawBox() {
QMatrix4x4 mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
m_program.bind();
m_program.setUniformValue("uMvpMatrix", mvpMatrix);
QMatrix4x4 normalMatrix;
normalMatrix = m_modelMatrix.inverted();
normalMatrix = normalMatrix.transposed();
m_program.setUniformValue("uNormalMatrix", normalMatrix);
glDrawElements(GL_TRIANGLES, m_amountOfVertices, GL_UNSIGNED_INT, nullptr);
}
void resizeGL(int w, int h) override {
glViewport(0, 0, w, h);
m_projMatrix.setToIdentity();
m_projMatrix.perspective(50.f, (float)width()/height(), 0.1f, 100.f);
}
int initVertexBuffers() {
// Create a cube
// v6----- v5
// /| /|
// v1------v0|
// | | | |
// | |v7---|-|v4
// |/ |/
// v2------v3
float vertPositions[] = {
// v0-v1-v2-v3 front
1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f, 1.f,
// v0-v3-v4-v5 right
1.f, 1.f, 1.f, 1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f,
// v0-v5-v6-v1 up
1.f, 1.f, 1.f, 1.f, 1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f,
// v1-v6-v7-v2 left
-1.f, 1.f, 1.f, -1.f, 1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f,
// v7-v4-v3-v2 down
-1.f, -1.f, -1.f, 1.f, -1.f, -1.f, 1.f, -1.f, 1.f, -1.f, -1.f, 1.f,
// v4-v7-v6-v5 back
1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f, -1.f, 1.f, 1.f, -1.f
};
m_vertPosBuffer.create();
m_vertPosBuffer.bind();
m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
m_program.bindAttributeLocation("aPosition", 0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
m_program.enableAttributeArray(0);
float normals[] = {
// v0-v1-v2-v3 front
0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f,
// v0-v3-v4-v5 right
1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f,
// v0-v5-v6-v1 up
0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f,
// v1-v6-v7-v2 left
-1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f,
// v7-v4-v3-v2 down
0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f,
// v4-v7-v6-v5 back
0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f
};
m_normalBuffer.create();
m_normalBuffer.bind();
m_normalBuffer.allocate(normals, sizeof(normals));
m_program.bindAttributeLocation("aNormal", 1);
m_program.setAttributeBuffer(1, GL_FLOAT, 0, 3);
m_program.enableAttributeArray(1);
int indices[] = {
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9, 10, 8, 10, 11, // up
12, 13, 14, 12, 14, 15, // left
16, 17, 18, 16, 18, 19, // down
20, 21, 22, 20, 22, 23 // back
};
m_indexBuffer.create();
m_indexBuffer.bind();
m_indexBuffer.allocate(indices, sizeof(indices));
int amountOfVertices = sizeof(indices) / sizeof(indices[0]);
return amountOfVertices;
}
};
#include "main.moc"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
OpenGLWidget w;
w.show();
return a.exec();
}
Drawing a texture: https://rextester.com/BJW63108
// Add this line to .pro:
// win32: LIBS += -lopengl32
#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLTexture>
#include <QtGui/QMatrix4x4>
class Widget : public QOpenGLWidget {
Q_OBJECT
public:
Widget() : m_texture(QOpenGLTexture::Target2D) {
setWindowTitle("OpenGL 3.3. Qt C++");
resize(400, 400);
}
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertPosBuffer;
QOpenGLBuffer m_texCoordBuffer;
QOpenGLTexture m_texture;
QMatrix4x4 m_mvpMatrix;
QMatrix4x4 m_projMatrix;
QMatrix4x4 m_viewMatrix;
QMatrix4x4 m_modelMatrix;
int m_uMvpMatrixLocation;
const float WORLD_HEIGHT = 50;
void initializeGL() override {
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
resize(400, 400);
const char *vertShaderSrc =
"#version 330 core\n"
"in vec3 aPosition;"
"in vec2 aTexCoord;"
"uniform mat4 uMvpMatrix;"
"out vec2 vTexCoord;"
"void main()"
"{"
" gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
" vTexCoord = aTexCoord;"
"}";
const char *fragShaderSrc =
"#version 330 core\n"
"uniform sampler2D uSampler;"
"in vec2 vTexCoord;"
"out vec4 fragColor;"
"void main()"
"{"
" fragColor = texture2D(uSampler, vTexCoord);"
"}";
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
m_program.link();
m_program.bind();
float vertPositions[] = {
-0.5f, -0.5f, 0.f,
0.5f, -0.5f, 0.f,
-0.5f, 0.5f, 0.f,
0.5f, 0.5f, 0.f
};
float texCoords[] = {
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f
};
initVertexBuffer(m_vertPosBuffer, vertPositions, sizeof(vertPositions), "aPosition", 0, 3);
initVertexBuffer(m_texCoordBuffer, texCoords, sizeof(texCoords), "aTexCoord", 1, 2);
m_texture.create();
m_texture.setData(QImage(":/Textures/WornBrownBrickwork_256.png"));
m_texture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
m_texture.setWrapMode(QOpenGLTexture::ClampToEdge);
m_program.bind();
m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");
m_modelMatrix.scale(QVector3D(50.f, 50.f, 1.f));
m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 40.f),
QVector3D(0.f, 0.f, 0.f),
QVector3D(0.f, 1.f, 0.f));
}
void paintGL() override {
glClear(GL_COLOR_BUFFER_BIT);
m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
m_program.bind();
m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
m_texture.bind();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
void resizeGL(int w, int h) override {
glViewport(0, 0, w, h);
float aspect = (float) w / h;
float worldWidth = aspect * WORLD_HEIGHT;
m_projMatrix.setToIdentity();
m_projMatrix.ortho(-worldWidth / 2.f, worldWidth / 2.f,
-WORLD_HEIGHT / 2.f, WORLD_HEIGHT / 2.f, 50.f, -50.f);
}
void initVertexBuffer(QOpenGLBuffer &buffer, float data[], int amount,
const char *locationName, int locationIndex, int tupleSize) {
buffer.create();
buffer.bind();
buffer.allocate(data, amount);
m_program.bindAttributeLocation(locationName, locationIndex);
m_program.setAttributeBuffer(locationIndex, GL_FLOAT, 0, tupleSize);
m_program.enableAttributeArray(locationIndex);
}
};
#include "main.moc"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}