C语言 如何将一个透明的表面blit到屏幕上,即不显示它

4xrmg8kj  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(111)

我在找哪个频道是阿尔法频道.
但是每次我把我认为应该是完全透明的表面用位图显示出来的时候,它也会修改RGB通道。
SDL 1.2-主要
下面是我的代码和我遇到的问题:

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
int main(int argc, char** argv) {
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) == -1) {
        fprintf(stderr, "Couldn't initialize SDL: %s.\n", SDL_GetError());
        exit(-1);
    }

    SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
    if(!modes) {
        printf(":(\n");
        return 1;
    }
    
    SDL_Surface* screen = SDL_SetVideoMode(modes[0]->w, modes[0]->h, 0, SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF);
    if(!screen) {
        printf(":(\n");
        return 1;
    }

    SDL_Surface* surface = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA, 32, 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
    if(!surface) {
        printf(":((\n");
        return 1;
    }

    for(int i=0; i!=32; i++) {
        for(int j=0; j!=32; j++) {
            // 0 blue
            // 1 green
            // 2 red
            // 3 alpha?
            ((char*)(surface->pixels))[0+i*4*32+j*4] = 0xff;
            ((char*)(surface->pixels))[1+i*4*32+j*4] = 0xff;
            ((char*)(surface->pixels))[2+i*4*32+j*4] = 0xff;
((char*)(surface->pixels))[3+i*4*32+j*4] = 0xff; // SDL_OPAQUE_ALPHA is 0xFF

            // not an alpha channel
        }
    }
    int ret = SDL_BlitSurface(surface, NULL, screen, NULL);

SDL_Flip(screen);
sleep(2);

    for(int i=0; i!=32; i++) {
        for(int j=0; j!=32; j++) {
            // 0 blue
            // 1 green
            // 2 red
            // 3 alpha?
            ((char*)(surface->pixels))[0+i*4*32+j*4] = 0x30;
            ((char*)(surface->pixels))[1+i*4*32+j*4] = 0x40;
            ((char*)(surface->pixels))[2+i*4*32+j*4] = 0x50;
((char*)(surface->pixels))[3+i*4*32+j*4] = 0x00;// This surface should be transparent, SDL_TRANSPARENT_ALPHA is 0

            // not an alpha channel
        }
    }
    int ret = SDL_BlitSurface(surface, NULL, screen, NULL);
    
    while(1) {
        SDL_Flip(screen);
//if the color is anything but pure white, alpha channel modification failed.
    }
}

我基本上需要这段代码来处理字体。现在我为每个字形做一个表面(是的,我应该做别的事情)。我需要能够将alpha通道设置为表面的值,并保证如果alpha设置为部分/完全透明,纹理的RGB值不会被块传输。

s4chpxco

s4chpxco1#

请考虑以下示例:

void main(void) {
    unsigned int t = 0x000000ff;
    unsigned char *ct = (unsigned char*)&t;
    printf("0x%x 0x%x 0x%x 0x%x\n", ct[0], ct[1], ct[2], ct[3]);
}

在小字节序机器上(即现在的大多数机器),它将输出0xff 0x0 0x0 0x0。您将alpha掩码设置为0x000000ff,这意味着当您访问像素时,alpha通道的字节偏移为0(即在内存中,它被放置为A,B,G,R)。
在big-endian机器上,输出将是0x0 0x0 0x0 0xff,因为整数中的字节顺序是相反的(内存中的R、G、B、A)。
如果您查看SDL 1.2 documentation for SDL_CreateRGBSurface,您可能会注意到示例代码检查SDL_BYTEORDER并在创建曲面时反转掩码以保持一致的字节顺序。
您已经在创建曲面时设置了SDL_SRCALPHA标志,因此不需要SDL_SetAlpha;但是,当您设置表面值时,您将alpha值设置为不正确偏移量,因为alpha的偏移量为0(如果您使用的是小字节序机器)。

相关问题