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:
-rw-r--r--source/blender/src/glutil.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c
index c64b07ae4af..5c0f1a7be89 100644
--- a/source/blender/src/glutil.c
+++ b/source/blender/src/glutil.c
@@ -286,55 +286,60 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, void *rect)
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, void *rect)
{
unsigned char *uc_rect= (unsigned char*) rect;
- float origin_x= 0.375;
- float origin_y= 0.375;
- /* Trivial case */
- if (x>=origin_x && y>=origin_y) {
- glRasterPos2f(x, y);
- glDrawPixels(img_w, img_h, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect);
- } else {
- int old_row_length= glaGetOneInteger(GL_UNPACK_ROW_LENGTH);
- float xzoom= glaGetOneFloat(GL_ZOOM_X);
- float yzoom= glaGetOneFloat(GL_ZOOM_Y);
+ float xzoom= glaGetOneFloat(GL_ZOOM_X);
+ float yzoom= glaGetOneFloat(GL_ZOOM_Y);
- /* The pixel space coordinate of the intersection of
- * the [zoomed] image with the origin.
- */
- float ix= (origin_x-x)/xzoom;
- float iy= (origin_y-y)/yzoom;
+ /* The pixel space coordinate of the intersection of
+ * the [zoomed] image with the origin.
+ */
+ float ix= -x/xzoom;
+ float iy= -y/yzoom;
- /* The maximum pixel amounts the image can cropped
- * without exceeding the origin.
- */
- int off_x= floor((ix>origin_x)?ix:origin_x);
- int off_y= floor((iy>origin_y)?iy:origin_y);
-
- /* The zoomed space coordinate of the raster
- * position.
- */
- float rast_x= x + off_x*xzoom;
- float rast_y= y + off_y*yzoom;
-
- /* We cannot zoom in larger than window size.
- * Let's assume that window size is 4 pixels minimum (ton)
- */
- if(xzoom>4.0 || yzoom>4.0) {
- GLfloat scissor[4];
- glGetFloatv(GL_SCISSOR_BOX, scissor);
-
- if( scissor[2] <= xzoom && scissor[3] <= floor(yzoom) ) {
- printf("GL error; Zoomed in too far\n");
- return;
- }
- }
+ /* The maximum pixel amounts the image can be cropped
+ * at the lower left without exceeding the origin.
+ */
+ int off_x= floor(max(ix, 0));
+ int off_y= floor(max(iy, 0));
- if (off_x<img_w && off_y<img_h) {
- glaRasterPosSafe2f(rast_x, rast_y, origin_x, origin_y);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
- glDrawPixels(img_w-off_x, img_h-off_y, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect+off_y*img_w*4+off_x*4);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length);
+ /* The zoomed space coordinate of the raster position
+ * (starting at the lower left most unclipped pixel).
+ */
+ float rast_x= x + off_x*xzoom;
+ float rast_y= y + off_y*yzoom;
+
+ GLfloat scissor[4];
+ int draw_w, draw_h;
+
+ /* Determine the smallest number of pixels we need to draw
+ * before the image would go off the upper right corner.
+ *
+ * It may seem this is just an optimization but some graphics
+ * cards (ATI) freak out if there is a large zoom factor and
+ * a large number of pixels off the screen (probably at some
+ * level the number of image pixels to draw is getting multiplied
+ * by the zoom and then clamped). Making sure we draw the
+ * fewest pixels possible keeps everyone mostly happy (still
+ * fails if we zoom in on one really huge pixel so that it
+ * covers the entire screen).
+ */
+ glGetFloatv(GL_SCISSOR_BOX, scissor);
+ draw_w = min(img_w-off_x, ceil((scissor[2]-rast_x)/xzoom));
+ draw_h = min(img_h-off_y, ceil((scissor[3]-rast_y)/yzoom));
+
+ if (draw_w>0 && draw_h>0) {
+ int old_row_length = glaGetOneInteger(GL_UNPACK_ROW_LENGTH);
+
+ /* Don't use safe RasterPos (slower) if we can avoid it. */
+ if (rast_x>=0 && rast_y>=0) {
+ glRasterPos2f(rast_x, rast_y);
+ } else {
+ glaRasterPosSafe2f(rast_x, rast_y, 0, 0);
}
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
+ glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect + (off_y*img_w + off_x)*4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length);
}
}