SDL_UpdateTexture()

=====================================================

SDL源代码分析系列文章列表:

SDL2源代码分析1:初始化(SDL_Init())

SDL2源代码分析2:窗口(SDL_Window)

SDL2源代码分析3:渲染器(SDL_Renderer)

SDL2源代码分析4:纹理(SDL_Texture)

SDL2源代码分析5:更新纹理(SDL_UpdateTexture())

SDL2源代码分析6:复制到渲染器(SDL_RenderCopy())

SDL2源代码分析7:显示(SDL_RenderPresent())

SDL2源代码分析8:视频显示总结

=====================================================

上一篇文章分析了SDL的创建纹理函数SDL_CreateTexture()。这篇文章继续分析SDL的源代码。本文分析SDL更新纹理数据函数SDL_UpdateTexture()。

SDL播放视频的代码流程如下所示。初始化:SDL_Init(): 初始化SDL。SDL_CreateWindow(): 创建窗口(Window)。SDL_CreateRenderer(): 基于窗口创建渲染器(Render)。SDL_CreateTexture(): 创建纹理(Texture)。循环渲染数据:SDL_UpdateTexture(): 设置纹理的数据。SDL_RenderCopy(): 纹理复制给渲染器。SDL_RenderPresent(): 显示。上篇文章分析了该流程中的第4个函数SDL_CreateTexture()。本文继续分析该流程中的第5个函数SDL_UpdateTexture()。SDL_UpdateTexture()函数简介SDL使用SDL_UpdateTexture()设置纹理的像素数据。SDL_UpdateTexture()的原型如下。int SDLCALL SDL_UpdateTexture(SDL_Texture * texture,const SDL_Rect * rect,const void *pixels, int pitch);

参数的含义如下。

texture:目标纹理。

rect:更新像素的矩形区域。设置为NULL的时候更新整个区域。

pixels:像素数据。

pitch:一行像素数据的字节数。

成功的话返回0,失败的话返回-1。

函数调用关系图

SDL_UpdateTexture()关键函数的调用关系可以用下图表示。

上面的图片不太清晰,更清晰的图片上传到了相册里面:

把相册里面的图片保存下来就可以得到清晰的图片。源代码分析

SDL_UpdateTexture()的源代码位于render\SDL_render.c中。如下所示。

int SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect,const void *pixels, int pitch){SDL_Renderer *renderer;SDL_Rect full_rect;CHECK_TEXTURE_MAGIC(texture, -1);if (!pixels) {return SDL_InvalidParamError("pixels");}if (!pitch) {return SDL_InvalidParamError("pitch");}if (!rect) {full_rect.x = 0;full_rect.y = 0;full_rect.w = texture->w;full_rect.h = texture->h;rect = &full_rect;}if (texture->yuv) {return SDL_UpdateTextureYUV(texture, rect, pixels, pitch);} else if (texture->native) {return SDL_UpdateTextureNative(texture, rect, pixels, pitch);} else {renderer = texture->renderer;return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);}}从源代码中可以看出,SDL_UpdateTexture()的大致流程如下。1.检查输入参数的合理性。例如像素格式是否支持,宽和高是否小于等于0等等。2.如果是一些特殊的格式,进行一定的处理:a)如果输入的像素数据是YUV格式的,则会调用SDL_UpdateTextureYUV()进行处理。b)如果输入的像素数据的像素格式不是渲染器支持的格式,则会调用SDL_UpdateTextureNative()进行处理。3.调用SDL_Render的UpdateTexture()方法更新纹理。这一步是整个函数的核心。下面我们详细看一下几种不同的渲染器的UpdateTexture ()的方法。1.Direct3DDirect3D 渲染器中对应UpdateTexture ()的函数是D3D_UpdateTexture(),它的源代码如下所示(位于render\direct3d\SDL_render_d3d.c)。static intD3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,const SDL_Rect * rect, const void *pixels, int pitch){D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;SDL_bool full_texture = SDL_FALSE;#ifdef USE_DYNAMIC_TEXTUREif (texture->access == SDL_TEXTUREACCESS_STREAMING &&rect->x == 0 && rect->y == 0 &&rect->w == texture->w && rect->h == texture->h) {full_texture = SDL_TRUE;}#endifif (!data) {SDL_SetError("Texture is not currently available");return -1;}if (D3D_UpdateTextureInternal(data->texture, texture->format, full_texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {return -1;}if (data->yuv) {/* Skip to the correct offset into the next texture */pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);if (D3D_UpdateTextureInternal(texture->format == SDL_PIXELFORMAT_YV12 ? data->vtexture : data->utexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, pixels, pitch / 2) < 0) {return -1;}/* Skip to the correct offset into the next texture */pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4);if (D3D_UpdateTextureInternal(texture->format == SDL_PIXELFORMAT_YV12 ? data->utexture : data->vtexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, pixels, pitch / 2) < 0) {return -1;}}return 0;}

伟人之所以伟大,是因为他与别人共处逆境时,

SDL_UpdateTexture()

相关文章:

你感兴趣的文章:

标签云: