I am trying to create a paint program in opengl3.2
What I am doing is loading a texture in stb and brush texture in stb.
I trying 3 textures to load and it works greate
if (mousePressed) {
//drawBrushWithTransparency(window, mouseX, mouseY, layer1, brush);
//drawPixelsOnData(window, mouseX, mouseY);
//drawCirclesOnData(window, mouseX, mouseY);
//drawSquaresOnData(window, mouseX, mouseY, layer1);
//dBOT = false; //needs repaint
drawBrushOnPbuffer(window, mouseX, mouseY, layer1, brush);
//drawCirclesOnPbuffer(window, mouseX, mouseY, layer1);
//drawSquaresOnPbuffer(window, mouseX, mouseY);
dBOT = true; //doesnt need repaint
}
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(shaderProgram);
if(!dBOT) repaint(layer1);
glBindTexture(GL_TEXTURE_2D, layer1->canvas_textureID);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(shaderProgram);
if(!dBOT) repaint(layer2);
glBindTexture(GL_TEXTURE_2D, layer2->canvas_textureID);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(shaderProgram);
if(!dBOT) repaint(layer3);
glBindTexture(GL_TEXTURE_2D, layer3->canvas_textureID);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
but when i add painting from a brush. using glTexSubImage2D it wont paint on
layer3
void drawBrushOnPbuffer(GLFWwindow* window, double mouseX, double mouseY, PGL_texture * pgl_texture, PGL_brush* pgl_brush) {
int width, height;
glfwGetFramebufferSize(window, &width, &height);
float texX = (float)mouseX / (float)width;
float texY = 1.0f - (float)mouseY / (float)height; // OpenGL's UVs start from the bottom-left, hence we flip Y
int texWidth, texHeight;
texWidth = pgl_texture->texture_width;
texHeight = pgl_texture->texture_height;
int paintX = texX * texWidth - pgl_brush->brush_width / 2;
int paintY = texY * texHeight - pgl_brush->brush_height / 2;
// Bind the brush texture
glBindTexture(GL_TEXTURE_2D, pgl_texture->canvas_textureID);
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Loop through the brush texture and apply it to the pbuffer
for (int i = 0; i < pgl_brush->brush_width; i++) {
for (int j = 0; j < pgl_brush->brush_height; j++) {
int brushIndex = (j * pgl_brush->brush_width + i) * 4;
unsigned char r = pgl_brush->brushData[brushIndex];
unsigned char g = pgl_brush->brushData[brushIndex + 1];
unsigned char b = pgl_brush->brushData[brushIndex + 2];
unsigned char a = pgl_brush->brushData[brushIndex + 3];
unsigned char brushColor[4];
brushColor[0] = r;
brushColor[1] = g;
brushColor[2] = b;
brushColor[3] = a;
//if (a != 0) { // Only update if alpha is not zero
int posX = paintX + i;
int posY = paintY + j;
int index = (j * pgl_brush->brush_width + i) * 4;
// Ensure the coordinates are within pbuffer bounds
// if (posX >= 0 && posY >= 0 && posX < width && posY < height) {
glTexSubImage2D(GL_TEXTURE_2D, 0, posX, posY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, brushColor);
//}
//}
}
}
// Unbind the texture and disable blending
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
}
i can only paint to layer1 the lowest layer.
if i paint directly to the layer texture or canvas data to any layers and update the layers it wont paint.
void drawBrushWithTransparency(GLFWwindow * window, double mouseX, double mouseY, PGL_texture* pgl_texture, PGL_brush* pgl_brush) {
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
GLFWmonitor* primary = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(primary);
float texX = (float)mouseX / (float)width;
// OpenGL's UVs start from the bottom-left, hence we flip Y
float texY = 1.0f - (float)mouseY / (float)height;
int texWidth = pgl_texture->texture_width;
int texHeight = pgl_texture->texture_height;
int paintX = texX * texWidth - pgl_brush->brush_width / 2;
int paintY = texY * texHeight - pgl_brush->brush_height / 2;
unsigned char brushColor[4];
// Bind the brush texture
glBindTexture(GL_TEXTURE_2D, pgl_brush->brush_textureID);
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (int i = 0; i < pgl_brush->brush_width; i++) {
for (int j = 0; j < pgl_brush->brush_height; j++) {
// Calculate the coordinates for the brush texture
int posX = paintX + i;
int posY = paintY + j;
// Check if the point is inside the target texture bounds
if (posX >= 0 && posX < texWidth && posY >= 0 && posY < texHeight) {
int index = (j * pgl_brush->brush_width + i) * 4;
unsigned char r = pgl_brush->brushData[index];
unsigned char g = pgl_brush->brushData[index + 1];
unsigned char b = pgl_brush->brushData[index + 2];
unsigned char a = pgl_brush->brushData[index + 3];
brushColor[0] = r;
brushColor[1] = g;
brushColor[2] = b;
brushColor[3] = a;
#if BDEBUG
printf("R:%i B:%i G:%i A:%i\n",
pgl_brush->brushData[index], pgl_brush->brushData[index+1], pgl_brush->brushData[index+2], pgl_brush->brushData[index+3]);
#endif
int cindex = (posY * pgl_texture->canvas_width + posX) * 4;
if ((int)a != 0) {
pgl_texture->canvas[cindex] = brushColor[0];
pgl_texture->canvas[cindex + 1] = brushColor[1];
pgl_texture->canvas[cindex + 2] = brushColor[2];
pgl_texture->canvas[cindex + 3] = brushColor[3];
}
}
}
}
// Unbind the texture and disable blending
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
}
I am using the concept of 2d painting and creating layers and painting on the texture or canvas data with brush data.
can someone tell me if i am approaching the problem wrong?
I posted 2 drawing version painting using pixel data and painting using subimage.
I just need help with not being able to see paintings on a givien canvas layer on my code even though i update it with glTexSubImage2D or by directly manipulating the canvas/pixel data.
Regards.