(Compute Shader) 1 pixel implicitly adding color to other pixels

#1

I am confused as to why the compute shader is implicitly adding color to untouched pixels of an image2D variable. This holds true if I shade (100+)^2 pixels white, and shade the [0,0] pixel as black; the result is a window where all pixels of the window are grey.

This is an issue because I cannot make any pixel art; they all blend for some reason.
i.e. I am doing pixel blending art, not pixel perfect art; and it’s a mess!

Why is life this way?

CODE

*Compute Shader*
#version 430 core

layout (binding = 0, rgba32f) uniform image2D img;
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

void main(void) {
	vec4 color;
	if (gl_GlobalInvocationID.xy == ivec2(0,0)){
		color = vec4(0.0,0.0,0.0,1.0);
	}
	else {
		color = vec4(1.0,1.0,1.0,1.0);
	}
	ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
	imageStore(img, pos, color);

}

*Vertex Shader*
#version 430 core

layout (location = 0) in vec3 vPos;
layout (location = 1) in vec2 tPos1;
out vec2 tPos2;

void main(){

    gl_Position = vec4(vPos, 1.0);
    tPos2 = tPos1;
}

*Fragment Shader*
#version 430 core

uniform sampler2D img;
in vec2 tPos2;
out vec4 FragColor;

void main()
{

	FragColor = texture(img, tPos2);
}

*Suspective App Code*
#include <GLAD/glad.h>
#include <GLFW/glfw3.h>
#include "Shader.h"

int main(void) {

	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_DECORATED, false);
	GLFWwindow* window = glfwCreateWindow(1200, 800, "(PC)", NULL, NULL);
	const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
	int windowX, windowY;
	glfwSetWindowSize(window, mode->width/2, mode->height/2);
	glfwGetWindowSize(window, &windowX, &windowY);
	glfwSetWindowPos(window, (mode->width - windowX)/2, (mode->height - windowY)/2);

	glfwMakeContextCurrent(window);

	glViewport(0, 0, windowX, windowY);

	// Data
	float data[] = {
		// x-y-z positions, & u-v texCoordinates (in a Row->)
		-1.0,-1.0, 0.0, 0.0,0.0,
		-1.0, 1.0, 0.0, 0.0,1.0,
		 1.0, 1.0, 0.0, 1.0,1.0,
		-1.0,-1.0, 0.0, 0.0,0.0,
		 1.0,-1.0, 0.0, 1.0,0.0,
		 1.0, 1.0, 0.0, 1.0,1.0
	};

	// Compute Shader
	Shader computeShader("shader.compute");
	computeShader.Use();
	glActiveTexture(GL_TEXTURE0);
	GLuint computeTexture;
	glGenTextures(1, &computeTexture);
	glBindTexture(GL_TEXTURE_2D, computeTexture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// If I remove the above 2 lines, it will not display anything...
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, windowX, windowY, 0, GL_RGBA, GL_FLOAT, 0);
	glBindImageTexture(0, computeTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

	// Vertex & Fragment Shader
	Shader vertexfragmentShader("shader.vs", "shader.fs");
	vertexfragmentShader.Use();
	// VAO
	GLuint vao;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	// VBO
	GLuint vbo;
	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
	// Data Lx Configuration
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)3);
	glEnableVertexAttribArray(1);
	// Texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, computeTexture);

	glClearColor(0.1,0.1,0.1,1.0);
	glDisable(GL_DEPTH_TEST);
	while (!glfwWindowShouldClose(window)) {

		computeShader.Use();
		glDispatchCompute((GLuint)windowX, (GLuint)windowY, 1);

		glClear(GL_COLOR_BUFFER_BIT);
		vertexfragmentShader.Use();
		glBindVertexArray(vao);
		glDrawArrays(GL_TRIANGLES, 0, 6);

		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glfwTerminate();
	return 1;
}

If I run all code in this current state (including the parts I left out that are correct), it outputs grey, because the [0,0] pixel was set to black, and everything else was set to white.

:slight_smile:

#2

The last parameter should be (void*)(3*sizeof(float)). As it stands, the texture coordinates are offset by 3 bytes rather than 3 floats.