Good day, need your help. I am trying to do simple hello world texture app using QT. I am trying to display simple generated image in my full screen rectangle, but got weird result.
If I visualize my UV coordinates all looks good, but when I try to sample texture I got total mess.
So here what I’ve got (from left to right ):
- UV coordinates visualization
- Generated image texture
- Result using texture sampler (should be more or less like 2 )
Here is generated texture image
And here is my result
Here is my code
#include "viewportwidget.h"
#include <QOpenGLWidget>
#include <QDebug>
#include <QOpenGLContext>
#include "lib/gimg/CImg.h"
using namespace cimg_library;
ViewportWidget::ViewportWidget(QWidget *parent)
:QOpenGLWidget(parent)
{
qDebug() << "Viewport Ctor";
}
ViewportWidget::~ViewportWidget()
{
}
void ViewportWidget::initializeGL()
{
qDebug() << "Initializing OpenGL context...";
// requested format
QSurfaceFormat requestedFormat = QSurfaceFormat();
requestedFormat.setMajorVersion(4);
requestedFormat.setMinorVersion(5);
requestedFormat.setProfile(QSurfaceFormat::CoreProfile);
requestedFormat.setRenderableType(QSurfaceFormat::OpenGL);
// create context
QOpenGLContext *oglContext = new QOpenGLContext(this);
oglContext->setFormat(requestedFormat);
// init context
bool ok = oglContext->create();
if (!ok) {
qDebug() << "Can not initialize OpenGL context";
exit(1);
}
QSurfaceFormat actualFormat = oglContext->format();
qDebug("Inited OpenGL version: %d.%d. Profile: %d. Render type: %d", actualFormat.majorVersion(), actualFormat.minorVersion(), actualFormat.profile(), actualFormat.renderableType());
oglF = oglContext->functions();
if (!oglF) {
qDebug() << "Can not get OpenGL functions pointer";
exit(1);
}
// X, Y, Z U, V
float vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
uint indices[] = { // note that we start from 0!
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
oglF->glGenBuffers(1, &VBO);
oglF->glBindBuffer(GL_ARRAY_BUFFER, VBO);
oglF->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
oglF->glGenBuffers(1, &EBO);
oglF->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
oglF->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// compile vertex shader
const char *vertexShaderSource = "#version 320 es\n layout (location = 0) in vec3 aPos;\n layout (location = 1) in vec2 aTexCoord;\n \n out vec2 TexCoord;\n \n void main()\n {\n gl_Position = vec4(aPos, 1.0);\n TexCoord = aTexCoord;\n }";
unsigned int vertexShader;
vertexShader = oglF->glCreateShader(GL_VERTEX_SHADER);
oglF->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
oglF->glCompileShader(vertexShader);
int success;
char infoLog[512];
oglF->glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
oglF->glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
qDebug("Vertex shader compilation error: %s", infoLog);
exit(1);
}
// compile fragment shader
const char *fragmentShaderSource = "#version 320 es\n \n in highp vec2 TexCoord;\n uniform sampler2D ourTexture;\n \n out highp vec4 FragColor;\n \n void main()\n {\n //FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n //FragColor = vec4(TexCoord.x, TexCoord.y, 0.0f, 1.0f);\n FragColor = texture(ourTexture, TexCoord);\n }";
unsigned int fragmentShader;
fragmentShader = oglF->glCreateShader(GL_FRAGMENT_SHADER);
oglF->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
oglF->glCompileShader(fragmentShader);
oglF->glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
oglF->glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
qDebug("Fragment shader compilation error: %s", infoLog);
exit(1);
}
// shader program
shaderProgram = oglF->glCreateProgram();
oglF->glAttachShader(shaderProgram, vertexShader);
oglF->glAttachShader(shaderProgram, fragmentShader);
oglF->glLinkProgram(shaderProgram);
oglF->glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
oglF->glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
qDebug("Link shader program error: %s", infoLog);
exit(1);
}
oglF->glUseProgram(shaderProgram);
//oglF->glDeleteShader(vertexShader);
//oglF->glDeleteShader(fragmentShader);
// link vertex buffer to vertex shader
uint posAttribute = oglF->glGetAttribLocation(shaderProgram, "aPos");
qDebug("Pos attribute: %d", posAttribute);
oglF->glVertexAttribPointer(posAttribute, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
oglF->glEnableVertexAttribArray(posAttribute);
// link vertex buffer to vertex shader
uint textCoordAttribute = oglF->glGetAttribLocation(shaderProgram, "aTexCoord");
qDebug("TextCoordAttribute attribute: %d", textCoordAttribute);
oglF->glVertexAttribPointer(textCoordAttribute, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
oglF->glEnableVertexAttribArray(textCoordAttribute);
// ##################### TEXTURE ######################
oglF->glGenTextures(1, &texture);
// create image of size 256x256 3 channels, fill color 255(white)
CImg<uchar> img(256, 256, 1, 3, 255);
const unsigned char color[] = { 0,0,0 };
// draw black line
img.draw_line(10, 10, 100, 100, color, 1.0f);
// get pointer to pixels data
textureData = img.data();
qDebug("Image width: %d", img.width());
qDebug("Image height: %d", img.height());
qDebug("Image spectrum: %d", img.spectrum());
// save image to debug
img.save("image.jpg");
oglF->glActiveTexture(GL_TEXTURE0);
oglF->glBindTexture(GL_TEXTURE_2D, texture);
oglF->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
oglF->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
oglF->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
oglF->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
uint textureAttribute = oglF->glGetUniformLocation(shaderProgram, "ourTexture");
qDebug("Texture attribute: %d", textureAttribute);
oglF->glUniform1i(textureAttribute, 0);
oglF->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
oglF->glGenerateMipmap(GL_TEXTURE_2D);
}
void ViewportWidget::paintGL()
{
qDebug() << "PaintGL";
oglF->glClear(GL_COLOR_BUFFER_BIT);
oglF->glBindBuffer(GL_ARRAY_BUFFER, VBO);
oglF->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
oglF->glUseProgram(shaderProgram);
oglF->glActiveTexture(GL_TEXTURE0);
oglF->glBindTexture(GL_TEXTURE_2D, texture);
// draw
oglF->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
qDebug("Error: %d", oglF->glGetError());
}
Fragment shader:
#version 320 es
in highp vec2 TexCoord;
uniform sampler2D ourTexture;
out highp vec4 FragColor;
void main()
{
//FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
//FragColor = vec4(TexCoord.x, TexCoord.y, 0.0f, 1.0f);
FragColor = texture(ourTexture, TexCoord);
}
Spend two days tweaking different parameters, no luck. What is wrong?