OpenGL着色器语言4.1.7.2(图片类型)-4.1.8(结构体类型)

4..1.7.2 图片

图片类型是不透明类型,声明和表现如上所述。它们可以被使用内存限定符进一步限定。当被组装进一个着色器中的数组中时,图片只能通过一个uniform整式被查找,否则结果是undefined.

图片变量有处理所有或 绑定到一个图片单元的纹理图片的一个级别的一部分的1,2,3维的图片。每种纹理类型有不同的图片类型对应那些级别绑定到图片单元的纹理 的目标,或无层的3D绑定或者图片数组应该使用那些与图片(例如,3D的一个层,2D数组,立方体,或者立方体数组应该使用image2D,1D数组应该使用imageID,2DMS数组的一个层应该使用image2DMS)。层的维度对应的图片类型。如果图片目标类型不以这种方式与绑定的图片对应,如果数据类型与绑定的图片不匹配,又或者格式化布局限定符与8.25节“纹理图片加载与存储”中描述的图片单元格式匹配,则对图片访问的结果是undefined但是不会引起程序终止


图片变量用于图片加载,存储,和8.12节“图片函数”中描述的原子函数指定一个要访问的图片。


4.1.7.3 原子计数器

原子计数器类型(atomic_unit)是对计数器的不透明处理,定义和表现如上对不透明类型所述。这些变量声明指定当使用如8.10节“原子计数函数”中描述的内置原子计数函数时访问哪个计数器。 它们按照  4.4.6.1节中“原子计数器布局限定符”所描述 的方式绑定到缓冲区。当被组装进一个着色器中的数组中时,原子计数器只能通过uniform整式查找,否则将返回undefined。结构体成员不可以被声明为原子计数器类型。


4.1.8 结构体

用户自定义类型可以通过使用关键字struct,将其它已定义的类型组合到结构体中来创建。

例如

struct light {
float intensity;
vec3 position;
} lightVar;

在这个例子中,light变为一个新类型的名字,并且lightVar变为一个light类型的变量。声明这个新类型的变量,可以使用它的名字(不使用struct关键字)

light lightVar2;

更正式的讲,结构体按照如下形式声明。完全正确的语法在第9节“着色器语法”中被给出。

结构体定义:

限定符(可选)struct 名称(可选){成员列表}被声明的变量(可选);

成员列表:

成员声明;

成员声明 成员列表

成员声明:

基本类型声明的变量;

名称变为新的用户自定义类型,并且可以用于声明新类型的变量。

这个名称与其他名称共享名字空间,类型和函数。所有之前的可见的变量,类型,构造函数,或者函数都变为隐藏的。限定符选项只提供给被声明的变量,并且不是被定义类型名字的一部分。

结构体最少要有一个成员成名。成员声明变量可以包含精度限定符,使用其它任何一种限定符都会产生一个编译期错误。不支持位字段。成员类型必须是已经被定义的。

如果成员变量声明时被初始化,会产生一个编译期错误。成员变量可以包含数组。这样的一个数组必须指定大小,并且这个大小必须是一个大于0的整型常量表达式(见4.3.3"常量表达式")。每个级别的结构体有其自己的名字空间,在成员变量中被给定。这样的名字在名字空间中应该是唯一的。

不支持匿名结构体。也不支持内嵌结构体。这些都会产生一个编译期错误。

struct S { float f; };
struct T {
S; //错误: 不允许匿名结构体
struct { ... }; // 错误: 不允许有内嵌结构体
S s; // 可以: 使用名字的嵌套结构体是允许的。
};

结构体可以再声明时通过构造函数被初始化,在5.4.3节”结构体构造函数“中进行描述。


任何关于一个类型或限定符的限制,也同样适用于任何包含一个次类型成员的结构体。这也递归地适用于成员类型是结构体的结构体。




PS:今天玩的比较晚,先少翻点,最近感觉此说明书中有大量的专属名词,需要在理解全部说明书后,回头修改,有很多翻译必然有错误,或者成篇不通顺的地方。最终在全书翻译完后,都会统一过一次。进行修正。部分非常不通顺和难于理解的部分已经使用红色标记出来。便于后续优先修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用ffmpeg4.1.8版本库实现音频解码为wav格式的代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/avutil.h> #include <libavutil/opt.h> #include <libswresample/swresample.h> int main(int argc, char **argv) { AVFormatContext *fmt_ctx = NULL; AVCodecContext *dec_ctx = NULL; AVCodec *dec = NULL; AVPacket pkt; AVFrame *frame = NULL; int stream_idx = -1; int ret = 0; int got_frame = 0; char *input_file = NULL; char *output_file = NULL; FILE *outfile = NULL; SwrContext *swr_ctx = NULL; uint8_t **dst_data = NULL; int dst_linesize; int dst_nb_samples; int max_dst_nb_samples; int dst_bufsize; int nb_channels; int dst_nb_channels; int src_rate, dst_rate; int src_layout, dst_layout; int src_nb_samples, dst_nb_samples_per_channel; int64_t src_ch_layout, dst_ch_layout; if (argc != 3) { fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]); exit(1); } input_file = argv[1]; output_file = argv[2]; av_register_all(); if ((ret = avformat_open_input(&fmt_ctx, input_file, NULL, NULL)) < 0) { fprintf(stderr, "Could not open input file '%s': %s\n", input_file, av_err2str(ret)); exit(1); } if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) { fprintf(stderr, "Could not find stream information: %s\n", av_err2str(ret)); exit(1); } av_dump_format(fmt_ctx, 0, input_file, 0); for (int i = 0; i < fmt_ctx->nb_streams; i++) { if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { stream_idx = i; break; } } if (stream_idx == -1) { fprintf(stderr, "Could not find audio stream in the input file\n"); exit(1); } dec = avcodec_find_decoder(fmt_ctx->streams[stream_idx]->codecpar->codec_id); if (!dec) { fprintf(stderr, "Failed to find codec\n"); exit(1); } dec_ctx = avcodec_alloc_context3(dec); if (!dec_ctx) { fprintf(stderr, "Failed to allocate codec context\n"); exit(1); } if ((ret = avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[stream_idx]->codecpar)) < 0) { fprintf(stderr, "Failed to copy codec parameters to codec context: %s\n", av_err2str(ret)); exit(1); } if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) { fprintf(stderr, "Failed to open codec: %s\n", av_err2str(ret)); exit(1); } frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Failed to allocate frame\n"); exit(1); } av_init_packet(&pkt); if ((ret = avformat_seek_file(fmt_ctx, -1, INT64_MIN, 0, INT64_MAX, 0)) < 0) { fprintf(stderr, "Failed to seek to beginning of file: %s\n", av_err2str(ret)); exit(1); } if (!(outfile = fopen(output_file, "wb"))) { fprintf(stderr, "Could not open output file '%s': %s\n", output_file, strerror(errno)); exit(1); } nb_channels = av_get_channel_layout_nb_channels(dec_ctx->channel_layout); src_rate = dec_ctx->sample_rate; src_layout = dec_ctx->channel_layout; src_nb_samples = dec_ctx->frame_size; dst_rate = src_rate; dst_layout = AV_CH_LAYOUT_STEREO; dst_nb_channels = av_get_channel_layout_nb_channels(dst_layout); dst_nb_samples_per_channel = av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP); max_dst_nb_samples = dst_nb_samples_per_channel; dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels, max_dst_nb_samples, AV_SAMPLE_FMT_S16, 1); dst_data = (uint8_t **)calloc(dst_nb_channels, sizeof(*dst_data)); if (!dst_data) { fprintf(stderr, "Failed to allocate memory for destination data\n"); exit(1); } if ((ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels, max_dst_nb_samples, AV_SAMPLE_FMT_S16, 1)) < 0) { fprintf(stderr, "Failed to allocate destination samples: %s\n", av_err2str(ret)); exit(1); } swr_ctx = swr_alloc_set_opts(NULL, dst_layout, AV_SAMPLE_FMT_S16, dst_rate, src_layout, dec_ctx->sample_fmt, src_rate, 0, NULL); if (!swr_ctx) { fprintf(stderr, "Failed to allocate resampler context\n"); exit(1); } if ((ret = swr_init(swr_ctx)) < 0) { fprintf(stderr, "Failed to initialize resampler context: %s\n", av_err2str(ret)); exit(1); } while (av_read_frame(fmt_ctx, &pkt) >= 0) { if (pkt.stream_index == stream_idx) { ret = avcodec_send_packet(dec_ctx, &pkt); if (ret < 0) { fprintf(stderr, "Error sending a packet for decoding: %s\n", av_err2str(ret)); exit(1); } while (ret >= 0) { ret = avcodec_receive_frame(dec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { fprintf(stderr, "Error during decoding: %s\n", av_err2str(ret)); exit(1); } if (frame->channels != nb_channels || frame->sample_rate != src_rate || frame->format != dec_ctx->sample_fmt) { fprintf(stderr, "Error: input audio parameters have changed\n"); exit(1); } dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) + frame->nb_samples, dst_rate, src_rate, AV_ROUND_UP); if (dst_nb_samples > max_dst_nb_samples) { av_free(dst_data[0]); ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, AV_SAMPLE_FMT_S16, 1); if (ret < 0) { fprintf(stderr, "Failed to allocate destination samples: %s\n", av_err2str(ret)); exit(1); } max_dst_nb_samples = dst_nb_samples; dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels, max_dst_nb_samples, AV_SAMPLE_FMT_S16, 1); } ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)frame->data, frame->nb_samples); if (ret < 0) { fprintf(stderr, "Error while converting\n"); exit(1); } fwrite(dst_data[0], 1, dst_bufsize, outfile); } } av_packet_unref(&pkt); } fclose(outfile); avcodec_free_context(&dec_ctx); avformat_close_input(&fmt_ctx); av_frame_free(&frame); swr_free(&swr_ctx); av_free(dst_data[0]); free(dst_data); return 0; } ``` 这段代码可以将音频解码为WAV格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值