首页 > 解决方案 > OpenGL single channel viability to multiple channel

问题描述

When I rasterize out a font, my code gives me a single channel of visability for a texture. Currently, I just duplicate this out to 4 different channels, and send that as a texture. Now this works, but I want to try and avoid unnecessary memory allocations and de-alocations on the cpu.

unsigned char *bitmap = new unsigned char[width*height] //How this is populated is not the point.

bitmap, now contains a 2d graphic.

It seems this guy also has the same problem: Opengl: Use single channel texture as alpha channel to display text

I do the same thing as a work around for now, where I just multiply the array size by 4 and copy the data into it 4 times.

unsigned char* colormap = new unsigned char[width * height * 4];
        int offset = 0;
        for (int d = 0; d < width * height;d++)
        {
            for (int i = 0;i < 4;i++)
            {
                colormap[offset++] = bitmap[d];
            }
        }

WHen I multiply it out, I use:

glTexParameteri(gltype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(gltype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(gltype, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, colormap);

And get:

Want

Which is what I want.

When i use only the single channel:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(gltype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(gltype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap);

And Get:

Get

It has no transparency, only red ext. makes it hard to colorize and ext. later.

Instead of having to do what I feel is a unnecessary allocations on the cpu side id like the tell OpenGL: "Hey your getting just one channel. multiply it out for all 4 color channels."

Is there a command for that?

标签: c++opengltexturesrasterizing

解决方案


In your shader, it's trivial enough to just broadcast the r component to all four channels:

vec4 vals = texture(tex, coords).rrrr;

If you don't want to modify your shader (perhaps because you need to use the same shader for 4-channel textures too), then you can apply a texture swizzle mask to the texture:

GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_RED};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);

When mechanisms read from the fourth component of the texture, they'll get the value defined by the red component of that texture.


推荐阅读