Home > Back-end >  Writing to a texture object from an array
Writing to a texture object from an array

Time:01-08

Since I filled the array with 1s I expected the square to be white. But when I ran the code the square was black. My idea was to use buffer sub data to upload the array to the buffer. I also tried to use persistent mapping so that I could write directly to the buffers memory. I have written a function that reads a texture from a file using stb image. Why is it that when using stb image to initialize the array the image shows up but it doesnt work with this array

Here is where I think the code is going wrong:

voxelEngine::BiomeMap::BiomeMap(int textureUnit) {
    pixels = new unsigned char[apothem*apothem*4];
    for(size_t i = 0; i < sizeof(pixels); i  ) {
        pixels[i] = 1;
    }
    _textureUnit = textureUnit;
    glGenBuffers(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);
    glGenBuffers(1, &tbo);
    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    float vertex_data[] = {
        0, 0, 0,    0, 0,
        0, 1, 0,    0, 1,
        1, 1, 0,    1, 1,
        1, 0, 0,    1, 0
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
    unsigned int indices[] = {
        0, 1, 2,
        0, 2, 3
    };
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glActiveTexture(GL_TEXTURE0   _textureUnit);
    glBindBuffer(GL_TEXTURE_2D, tbo);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, apothem, apothem, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, apothem, apothem, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    // set the texture wrapping/filtering options (on the currently bound texture object)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA, apothem, apothem);
    glGenerateMipmap(GL_TEXTURE_2D);

    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*sizeof(float)));
    glEnableVertexAttribArray(1);
}

Fragment shader:

#version 330 core
out vec4 FragColor;
in vec2 oTexCoord;

uniform sampler2D my_sampler;

void main()
{
    FragColor = texture(my_sampler, oTexCoord);
    //FragColor = vec4(1, 1, 1, 1);
}

Vertex shader:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 texCoord;

out vec2 oTexCoord;

uniform mat4 modelMat;
uniform mat4 projMat;

void main()
{
    gl_Position = projMat * modelMat * vec4(aPos.x, aPos.y, aPos.z, 1.0);
    oTexCoord = texCoord;
}

What image format does teximage2d expect why doesn't a linear array of rgba color values work? Does it have to do with texsubimage/teximage2d or are the textures not configured correctly?

CodePudding user response:

pixels = new unsigned char[apothem*apothem*4];

This allocates apothem*apothem*4 unsigned chars.

for(size_t i = 0; i < sizeof(pixels); i  ) {

sizeof(pixels) does not do what you think it does. Since pixels is, presumably, an unsigned char *, sizeof(pixels) will always be 8, on a 64-bit platform because all pointers take up 8 bytes.

I filled the array with 1s

No, you did not. You only filled the first 8 values in the array. And, if apothem happens to be 1 you just scrambled a bunch of memory, and created undefined behavior.

The fix is obvious.

size_t pixels_s=apothem*apothem*4;

pixels = new unsigned char[pixels_s];

for(size_t i = 0; i < pixels_s; i  ) {

and so on.

Even better: forget about new, use a std::vector<unsigned char> use the appropriate constructor that allocates the vector and initializes it, and you don't have to worry about forgetting to delete anything, and leak memory. This is what std::vector is for.

  • Related