Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

For reasons detailed here I need to texture a quad using a bitmap (as in, 1 bit per pixel, not an 8-bit pixmap).

Right now I have a bitmap stored in an on-device buffer, and am mounting it like so:

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BFR.G[(T+1)%2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_COLOR_INDEX, GL_BITMAP, 0);

The OpenGL spec has this to say about glTexImage2D: "If type is GL_BITMAP, the data is considered as a string of unsigned bytes (and format must be GL_COLOR_INDEX). Each data byte is treated as eight 1-bit elements..."

Judging by the spec, each bit in my buffer should correspond to a single pixel. However, the following experiments show that, for whatever reason, it doesn't work as advertised:

1) When I build my texture, I write to the buffer in 32-bit chunks. From the wording of the spec, it is reasonable to assume that writing 0x00000001 for each value would result in a texture with 1-px-wide vertical bars with 31-wide spaces between them. However, it appears blank.

2) Next, I write with 0x000000FF. By my apparently flawed understanding of the bitmap mode, I would expect that this should produce 8-wide bars with 24-wide spaces between them. Instead, it produces a white 1-px-wide bar.

3) 0x55555555 = 1010101010101010101010101010101, therefore writing this value ought to create 1-wide vertical stripes with 1 pixel spacing. However, it creates a solid gray color.

4) Using my original 8-bit pixmap in GL_BITMAP mode produces the correct animation.

I have reached the conclusion that, even in GL_BITMAP mode, the texturer is still interpreting 8-bits as 1 element, despite what the spec seems to suggest. The fact that I can generate a gray color (while I was expecting that I was working in two-tone), as well as the fact that my original 8-bit pixmap generates the correct picture, support this conclusion.

Questions:

1) Am I missing some kind of prerequisite call (perhaps for setting a stride length or pack alignment or something) that will signal to the texturer to treat each byte as 8-elements, as it suggests in the spec?

2) Or does it simply not work because modern hardware does not support it? (I have read that GL_BITMAP mode was deprecated in 3.3, I am however forcing a 3.0 context.)

3) Am I better off unpacking the bitmap into a pixmap using a shader? This is a far more roundabout solution than I was hoping for but I suppose there is no such thing as a free lunch.

share|improve this question

1 Answer 1

up vote 2 down vote accepted

While you could probably get this to work, I would say the best answer is choice #3, for several reasons.

1) GL_BITMAP is actually not deprecated in 3.3, it is full on removed. If you are doing OpenGL 3.+, I strongly advise against using deprecated functionality.

2) It is probably not going to be super fast on today's hardware anyway. (although I have no benchmarks to back this up, but I assume it is fixed-functionality that is probably emulated by the driver.)

So I would just do it in the shader. You should be able to bit shift based on texture co-ordinates, or unless texture memory is very constrained, you could probably get away with 8 bits per pixel, having 0x00 as 0 and 0xFF as 1.

If you really want to keep going along the current route, you could try using the compatibility profile instead of core.

share|improve this answer
    
If I understand you correctly, in 3.+ there is no way to have the texturer read 1-bit-per-element, and so, despite what the spec says, in practice it will read 1-byte-per-element? –  evenex_code Dec 8 '12 at 18:54
    
Well, changing compatibility profile hasn't helped, and it really appears as though the spec is misleading. I think I can take the memory hit of an extra texture to unpack my bitmap to via shader (its really the transfer time of a full-sized texture between OpenCL and OpenGL that is killing me) so I am going try this. Still, it is very strange that the spec would say one thing, and yet the API behaves in another... –  evenex_code Dec 8 '12 at 19:11
    
Upon reading your question on SO, I think you could probably optimize your openGL + openCL interaction. Look at this as a starting point: dyn-lab.com/articles/cl-gl.html. I think the reason the time acquiring the lock in OpenCL is proportional to the texture size is probably because it is waiting on the frag shader to finish processing. –  Stephan van den Heuvel Dec 8 '12 at 19:38
    
You bring up an interesting point, so while I ponder it and read over your link I would like to make note of two details: First, the transfer time is equivalent to the actual byte-size of the data. It seems like the frag shader should take the same amount of time for the same amount of elements, regardless of their actual byte-size. Second, I am switching between two buffers, and so the fact that releasing and acquiring both take the same amount of time makes me wonder if it could indeed be due to render time. –  evenex_code Dec 8 '12 at 19:47
    
Update: I have disabled all rendering and buffer binding operations in OpenGL, leaving only the kernel computation, buffer acquisition and release. Acquisition and release times are mostly unchanged (acquisition time is negligibly faster, so the issue you described may indeed have some effect). However this leads me to suspect that acquisition and release are not waiting on the frag shader. –  evenex_code Dec 8 '12 at 19:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.