Open gl draw turns white after one frame drawn - c++

I am newbie in Opengl. I used the following example from Qt as a start in Opengl as I know Qt.
http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-squircle-cpp.html
I replaced the paint function of the program with following code with an intent to draw chess board pattern. Following is not the paint or render function of my program
paint()
{
if (!m_program) {
initializeOpenGLFunctions();
m_program = new QOpenGLShaderProgram();
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform lowp float t;"
"varying highp vec2 coords;"
"void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
}
auto width = static_cast<float>(m_viewportSize.width());
auto height = static_cast<float>(m_viewportSize.height());
auto a = 2.f / width;
auto b = 2.f / height;
std::vector<float> matrix =
{
a , 0, 0, 0,
0, -b, 0, 0,
0, 0, 1, 0,
-1, 1, 0, 1
};
// Set the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(matrix.data());
// Initialize vertices:
std::vector<float> vertices =
{
0, 0,
0, height,
width, height,
width, 0
};
// Initialize colors
std::vector<float> colors =
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
0, 1, 1
};
// Initialize texture virtice
std::vector<float> texCoord =
{
0, 0,
0, 1,
1, 1,
1, 0
};
// Create texture: simple chess board 8x8
auto numRows = 8u;
auto numCols = 8u;
auto character = 172u;
auto remain = 255u - character;
std::vector<unsigned char> texture(numCols * numRows);
for (auto i = 0u; i < texture.size(); ++i)
texture[i] = ((i + (i / numCols)) % 2) * remain + character;
// Upload to GPU texture
unsigned textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, numCols, numRows, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texture.data());
// Initialize clear colors
glClearColor(0.f, 0.f, 0.f, 1.f);
// Activate necessary states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices.data());
glColorPointer(3, GL_FLOAT, 0, colors.data());
glTexCoordPointer(2, GL_FLOAT, 0, texCoord.data());
// render
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_QUADS, 0, 4);
m_program->disableAttributeArray(0);
m_program->release();
m_window->resetOpenGLState();
}
The chess board is drawn. But its drawn for a split second & then the screen turns fully white. I want to draw the chess board pattern continiously with each frame draw.
Can someone pls point out what might be going wrong ?

At the very top you have:
if (!m_program) {
then you initialize m_program, at the very bottom you have:
m_program->release();
which as Harish in comments points out is equivalent to calling glUseProgram(0);. So in the next iteration of paint your shader is not bound and not available.
According to docs, the reverse of release(); is bind(); so (I am not expert on this class) the solution might be to call QOpenGLShaderProgram::bind() on the next iteration of your paint.

For future reference, it's a good idea to run opengl programs through a graphics debugger like gDEbugger to give you an insight into what's actually happening inside the API.

Related

Opengl Textures dont display but give corrupted double linked list error

I've been playing with textures for some time and i just can't get it to work
Here is the code
#include "App.h"
std::array <float, 4> background_col = {0.25, 0.25, 0.25, 1.0} ;
std::string name = "OpenGL" ;
std::string icon = "data/images/dot.png" ;
const int width = 800 ;
const int height = 800 ;
bool anti_aliasing = true ;
bool FPS_60_CAP = true ;
MVP mvp;
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
}
void App::run()
{
Window window(true, anti_aliasing);
window.make_Window(glfwCreateWindow(width, height, name.c_str(), NULL, NULL), key_callback, icon);
srand(time(NULL));
mvp.view = glm::ortho(0.0f, (float)width, 0.0f, (float)height);
Renderer renderer;
Player player;
// redesighn with errors in mind
// 1. TODO: Implement Text
// 2. TODO: Implement UI
std::vector<float> vertexes = {
200, 200, 1, 1, 1, 1, 0, 0,
200, 600, 1, 1, 1, 1, 0, 1,
600, 600, 1, 1, 1, 1, 1, 1,
600, 200, 1, 1, 1, 1, 1, 0
};
std::vector<uint32_t> indexes = {0, 1, 2, 3};
while (!glfwWindowShouldClose(window.window))
{
glClearColor(background_col[0], background_col[1], background_col[2], background_col[3]);
glClear(GL_COLOR_BUFFER_BIT);
warn(0);
Shader shader("shaders/text.shader");
shader.useShader();
warn(1);
Texture tex("data/images/dot.png");
tex.Bind();
warn(2);
shader.uniformMat4Float("u_projection_matrix", mvp.projection * mvp.view * mvp.model);
shader.uniformInt({0}, "tex");
warn(3);
VBO vbo;
VAO vao;
IBO ibo;
warn(4);
vbo.write(vertexes.data(), vertexes.size() * sizeof(float));
ibo.write(indexes.data(), indexes.size() * sizeof(uint32_t));
warn(5);
ibo.bind();
vbo.bind();
vao.bind();
warn(6);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 2));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (const void *)(sizeof(float) * 6));
warn(7);
glDrawElements(GL_QUADS, indexes.size(), GL_UNSIGNED_INT, nullptr);
warn(8);
ibo.unbind();
vbo.unbind();
vao.unbind();
warn(9);
tex.unBind();
tex.~Texture();
warn(10);
vbo.~VBO();
vao.~VAO();
ibo.~IBO();
warn(11);
shader.deleteShader();
warn(12);
glfwSwapBuffers(window.window);
glfwSwapInterval(FPS_60_CAP);
glfwPollEvents();
}
alcCloseDevice(player.Device);
window.~Window();
}
the texture class:
#include "Core.h"
Texture::Texture(std::string path)
{
this->path = path;
this->bpp = 0;
this->height = 0;
this->width = 0;
this->localbuffer = nullptr;
this->TexID = 0;
stbi_set_flip_vertically_on_load(1);
localbuffer = stbi_load(path.c_str(), &width, &height, &bpp, 4);
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localbuffer);
glBindTexture(GL_TEXTURE_2D, 0);
if (localbuffer) { stbi_image_free(localbuffer); }
else { info("h"); }
}
void Texture::Bind(uint32_t slot)
{
glActiveTexture(GL_TEXTURE0 + slot);
}
void Texture::unBind()
{
glBindTexture(GL_TEXTURE_2D, 0);
}
Texture::~Texture()
{
glDeleteTextures(1, &TexID);
}
and the shader:
#shader vertex
#version 400 core
layout (location = 0) in vec4 Pos;
layout (location = 1) in vec4 vColor;
layout (location = 2) in vec2 vTexCoord;
out vec4 color;
out vec2 TexCoord;
uniform mat4 u_projection_matrix;
void main()
{
gl_Position = u_projection_matrix * Pos;
color = vColor;
TexCoord = vTexCoord;
}
#shader fragment
#version 400 core
in vec4 color;
in vec2 TexCoord;
uniform sampler2D tex;
void main()
{
vec4 texcol = texture(tex, TexCoord);
gl_FragColor = texcol;
}
it just stays blank and displays this error
corrupted double-linked list
it is important to mention this error happens on the second frame
The code that I know works because I've got textures to display before correctly is:
the Shader class
VAO VBO and IBO
EDIT: after the fix from rafix07 it doesn't crash anymore it just doesn't display
EDIT2:
I've implemented glDebugMessageCallback, and it gives me this error:
source: 33352
type: 33361
id: 1
severity: 33387
length: 130
GL ERROR!: Shader Stats: SGPRS: 24 VGPRS: 24 Code Size: 72 LDS: 0 Scratch: 0 Max Waves: 10 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
Remove all explicit invocations of destructors, like:
tex.~Texture();
You get corrupted double-linked list because you deallocate a resource twice: first time by calling destructor explicitly and the second one when destructor is called at the end of scope within object is defined.
{
Texture tex;
// ...
tex.~Texture(); // texture is deallocated and id texture is dangling reference
// <-- dtor of tex is called implicitly, and the same id texture is deleted again leading to crash
}

Why always produce 4 pictures in my qt opengl program?

Here is my code:
modify from qt example: Examples\Qt-5.14.2\quick\scenegraph\openglunderqml
void SquircleRenderer::init()
{
unsigned char* data = (unsigned char*)malloc(1200*4);
for(int i=0;i<600;i++)
{
data[i*4] = 0;
data[i*4+1] = 255;
data[i*4+2] = 0;
data[i*4+3] = 255;
}
for(int i=600;i<1200;i++)
{
data[i*4] = 0;
data[i*4+1] = 0;
data[i*4+2] = 255;
data[i*4+3] = 255;
}
if (!m_program) {
QSGRendererInterface *rif = m_window->rendererInterface();
Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
initializeOpenGLFunctions();
if (texs[0])
{
glDeleteTextures(1, texs);
}
glGenTextures(1, texs);
glBindTexture(GL_TEXTURE_2D, texs[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 30, 40, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
m_program = new QOpenGLShaderProgram();
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
"varying highp vec2 coords;"
"uniform sampler2D inputImageTexture;"
"void main() {"
" gl_FragColor = texture2D(inputImageTexture, coords);"
"}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
arrUni[0] = m_program->uniformLocation("inputImageTexture");
}
}
//! [4] //! [5]
void SquircleRenderer::paint()
{
// Play nice with the RHI. Not strictly needed when the scenegraph uses
// OpenGL directly.
m_window->beginExternalCommands();
m_program->bind();
m_program->enableAttributeArray(0);
float values[] = {
-1, 1,
1, 1,
-1, -1,
1, -1
};
// This example relies on (deprecated) client-side pointers for the vertex
// input. Therefore, we have to make sure no vertex buffer is bound.
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program->setAttributeArray(0, GL_FLOAT, values, 2);//values
//m_program->setUniformValue("t", (float) m_t);
qDebug()<<m_viewportSize.width()<<m_viewportSize.height()<<"\n";
glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texs[0]);
glUniform1i(arrUni[0], 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_program->disableAttributeArray(0);
m_program->release();
m_window->endExternalCommands();
}
As the picture you can see,it produces 4 same pictures,could you tell me how to produce 1 picture fill the whole window?:
I tried so many methods, but it didn't work, I guess the problem exists in the values array or the glTexImage2D function.
Textures are mapped accross the [0, 1] range, and values outside of that range are modulo-looped back into it, which creates a repeating pattern. Interpreting the texture over the [-1, 1] range leads to what you are seeing since you are mapping exactly twice the UV range in both axises.
There's a few ways to fix this. But my personal preference for a full-framebuffer pass like this is to have the attribute be normalized, and then have it converted to the expected [-1, 1] range for the clip-space coordinate in the vertex shader:
float values[] = {
0.f, 1.f,
1.f, 1.f,
0.f, 0.f,
1.f, 0.f
};
gl_Position = vertices * 2.0 - vec4(1.0, 1.0,0.0,1.0);
Another common technique is to do away with the attribute buffer altogether, and use gl_VertexID to directly generate both the UVs and coordinates.

Rendering with RBG32UI internalFormat and reading with glReadPixels() not giving proper pixels

for fun I was testing format RGB32UI for rendering.
I managed to solve problem in some fancy way, I'm curious if it's possible to do it "normally".
Here is my code to draw quad to render buffer:
virtual long Run()
{
long result = NO_ERROR;
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_program = CreateProgram(VertexShader(), "", "", "", FragmentShader());
glLinkProgram(m_program);
const float vertex_data[] = { -1, -1, 0, 1, 1, -1, 1, 1, 1, 1, 1, 0, -1, 1, 0, 0 };
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glBindVertexArray(m_vao);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glUseProgram(m_program);
glUniform1f(glGetUniformLocation(m_program, "normalizer"), 127.0);
if (Execute<GLbyte>(GL_RGBA8I, GL_BGRA_INTEGER, GL_BYTE, 0x00, 101, 127, 85) == ERROR)
{
Output(2, "Fail: Internal format GL_RGBA8I\t\tType GL_BYTE.\n");
result |= ERROR;
}
glUniform1f(glGetUniformLocation(m_program, "normalizer"), 32767.0);
if (Execute<GLshort>(GL_RGBA16I, GL_BGRA_INTEGER, GL_SHORT, 0x0000, 26214, 32767, 21845) == ERROR)
{
Output(2, "Fail: Internal format GL_RGBA16I\t\tType GL_SHORT.\n");
result |= ERROR;
}
glUniform1f(glGetUniformLocation(m_program, "normalizer"), 2147483647.0);
if (Execute<GLint>(GL_RGBA32I, GL_BGRA_INTEGER, GL_INT, 0x00000000, 1717987071, 2147483647, 1431655807) == ERROR)
{
Output(2, "Fail: Internal format GL_RGBA32I\t\tType GL_INT.\n");
result |= ERROR;
}
return result;
}
template<typename T>
long Execute(const long& internalFormat, const long& format, const long& type, const long& B, const long& G, const long& R, const long& A)
{
long result = NO_ERROR;
std::vector<T> dataIN(8192 * 4);
std::vector<T> dataOUT(8192 * 4);
for (int i = 0; i < 8192; i++)
{
dataIN[4 * i] = B;
dataIN[4 * i + 1] = G;
dataIN[4 * i + 2] = R;
dataIN[4 * i + 3] = A;
}
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 8192, 1, 0, format, type, &dataIN[0]);
glGetTexImage(GL_TEXTURE_2D, 0, format, type, &dataOUT[0]);
if (memcmp(&dataIN[0], &dataOUT[0], sizeof(T) * 8192 * 4) != 0)
{
Output(3, "Texel read from bound texture (%d, %d, %d, %d) is not equal to texel wrote to bound texture (%d, %d, %d, %d).\n",
dataOUT[0], dataOUT[1], dataOUT[2], dataOUT[3], dataIN[0], dataIN[1], dataIN[2], dataIN[3]);
result = ERROR;
}
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_QUADS, 0, 4);
std::vector<vec4> pix(100 * 100);
glReadPixels(0, 0, 100, 100, GL_RGBA, GL_FLOAT, &pix[0]);
DisplayData(100, 100, pix);
result |= CheckRectColor(pix, 100, 0, 0, 100, 100, vec4(1.0f, 0.8f, 0.0f, 0.666666f)) ? NO_ERROR : ERROR;
return result;
}
My fancy VertexShader:
std::string FragmentShader()
{
return
CONF_SHADER_BEGIN(430)
NL "in vec2 texCoord;"
NL "out vec4 out_color;"
NL "uniform isampler2D tex;"
NL "uniform float normalizer;"
NL "void main() {"
NL " ivec4 color = texture(tex, texCoord);"
NL " out_color = vec4(color.rgb / normalizer, color.a / normalizer);"
NL "}";
}
As you can see I'd like to render texture with GL_BGRA_INTEGER type (formats: GL_RGBA8I, GL_RGBA16I, GL_RGBA32I) to buffer and then read pixels from it with glReadPixels().
I tried to do it with GL_FLOAT and GL_INT formats but they give me nothing...
Only way I managed to do it is by normalizing values inside shader.
The way I'd like to do it is with FragmentShader below:
virtual std::string FragmentShader()
{
return
CONF_SHADER_BEGIN(430)
NL "in vec2 texCoord;"
NL "out ivec4 out_color;"
NL "uniform isampler2D tex;"
NL "void main() {"
NL " out_color = texture(tex, texCoord);"
NL "}";
}
And read pixels with:
std::vector<ivec4> pix(100 * 100);
glReadPixels(0, 0, 100, 100, GL_RGBA, GL_INT, &pix[0]);

FreeType library is not display with tutorial code

-Using Mac Retina display 2304x1440
I succeeded in including the FreeType library and tried to draw based on the tutorial but nothing was displayed.
There are no errors, so I can not identify the problem.
// For LoadShaders
#include "shader.hpp"
#include <vector>
#include <cstring>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <ft2build.h>
#include FT_FREETYPE_H
FT_Library library;
FT_Face face;
GLuint TextShaderID;
GLuint uniform_tex;
GLuint uniform_color;
GLuint vbo00;
// I have already acquired this font.
const char * fontfilename = "OpenSans-Regular.ttf";
void iii()
{
/* Initialize the FreeType2 library */
if (FT_Init_FreeType(&library)) {
fprintf(stderr, "Could not init freetype library\n");
}
/* Load a font */
if (FT_New_Face(library, fontfilename, 0, &face)) {
fprintf(stderr, "Could not open font %s\n", fontfilename);
}
// Initialize Shader (Here is not problem. Maybe.)
TextShaderID = LoadShaders( "material/shader/FreeType.vertexshader", "material/shader/FreeType.fragmentshader" );
// Initialize uniforms' IDs
uniform_tex = glGetUniformLocation( TextShaderID, "myTextureSampler" );
uniform_color = glGetUniformLocation( TextShaderID, "texcol" );
glGenBuffers(1, &vbo00);
}
void render_text(const char *text, float x, float y, float sx, float sy) {
const char *p;
FT_GlyphSlot g = face->glyph;
glActiveTexture(GL_TEXTURE0);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(uniform_tex, 0);
/* We require 1 byte alignment when uploading texture data */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* Clamping to edges is important to prevent artifacts when scaling */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/* Linear filtering usually looks best for text */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* Set up the VBO for our vertex data */
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo00);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
/* Loop through all characters */
for (p = text; *p; p++) {
/* Try to load and render the character */
if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
continue;
/* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
/* Calculate the vertex and texture coordinates */
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2, 0, 0},
{x2 + w, -y2, 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
/* Draw the character on the screen */
glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* Advance the cursor to the start of the next character */
x += (g->advance.x >> 6) * sx;
y += (g->advance.y >> 6) * sy;
}
glDisableVertexAttribArray(0);
glDeleteTextures(1, &tex);
}
void rrr()
{
glUseProgram(TextShaderID);
/* White background */
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float sx = 2/2304/4;
float sy = 2/1440/4;
FT_Set_Pixel_Sizes(face, 0, 48);
/* Effects of alignment */
GLfloat red[4] = { 1, 0, 0, 1 };
glUniform4fv(uniform_color, 1, red);
render_text("The Quick Brown Fox Jumps Over The Lazy Dog", 0, 0, sx, sy);
glutSwapBuffers();
}
float sx = 2/2304/4;
float sy = 2/1440/4;
are integral divisions. If an integral number is divided by a greater integral number, than the result is 0.
You've to do floating point divisions:
float sx = 2.0f/2304.0f/4.0f;
float sy = 2.0f/1440.0f/4.0f;
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
g->bitmap.width, g->bitmap.rows, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
generates a texture, where the data is encoded to the alpha channel. This has to be considered in the shader code, when the texture is looked up (by .a):
e.g.
#version 460
// [...]
uniform sampler2D myTextureSampler;
uniform vec4 texcol;
void main()
{
vec4 col = texcol * texture(myTextureSampler, uv).a;
// [...]
}
Anyway GL_ALPHA is deprecated and Legacy OpenGL. This means this won't work if you use a core profile Context.
Use GL_RED instead:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,
g->bitmap.width, g->bitmap.rows, 0,
GL_RED, GL_UNSIGNED_BYTE, g->bitmap.buffer);
Read the data from the red color channel (.r) in the fragment shader:
#version 460 core
// [...]
uniform sampler2D myTextureSampler;
uniform vec4 texcol;
void main()
{
vec4 col = texcol * texture(myTextureSampler, uv).r;
// [...]
}

Compute shader doesn't change texture

I'm trying currently to change the color of a texture to black with a compute shader, but it doesn't work and i don't find why. There is no problem with the shader compilation, neither with the program linking, so i think that the problem is in the update of the shader. Here's my code :
Update :
glUseProgram(m_programID);
int location = glGetUniformLocation(m_programID, "img_out");
glUniform1i(location, 0);
glBindImageTexture(0, texID, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
glDispatchCompute(1024, 1024, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
int format;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
unsigned char* img = new unsigned char[1024 * 1024 * 4];
glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, img);
int i = SOIL_save_image("img.bmp", SOIL_SAVE_TYPE_BMP, 1024, 1024, 4, img);
std::cout << SOIL_last_result() << std::endl;
delete[] img;
glUseProgram(0);
Shader :
#version 450 core
layout(local_size_x = 1, local_size_y = 1) in;
layout(binding = 0, RGBA32F) uniform image2D img_out;
void main()
{
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
imageStore(img_out, pos, vec4(0.f, 0.f, 0.f, 1.f));
}
ps : texture used here is an image loaded with soil but does it matter?