Convert a byte array into an image

Hi,

I’m very new to OpenGL and it seems to me that it could fulfill the requirements of my project :
I want to write a kind of “Game of life” program in C++, I will compute in a 2D array the state of the system from a previous state and a transition function. Each entry will take a float value between 0 and 1 (or more conveniently a byte between 0 and 255), and I wonder how I could draw an image by coloring each pixel in shades of grey from each value in this array. Then I want to redraw the image after each (or some) time step.

The dynamic aspect of this drawing project brought me here, but I struggle to find a starting point (I’ve read a bit about textures but I haven’t found how to build it from my array yet). Could you confirm or disconfirm my idea to use OpenGL for this application ? Do you have some hints to begin in the right direction ?

Thank you for your help.

[QUOTE=Singularite;1284333]Hi,

I’m very new to OpenGL and it seems to me that it could fulfill the requirements of my project :
I want to write a kind of “Game of life” program in C++, I will compute in a 2D array the state of the system from a previous state and a transition function. Each entry will take a float value between 0 and 1 (or more conveniently a byte between 0 and 255), and I wonder how I could draw an image by coloring each pixel in shades of grey from each value in this array. Then I want to redraw the image after each (or some) time step.

The dynamic aspect of this drawing project brought me here, but I struggle to find a starting point (I’ve read a bit about textures but I haven’t found how to build it from my array yet). Could you confirm or disconfirm my idea to use OpenGL for this application ? Do you have some hints to begin in the right direction ?

Thank you for your help.[/QUOTE]

That sounds like something you would use opengl for.

As a tip, you would not use a texture when making something a shade of grey. You can just have vertex attributes [x,y,grayscale] and convert the grayscale to RGB in your fragment shader

starting point:
first you have to understand the “graphics pipeline” or how the data flows / gets processed
the best way is to do tutorials and at the same time reading a (good & understandable) book, as well as reading the opengl wiki

after you have undestood how to draw a quad / triangle / etc, adding a texture isnt very hard:

  1. generate one, set the necessary basic parameters for it, and allocate memory + fill the memory with your image data

  2. to have access to that texture, bind it to any available “texture unit” and tell your fragment shader from what texture unit to read the image data

  3. delete the texture if you dont need it anymore

  4. example code to generatet a RGBA texture (8bits per channel)


// creating a texture
unsigned int texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

// set necessary texture parameters
glTexParameteri(GL_TEXTURE_2D,        GL_TEXTURE_WRAP_S,            GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,        GL_TEXTURE_WRAP_T,            GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,        GL_TEXTURE_MIN_FILTER,        GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,        GL_TEXTURE_MAG_FILTER,    GL_LINEAR);

// allocate memory and set texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

“data” is the pointer to your “byte array”
“GL_UNSIGNED_BYTE” says that your image data has 1 byte pre channel (R, G, B and A)
“GL_RGBA” says that your image has 4 channels (R, G, B and A)

so basically your image data has pixels like that:


struct Pixel {
unsigned char R, G, B, A;
};

  1. bind texture to a texture unit:

unsigned int textureunit = 1;

// assign texture unit to the sampler2D in the fragment shader
int variablelocation = glGetUniformLocation(program, "image1");
glProgramUniform1i(program, variablelocation, textureunit);

// bind texture to that unit
glActiveTexture(GL_TEXTURE0 + textureunit);
glBindTexture(GL_TEXTURE_2D, texture);

“program” is your program object which contains all your shaders (at least vertex shader + fragment shader)

  1. delete texture

glDeleteTextures(1, &texture);

to have access in your fragment shader to that texture:


// source code of fragment shader

uniform sampler2D image1;

void main() {
// read pixel color at certain location:
vec4 pixelcolor = texture(image1, sometexturecoordinates);

// ...
}

“sometexturecoordinates” describes the location from which you want to read the image pixel
it is a 2-dimensional float vector (vec2), [0, 1] x [0, 1], the origin it the upper left corner
if your texture coordinate exceeds these boundaries, then some “texture parameters” will describe how to fetch the “texel” (~= pixel)

“GL_CLAMP_TO_EDGE” says:
– if the texture coordinate < 0, it will read from 0
– if the texture coordinate > 1, it will read from 1

I would suggest not using a texture. Instead, send the color for each cell in a VBO.
I assume the positions of your cells on screen are static. In this case you can have separate buffers for the positions and colors and you only have to update the color buffer every now and then.

Just like other posters said, you don’t need to use textures for this.

If you use OpenGL the “old” way, I mean, by using glVertex, glTexCoord and so on, then just use glColor3f(grey,grey,grey).

OpenGL is certainly capable of doing this, but it may be overkill for such a simple task.

Texture mapping is covered in chapter 9 of the red book.

For a grey-scale texture (one byte per pixel), you should use GL_LUMINANCE as the format, rather than e.g. GL_RGB or GL_RGBA.