RGBColor BilinearInterpolation(float x1, float y1,Image& image, ImageTexture::BorderHandlingType bh) { float r_,g_,b_; Point q1,q2,q3,q4; int px0, px1, py0, py1; px0 = (int) floor(x1); py0 = (int) floor(y1); px1 = px0 + 1; py1 = py0 + 1; if(bh == ImageTexture::REPEAT) { px1 = px1 % (int)image.width(); py1 = py1 % (int)image.height(); } else { if(px1 >= image.width()) px1 = image.width() - 1; if(py1 >= image.height()) py1 = image.height() - 1; if(px0 < 0) px0 = 0; if(py0 < 0) py0 = 0; } return lerp2d(image(px0, py0), image(px1, py0), image(px0, py1), image(px1, py1), x1 - px0, y1 - py0); }
static GLboolean verify(const TestCase &test, GLuint srcFBO, GLuint dstFBO, GLuint numChannels) { GLint srcX0 = test.srcX0; GLint srcY0 = test.srcY0; GLint srcX1 = test.srcX1; GLint srcY1 = test.srcY1; GLint dstX0 = test.dstX0; GLint dstY0 = test.dstY0; GLint dstX1 = test.dstX1; GLint dstY1 = test.dstY1; if (dstX1 < dstX0) { std::swap(srcX0, srcX1); std::swap(dstX0, dstX1); } if (dstY1 < dstY0) { std::swap(srcY0, srcY1); std::swap(dstY0, dstY1); } GLint srcDX = srcX1 - srcX0; GLint srcDY = srcY1 - srcY0; GLint dstDX = dstX1 - dstX0; GLint dstDY = dstY1 - dstY0; GLint dstW = piglit_width; GLint dstH = piglit_height; float *srcPixels = new float[test.srcH * test.srcW * numChannels]; glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO); glReadPixels(0, 0, test.srcW, test.srcH, GL_RGB, GL_FLOAT, srcPixels); float *expectedDstPixels = new float[dstH * dstW * numChannels]; for (GLint dstY = 0; dstY < dstH; ++dstY) { for (GLint dstX = 0; dstX < dstW; ++dstX) { float *dstPixel = expectedDstPixels + (dstY * dstW + dstX) * numChannels; for (GLuint c = 0; c < numChannels; ++c) { dstPixel[c] = clearColor[c]; } } } GLint dstX0clamped = std::max(dstX0, 0); GLint dstY0clamped = std::max(dstY0, 0); GLint dstX1clamped = std::min(dstX1, dstW); GLint dstY1clamped = std::min(dstY1, dstH); for (GLint dstY = dstY0clamped; dstY < dstY1clamped; ++dstY) { float srcY = srcY0 + (dstY - dstY0 + 0.5) * srcDY / dstDY; if (srcY < 0 || srcY >= test.srcH) { continue; } srcY -= 0.5f; GLint srcPixelY0, srcPixelY1; float weightY; filter(test, srcY, srcPixelY0, srcPixelY1, weightY); clamp(srcPixelY0, 0, test.srcH - 1); clamp(srcPixelY1, 0, test.srcH - 1); for (GLint dstX = dstX0clamped; dstX < dstX1clamped; ++dstX) { float srcX = srcX0 + (dstX - dstX0 + 0.5) * srcDX / dstDX; if (srcX < 0 || srcX >= test.srcW) { continue; } srcX -= 0.5f; GLint srcPixelX0, srcPixelX1; float weightX; filter(test, srcX, srcPixelX0, srcPixelX1, weightX); clamp(srcPixelX0, 0, test.srcW - 1); clamp(srcPixelX1, 0, test.srcW - 1); float *srcPixel00 = srcPixels + (srcPixelY0 * test.srcW + srcPixelX0) * numChannels; float *srcPixel01 = srcPixels + (srcPixelY0 * test.srcW + srcPixelX1) * numChannels; float *srcPixel10 = srcPixels + (srcPixelY1 * test.srcW + srcPixelX0) * numChannels; float *srcPixel11 = srcPixels + (srcPixelY1 * test.srcW + srcPixelX1) * numChannels; float *dstPixel = expectedDstPixels + (dstY * dstW + dstX) * numChannels; for (GLuint c = 0; c < numChannels; ++c) { dstPixel[c] = lerp2d(srcPixel00[c], srcPixel01[c], srcPixel10[c], srcPixel11[c], weightX, weightY); } } } delete [] srcPixels; float *observedDstPixels = new float[dstH * dstW * numChannels]; glBindFramebuffer(GL_READ_FRAMEBUFFER, dstFBO); glReadPixels(0, 0, dstW, dstH, GL_RGB, GL_FLOAT, observedDstPixels); GLboolean pass; pass = piglit_compare_images_color(0, 0, dstW, dstH, numChannels, piglit_tolerance, expectedDstPixels, observedDstPixels); delete [] observedDstPixels; delete [] expectedDstPixels; return pass; }
Point lerp2d(const Point& px0y0, const Point& px1y0, const Point& px0y1, const Point& px1y1, float xPoint, float yPoint) { return Point(lerp2d(Float4(px0y0), Float4(px1y0), Float4(px0y1), Float4(px1y1), xPoint, yPoint)); }