glDrawPixels(...) and alpha blending c++

Started by
4 comments, last by Koshmaar 18 years, 7 months ago
I have a question about glDrawPixels(...), I can't find any documentation that says it supports alpha blending, though it does support a number of other features , including pixel formats that include alpha values. So I'm looking for a definative yes or no, if yes, could you show me what I'm doing wrong? If no, I have a few follow up questions.


void BasicLibrary::drawImage(float X, float Y, Image *IMG)
{
  if(IMG->loaded==false)
  {return;}
  
  if(IMG->isAlphaOn())
  {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
    glRasterPos2f(TransXpt(X), TransYpt(Y));
    glDrawPixels((int)IMG->xSize, (int)IMG->ySize, GL_RGBA, GL_UNSIGNED_BYTE, &IMG->pixelData[0]);
    glDisable(GL_BLEND);
  }
  else
  {
    glRasterPos2f(TransXpt(X), TransYpt(Y));
    glDrawPixels((int)IMG->xSize, (int)IMG->ySize, GL_RGB, GL_UNSIGNED_BYTE, &IMG->pixelData[0]);
  }
}

The result of this code is the pixel image drawn to the screen without any blending effects.
Advertisement
According to the Red Book:

"(...)When using glDrawPixels() to write RGBA or color-index information, you may need to control the current drawing buffers with glDrawBuffer(), which, along with glReadBuffer(), is also described in "Selecting Color Buffers for Writing and Reading" in Chapter 10.(...)"

"(...)To paint with a circular brush in blue, repeatedly draw a blue square with glDrawPixels() where the alpha values are largest in the center and taper to zero at the edges of a circle centered in the square. Draw using a blending function that uses alpha of the incoming color and (1-alpha) of the color already at the pixel.(...)"


So it looks that alpha blending is supported by this function.

Forgetting for a while about first quote: maybe your problem is caused by fact, that you read the image without its alpha channel? Dunno, I don't see any obvious errors in your source code.


Btw, in terms of performance, it would be much better to change your Image to OGL texture, change view to ortographical and then render quad with stretched over it texture. I can show you even some code if you want :-)
Ahh thanks!

Yes, my image data isn't read with an alpha channel. However, I add one through some code.

void Image::addAlphaComponent(){  if(alphaOn == true)  {return;}    else  {alphaOn=true;}    int imageSize = xSize * ySize * 3;  int totalSize = xSize * ySize * 4;  int k = 0;  vector<unsigned char> tmp;  tmp.resize(totalSize);    for(int i=0;i<imageSize;i+=3, k+=4)  {    tmp[k + 0] = pixelData;<br>    tmp[k + <span class="cpp-number">1</span>] = pixelData;<br>    tmp[k + <span class="cpp-number">2</span>] = pixelData;<br>    <br>    tmp[k + <span class="cpp-number">3</span>] = (<span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">char</span>) <span class="cpp-number">255</span>;<br>  } <br>  pixelData.resize(totalSize);<br>  <br>  <span class="cpp-keyword">for</span>(<span class="cpp-keyword">int</span> i=<span class="cpp-number">0</span>;i&lt;totalSize;++i)<br>  {<br>    pixelData<span style="font-weight:bold;"> = tmp<span style="font-weight:bold;">;<br>  }<br>}<br><br></pre></div><!–ENDSCRIPT–><br><br>Basically, I think it works because it doesn't make the image distort or anything.  Yes, that code would assign an alpha value that would make it appear solid.  I change the alpha value in some other code.<br><br>I was thinking about using the image data as a texture, then rendering an quad using said texture.  At this point in time though, I wouldn't be storing the texture index.  Would be ok if every frame I remake the texture using the image data?  I might be manipulating it a lot (i.e adding removing alpha, flipping horizontally/vertically, swapping red blue values, etc) and would I suffer super performance problems doing so?
Quote:I was thinking about using the image data as a texture, then rendering an quad using said texture. At this point in time though, I wouldn't be storing the texture index. Would be ok if every frame I remake the texture using the image data? I might be manipulating it a lot (i.e adding removing alpha, flipping horizontally/vertically, swapping red blue values, etc) and would I suffer super performance problems doing so?


It would be OK, but it would be also horribly slow :-) But, AFAIK, you don't need to re-create texture in every frame, since you can *change texture* using glDrawPixels.

Other things:

- why on Earth would you be adding / removing alpha to the same picture every frame? Calling just glEnable / glDisable GL_BLEND wouldn't be sufficent?

- flipping horizontally/vertically is very (and I mean very) simple to do with textures - you get it for free, as well as rotation, stretching, alpha blending (blending only to some extent) etc.

- swapping red blue values - just like in the first paragraph, you could use glReadPixels / glDrawPixels to alter those channels. OTOH, such operation, will be horribly slow - and AFAIK it doesn't matter if you do it on screen or texture.


Btw, for your last loop:

for(int i=0;i<totalSize;++i)
{
pixelData = tmp;
}

it will be faster if you will use memcpy.
Seems like I need to investigate the capabilities of textures more. If I can make it them do all that, makes my code I wrote for my Image class obsolete, but in a good way. :)

I'm under the impression that memcpy didn't work for vectors because the memory involved isn't necessarily consecutive. Never tried it though. Much to consider, thanks!
No prob :-)

Yes, I suggest to try textures - IMHO they are very easy to work with, have good capabilities and outstanding performance.

In all cases, std :: vectors are implemented internally by normal arrays - and they are contiguous. Read more.

This topic is closed to new replies.

Advertisement