Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_draw.c
| Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| #include "IMB_imbuf.h" | #include "IMB_imbuf.h" | ||||
| #include "IMB_imbuf_types.h" | #include "IMB_imbuf_types.h" | ||||
| #include "BKE_colorband.h" | #include "BKE_colorband.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_movieclip.h" | |||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "GPU_draw.h" | #include "GPU_draw.h" | ||||
| #include "GPU_extensions.h" | #include "GPU_extensions.h" | ||||
| #include "GPU_glew.h" | #include "GPU_glew.h" | ||||
| #include "GPU_material.h" | #include "GPU_material.h" | ||||
| #include "GPU_matrix.h" | #include "GPU_matrix.h" | ||||
| ▲ Show 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { | ||||
| compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace); | compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace); | ||||
| rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__); | rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__); | ||||
| if (rect == NULL) { | if (rect == NULL) { | ||||
| return bindcode; | return bindcode; | ||||
| } | } | ||||
| /* Texture storage of images is defined by the alpha mode of the image. The | /* Texture storage of images is defined by the alpha mode of the image. The | ||||
| * downside of this is that there can be artifacts near alpha edges. However, | * downside of this is that there can be artifacts near alpha edges. However, | ||||
jbakker: Merge with `gpu_get_image_gputexture` code | |||||
| * this allows us to use sRGB texture formats and preserves color values in | * this allows us to use sRGB texture formats and preserves color values in | ||||
| * zero alpha areas, and appears generally closer to what game engines that we | * zero alpha areas, and appears generally closer to what game engines that we | ||||
| * want to be compatible with do. */ | * want to be compatible with do. */ | ||||
| const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); | const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true; | ||||
| IMB_colormanagement_imbuf_to_byte_texture( | IMB_colormanagement_imbuf_to_byte_texture( | ||||
| rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); | rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Float image is already in scene linear colorspace or non-color data by | /* Float image is already in scene linear colorspace or non-color data by | ||||
| * convention, no colorspace conversion needed. But we do require 4 channels | * convention, no colorspace conversion needed. But we do require 4 channels | ||||
| * currently. */ | * currently. */ | ||||
| const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); | const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false; | ||||
| if (ibuf->channels != 4 || !store_premultiplied) { | if (ibuf->channels != 4 || !store_premultiplied) { | ||||
| rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); | rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); | ||||
| if (rect_float == NULL) { | if (rect_float == NULL) { | ||||
| return bindcode; | return bindcode; | ||||
| } | } | ||||
| IMB_colormanagement_imbuf_to_float_texture( | IMB_colormanagement_imbuf_to_float_texture( | ||||
| rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); | rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); | ||||
| } | } | ||||
| } | } | ||||
| /* Create OpenGL texture. */ | /* Create OpenGL texture. */ | ||||
| GPU_create_gl_tex(&bindcode, | GPU_create_gl_tex(&bindcode, | ||||
| (uint *)rect, | (uint *)rect, | ||||
| Show All 11 Lines | #endif | ||||
| } | } | ||||
| if (rect_float && rect_float != ibuf->rect_float) { | if (rect_float && rect_float != ibuf->rect_float) { | ||||
| MEM_freeN(rect_float); | MEM_freeN(rect_float); | ||||
| } | } | ||||
| return bindcode; | return bindcode; | ||||
| } | } | ||||
| static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, | |||||
| MovieClipUser *cuser, | |||||
| GLenum textarget) | |||||
| { | |||||
| MovieClip_RuntimeGPUTexture *tex; | |||||
| for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { | |||||
| if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (tex == NULL) { | |||||
| tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__); | |||||
| for (int i = 0; i < TEXTARGET_COUNT; i++) { | |||||
| tex->gputexture[i] = NULL; | |||||
| } | |||||
| memcpy(&tex->user, cuser, sizeof(MovieClipUser)); | |||||
| BLI_addtail(&clip->runtime.gputextures, tex); | |||||
| } | |||||
| if (textarget == GL_TEXTURE_2D) | |||||
| return &tex->gputexture[TEXTARGET_TEXTURE_2D]; | |||||
| else if (textarget == GL_TEXTURE_CUBE_MAP) | |||||
| return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP]; | |||||
| return NULL; | |||||
| } | |||||
| static void gpu_texture_update_scaled( | static void gpu_texture_update_scaled( | ||||
| uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h) | uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h) | ||||
| { | { | ||||
| /* Partial update with scaling. */ | /* Partial update with scaling. */ | ||||
| int limit_w = smaller_power_of_2_limit(full_w); | int limit_w = smaller_power_of_2_limit(full_w); | ||||
| int limit_h = smaller_power_of_2_limit(full_h); | int limit_h = smaller_power_of_2_limit(full_h); | ||||
| float xratio = limit_w / (float)full_w; | float xratio = limit_w / (float)full_w; | ||||
| float yratio = limit_h / (float)full_h; | float yratio = limit_h / (float)full_h; | ||||
| ▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget) | ||||
| bindcode = gpu_texture_create_from_ibuf(ima, ibuf, textarget); | bindcode = gpu_texture_create_from_ibuf(ima, ibuf, textarget); | ||||
| BKE_image_release_ibuf(ima, ibuf, NULL); | BKE_image_release_ibuf(ima, ibuf, NULL); | ||||
| *tex = GPU_texture_from_bindcode(textarget, bindcode); | *tex = GPU_texture_from_bindcode(textarget, bindcode); | ||||
| return *tex; | return *tex; | ||||
| } | } | ||||
| GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget) | |||||
| { | |||||
| if (clip == NULL) { | |||||
| return NULL; | |||||
| } | |||||
| GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget); | |||||
| if (*tex) { | |||||
| return *tex; | |||||
| } | |||||
| /* check if we have a valid image buffer */ | |||||
| uint bindcode = 0; | |||||
| ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); | |||||
| if (ibuf == NULL) { | |||||
| *tex = GPU_texture_from_bindcode(textarget, bindcode); | |||||
| return *tex; | |||||
| } | |||||
| bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget); | |||||
| IMB_freeImBuf(ibuf); | |||||
| *tex = GPU_texture_from_bindcode(textarget, bindcode); | |||||
| return *tex; | |||||
| } | |||||
| void GPU_free_texture_movieclip(struct MovieClip *clip) | |||||
| { | |||||
| /* number of gpu textures to keep around as cache | |||||
| * We don't want to keep too many GPU textures for | |||||
| * movie clips around, as they can be large.*/ | |||||
| const int MOVIECLIP_NUM_GPUTEXTURES = 1; | |||||
| while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { | |||||
| MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures); | |||||
| for (int i = 0; i < TEXTARGET_COUNT; i++) { | |||||
| /* free glsl image binding */ | |||||
| if (tex->gputexture[i]) { | |||||
| GPU_texture_free(tex->gputexture[i]); | |||||
| tex->gputexture[i] = NULL; | |||||
| } | |||||
| } | |||||
| MEM_freeN(tex); | |||||
| } | |||||
| } | |||||
| static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth) | static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth) | ||||
| { | { | ||||
| size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]); | size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]); | ||||
| void **sides = NULL; | void **sides = NULL; | ||||
| int h = recth / 2; | int h = recth / 2; | ||||
| int w = rectw / 3; | int w = rectw / 3; | ||||
| if (w != h) { | if (w != h) { | ||||
| ▲ Show 20 Lines • Show All 1,077 Lines • Show Last 20 Lines | |||||
Merge with gpu_get_image_gputexture code