Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2012-01-17 20:31:13 +0400
committerAntony Riakiotakis <kalast@gmail.com>2012-01-17 20:31:13 +0400
commita8081c1d2bb9115833493b011bb93d6c08112b2d (patch)
tree4383d080b80786257b291068e48a06bdb0ef5bd6 /source/blender/gpu
parentfcc54520d1f029b86cb8c6f43c239ef81090a99a (diff)
Uv Tools branch GSOC 2011
========================= Documentation: http://wiki.blender.org/index.php/User:Psy-Fi/UV_Tools Major features include: *16 bit image support in viewport *Subsurf aware unwrapping *Smart Stitch(snap/rotate islands, preview, middlepoint/endpoint stitching) *Seams from islands tool (marks seams and sharp, depending on settings) *Uv Sculpting(Grab/Pinch/Rotate) All tools are complete apart from stitching that is considered stable but with an extra edge mode under development(will be in soc-2011-onion-uv-tools).
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_draw.c156
1 files changed, 118 insertions, 38 deletions
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 5d36ba169f3..59802f2cf58 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -410,9 +410,12 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
ImBuf *ibuf = NULL;
unsigned int *bind = NULL;
int rectw, recth, tpx=0, tpy=0, y;
- unsigned int *rectrow, *tilerectrow;
unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
+ float *ftilerect= NULL, *fscalerect = NULL, *frect = NULL;
+ float *srgb_frect = NULL;
short texwindx, texwindy, texwinsx, texwinsy;
+ /* flag to determine whether high resolution format is used */
+ int use_high_bit_depth = FALSE, do_color_management = FALSE;
/* initialize tile mode and number of repeats */
GTS.ima = ima;
@@ -462,9 +465,20 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if(ibuf==NULL)
return 0;
- /* ensure we have a char buffer and not only float */
- if ((ibuf->rect==NULL) && ibuf->rect_float)
- IMB_rect_from_float(ibuf);
+ if(ibuf->rect_float) {
+ if(U.use_16bit_textures) {
+ /* use high precision textures. This is relatively harmless because OpenGL gives us
+ a high precision format only if it is available */
+ use_high_bit_depth = TRUE;
+ }
+
+ /* TODO unneeded when float images are correctly treated as linear always */
+ if(ibuf->profile == IB_PROFILE_LINEAR_RGB)
+ do_color_management = TRUE;
+
+ if(ibuf->rect==NULL)
+ IMB_rect_from_float(ibuf);
+ }
/* currently, tpage refresh is used by ima sequences */
if(ima->tpageflag & IMA_TPAGE_REFRESH) {
@@ -498,17 +512,39 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
tpx= texwindx;
tpy= texwindy;
- rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
+ if(use_high_bit_depth) {
+ if(do_color_management) {
+ srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(float)*4, "floar_buf_col_cor");
+ IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
+ ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0,
+ ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ frect= srgb_frect + texwinsy*ibuf->x + texwinsx;
+ }
+ else
+ frect= ibuf->rect_float + texwinsy*ibuf->x + texwinsx;
+ }
+ else
+ rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
}
}
else {
/* regular image mode */
bind= &ima->bindcode;
-
+
if(*bind==0) {
tpx= ibuf->x;
tpy= ibuf->y;
rect= ibuf->rect;
+ if(use_high_bit_depth) {
+ if(do_color_management) {
+ frect = srgb_frect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(*srgb_frect)*4, "floar_buf_col_cor");
+ IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float,
+ ibuf->channels, IB_PROFILE_SRGB, ibuf->profile, 0,
+ ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ }
+ else
+ frect= ibuf->rect_float;
+ }
}
}
@@ -523,26 +559,57 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
/* for tiles, copy only part of image into buffer */
if (GTS.tilemode) {
- tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
+ if(use_high_bit_depth) {
+ float *frectrow, *ftilerectrow;
- for (y=0; y<recth; y++) {
- rectrow= &rect[y*ibuf->x];
- tilerectrow= &tilerect[y*rectw];
-
- memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
+ ftilerect= MEM_mallocN(rectw*recth*sizeof(*ftilerect), "tilerect");
+
+ for (y=0; y<recth; y++) {
+ frectrow= &frect[y*ibuf->x];
+ ftilerectrow= &ftilerect[y*rectw];
+
+ memcpy(ftilerectrow, frectrow, tpx*sizeof(*frectrow));
+ }
+
+ frect= ftilerect;
}
+ else {
+ unsigned int *rectrow, *tilerectrow;
+
+ tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
+
+ for (y=0; y<recth; y++) {
+ rectrow= &rect[y*ibuf->x];
+ tilerectrow= &tilerect[y*rectw];
+
+ memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
+ }
- rect= tilerect;
+ rect= tilerect;
+ }
}
- /* scale if not a power of two */
+ /* scale if not a power of two. this is not strictly necessary for newer
+ GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures */
if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
rectw= smaller_pow2_limit(rectw);
recth= smaller_pow2_limit(recth);
- scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
- gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
- rect= scalerect;
+ if(use_high_bit_depth) {
+ fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
+ gluScaleImage(GL_RGBA, tpx, tpy, GL_FLOAT, frect, rectw, recth, GL_FLOAT, fscalerect);
+ /* frect will refer to ibuf->rect_float when not color converting. We don't want to free that */
+ if(do_color_management)
+ MEM_freeN(frect);
+
+ frect = fscalerect;
+ }
+ else {
+ scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
+ gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+
+ rect= scalerect;
+ }
}
/* create image */
@@ -550,12 +617,18 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
glBindTexture( GL_TEXTURE_2D, *bind);
if (!(gpu_get_mipmap() && mipmap)) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ if(use_high_bit_depth)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
}
else {
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ if(use_high_bit_depth)
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
+ else
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
@@ -570,9 +643,14 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
/* clean up */
if (tilerect)
MEM_freeN(tilerect);
+ if (ftilerect)
+ MEM_freeN(ftilerect);
if (scalerect)
MEM_freeN(scalerect);
-
+ if (fscalerect)
+ MEM_freeN(fscalerect);
+ if (srgb_frect)
+ MEM_freeN(srgb_frect);
return *bind;
}
@@ -692,23 +770,21 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
- if (ibuf->rect_float){
- /*This case needs a whole new buffer*/
- if(ibuf->rect==NULL) {
- IMB_rect_from_float(ibuf);
- }
- else {
- /* Do partial drawing. 'buffer' holds only the changed part. Needed for color corrected result */
- float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
- IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
- glBindTexture(GL_TEXTURE_2D, ima->bindcode);
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ /* if color correction is needed, we must update the part that needs updating. */
+ if(ibuf->rect_float && (!U.use_16bit_textures || (ibuf->profile == IB_PROFILE_LINEAR_RGB))) {
+ float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
+ IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
GL_FLOAT, buffer);
- MEM_freeN(buffer);
- if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
- ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
- return;
- }
+
+ MEM_freeN(buffer);
+
+ if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+
+ return;
}
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
@@ -717,8 +793,12 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
- GL_UNSIGNED_BYTE, ibuf->rect);
+ if(ibuf->rect_float)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ GL_FLOAT, ibuf->rect_float);
+ else
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ GL_UNSIGNED_BYTE, ibuf->rect);
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);