コード例 #1
0
ファイル: htable.cpp プロジェクト: pmattern/qps
// repaint columns from col0 to col1. If col1 is -1, repaint all
// the way to the right edge of the table.
// called by
//          1.void Qps::update_table(int col)
void HeadedTable::repaintColumns(int col0, int col1)
{
    QRect bvr = body->viewRect();
    QRect hvr = head->viewRect();
    int x0 = colOffset(col0) - body->xOffset();
    if (x0 > hvr.width())
        return;
    if (x0 < 0)
        x0 = 0;
    bvr.setLeft(x0);
    hvr.setLeft(x0);
    if (col1 >= 0)
    {
        int x1 = colOffset(col1) + max_widths[col1] - body->xOffset();
        if (x1 < hvr.width())
        {
            hvr.setRight(x1);
            bvr.setRight(x1);
        }
    }
    head->repaint(hvr);
    body->repaint(bvr);
}
コード例 #2
0
Mat IntegralGradientFilter::applyTo(const Mat& image, Mat& filtered) const {
	if (image.type() != CV_32SC1)
		throw invalid_argument("IntegralGradientFilter: the image must be of type CV_32SC1");

	filtered.create(rows, cols, CV_8UC2);
	int width = image.cols - 1;
	int height = image.rows - 1;

	int radiusX = std::max(1, cvRound(static_cast<double>(width - 1) / static_cast<double>(cols + 2)));
	int radiusY = std::max(1, cvRound(static_cast<double>(height - 1) / static_cast<double>(rows + 2)));
	double spacingX = static_cast<double>(width - 3 * radiusX) / static_cast<double>(cols - 1);
	double spacingY = static_cast<double>(height - 3 * radiusY) / static_cast<double>(rows - 1);
	int gradientHalfArea = radiusY * radiusX;

	int step0 = static_cast<int>(image.step.p[0]);
	int step1 = static_cast<int>(image.step.p[1]);
	int offsetY[] = { -radiusY * step0, 0, radiusY * step0, 2 * radiusY * step0 };
	int offsetX[] = { -radiusX * step1, 0, radiusX * step1, 2 * radiusX * step1 };
	vector<size_t> rowOffset(rows);
	vector<size_t> colOffset(cols);
	for (int row = 0; row < rows; ++row)
		rowOffset[row] = cvRound(radiusY + row * spacingY) * image.step.p[0];
	for (int col = 0; col < cols; ++col)
		colOffset[col] = cvRound(radiusX + col * spacingX) * image.step.p[1];

	for (int row = 0; row < rows; ++row) {
		const uchar* pRow = image.data + rowOffset[row];
		Vec2b* gradientValues = filtered.ptr<Vec2b>(row);
		for (int col = 0; col < cols; ++col) {
			const uchar* pPoint = pRow + colOffset[col];
			Vec2b& gradient = gradientValues[col];

			//     p1  p2
			// p3  p4  p5  p6
			// p7  p8  p9  p10
			//     p11 p12
			int p1  = *reinterpret_cast<const int*>(pPoint + offsetY[0] + offsetX[1]);
			int p2  = *reinterpret_cast<const int*>(pPoint + offsetY[0] + offsetX[2]);
			int p3  = *reinterpret_cast<const int*>(pPoint + offsetY[1] + offsetX[0]);
			int p4  = *reinterpret_cast<const int*>(pPoint + offsetY[1] + offsetX[1]);
			int p5  = *reinterpret_cast<const int*>(pPoint + offsetY[1] + offsetX[2]);
			int p6  = *reinterpret_cast<const int*>(pPoint + offsetY[1] + offsetX[3]);
			int p7  = *reinterpret_cast<const int*>(pPoint + offsetY[2] + offsetX[0]);
			int p8  = *reinterpret_cast<const int*>(pPoint + offsetY[2] + offsetX[1]);
			int p9  = *reinterpret_cast<const int*>(pPoint + offsetY[2] + offsetX[2]);
			int p10 = *reinterpret_cast<const int*>(pPoint + offsetY[2] + offsetX[3]);
			int p11 = *reinterpret_cast<const int*>(pPoint + offsetY[3] + offsetX[1]);
			int p12 = *reinterpret_cast<const int*>(pPoint + offsetY[3] + offsetX[2]);

			int top = p1 - p2 - p4 + p5;
			int bottom = p8 - p9 - p11 + p12;
			int left = p3 - p4 - p7 + p8;
			int right = p5 - p6 - p9 + p10;

			int dx = (right - left) / (2 * gradientHalfArea);
			int dy = (bottom - top) / (2 * gradientHalfArea);
			gradient[0] = static_cast<uchar>(dx + 127);
			gradient[1] = static_cast<uchar>(dy + 127);
		}
	}

	return filtered;
}
コード例 #3
0
ファイル: softwareOcclusion.cpp プロジェクト: hyp/Arpheg
//Returns true if the triangle is visible
bool DepthBuffer::testTriangle2x2(const vec4f& v0,const vec4f& v1,const vec4f& v2){
	VecS32 colOffset(0, 1, 0, 1);
	VecS32 rowOffset(0, 0, 1, 1);

	vec2i vertex[3];
	vertex[0] = vec2i(int32(v0.x),int32(v0.y));
	vertex[1] = vec2i(int32(v1.x),int32(v1.y));
	vertex[2] = vec2i(int32(v2.x),int32(v2.y));

	// Reject the triangle if any of its verts is behind the nearclip plane
	if(v0.w == 0.0f || v1.w == 0.0f || v2.w == 0.0f) return true;

	float minZ = std::min(v0.z,std::min(v1.z,v2.z));
	VecF32 fixedDepth(minZ);

	// Fab(x, y) =     Ax       +       By     +      C              = 0
	// Fab(x, y) = (ya - yb)x   +   (xb - xa)y + (xa * yb - xb * ya) = 0
	// Compute A = (ya - yb) for the 3 line segments that make up each triangle
	auto A0 = vertex[1].y - vertex[2].y;
	auto A1 = vertex[2].y - vertex[0].y;
	auto A2 = vertex[0].y - vertex[1].y;

	// Compute B = (xb - xa) for the 3 line segments that make up each triangle
	auto B0 = vertex[2].x - vertex[1].x;
	auto B1 = vertex[0].x - vertex[2].x;
	auto B2 = vertex[1].x - vertex[0].x;

	// Compute C = (xa * yb - xb * ya) for the 3 line segments that make up each triangle
	auto C0 = vertex[1].x * vertex[2].y - vertex[2].x * vertex[1].y;
	auto C1 = vertex[2].x * vertex[0].y - vertex[0].x * vertex[2].y;
	auto C2 = vertex[0].x * vertex[1].y - vertex[1].x * vertex[0].y;

	// Use bounding box traversal strategy to determine which pixels to rasterize 
	auto minx = std::max(std::min(std::min(vertex[0].x,vertex[1].x),vertex[2].x),0) & (~1);
	auto maxx = std::min(std::max(std::max(vertex[0].x,vertex[1].x),vertex[2].x),size_.x-2);
	auto miny = std::max(std::min(std::min(vertex[0].y,vertex[1].y),vertex[2].y),0) & (~1);
	auto maxy = std::min(std::max(std::max(vertex[0].y,vertex[1].y),vertex[2].y),size_.y-2);

	VecS32 a0(A0);
	VecS32 a1(A1);
	VecS32 a2(A2);
	VecS32 b0(B0);
	VecS32 b1(B1);
	VecS32 b2(B2);

	VecS32 col = VecS32(minx) + colOffset;
	VecS32 row = VecS32(miny) + rowOffset;
	auto rowIdx = miny*size_.x + 2 * minx;
	VecS32 w0_row  = a0 * col + b0 * row + VecS32(C0);
	VecS32 w1_row  = a1 * col + b1 * row + VecS32(C1);
	VecS32 w2_row  = a2 * col + b2 * row + VecS32(C2);

	//Multiply each weight by two(rasterize 2x2 quad at once).
	a0 = shiftl<1>(a0);
	a1 = shiftl<1>(a1);
	a2 = shiftl<1>(a2);
	b0 = shiftl<1>(b0);
	b1 = shiftl<1>(b1);
	b2 = shiftl<1>(b2);

	for(int32 y = miny;y<=maxy;y+=2,rowIdx += 2 * size_.x){
		auto w0 = w0_row;
		auto w1 = w1_row;
		auto w2 = w2_row;

		auto idx = rowIdx;
				
		for(int32 x = minx;x<=maxx;x+=2,idx+=4){
			auto mask = w0|w1|w2;
			auto masks = _mm_movemask_ps(bits2float(mask).simd);
			if(masks != 0xF){
				VecF32 previousDepth = VecF32::load(data_+idx);
				auto cmpMask = ((~masks)&0xF)& _mm_movemask_ps(cmple(fixedDepth,previousDepth).simd);
				if(cmpMask){
					return true;
				}
			}
			
			w0+=a0;
			w1+=a1;
			w2+=a2;
		}
		w0_row += b0;
		w1_row += b1;
		w2_row += b2;
	}
	return false;
}
コード例 #4
0
ファイル: softwareOcclusion.cpp プロジェクト: hyp/Arpheg
//Rasterize 4 pixels at once
void DepthBuffer::rasterizeTile2x2(int32 x,int32 y,uint32 pass) {

	auto tileIndex = x + y*tileCount_.x;
	auto count = tileTriangleCount_[tileIndex];
	tileTriangleCount_[tileIndex] = 0;
	auto faces = triangleBins_ + x*kMaxTrianglesPerTile + y*tileCount_.x*kMaxTrianglesPerTile;
	vec2i tilePos(x*tileSize_.x,y*tileSize_.y);
	vec2i tileEnd(tilePos + tileSize_);
#ifdef ARPHEG_ARCH_X86
	enum { kNumLanes = 4 };

	//Flush denormals to zero
	_mm_setcsr( _mm_getcsr() | 0x8040 );

	VecS32 colOffset(0, 1, 0, 1);
	VecS32 rowOffset(0, 0, 1, 1);

	//Process the 4 binned triangles at a time
	VecS32 vertexX[3];
	VecS32 vertexY[3];
	VecF32  vertexZ[4];
	VecS32 tileMinXSimd(tilePos.x);
	VecS32 tileMaxXSimd(tilePos.x+tileSize_.x-2);
	VecS32 tileMinYSimd(tilePos.y);
	VecS32 tileMaxYSimd(tilePos.y+tileSize_.y-2);

	for(uint32 i = 0;i<count;i += kNumLanes){

		uint32 numSimdTris = std::min(uint32(kNumLanes),count-i);
		auto f = faces+i;
		for(uint32 ii = 0;ii< numSimdTris;++ii){
			vertexX[0].lane[ii] = f[ii].v[0].x;
			vertexY[0].lane[ii] = f[ii].v[0].y;
			vertexX[1].lane[ii] = f[ii].v[1].x;
			vertexY[1].lane[ii] = f[ii].v[1].y;
			vertexX[2].lane[ii] = f[ii].v[2].x;
			vertexY[2].lane[ii] = f[ii].v[2].y;
			vertexZ[ii] = VecF32(f[ii].z[0],f[ii].z[1],f[ii].z[2],0.0f);
		}

		// Fab(x, y) =     Ax       +       By     +      C              = 0
		// Fab(x, y) = (ya - yb)x   +   (xb - xa)y + (xa * yb - xb * ya) = 0
		// Compute A = (ya - yb) for the 3 line segments that make up each triangle
		VecS32 A0 = vertexY[1] - vertexY[2];
		VecS32 A1 = vertexY[2] - vertexY[0];
		VecS32 A2 = vertexY[0] - vertexY[1];

		// Compute B = (xb - xa) for the 3 line segments that make up each triangle
		VecS32 B0 = vertexX[2] - vertexX[1];
		VecS32 B1 = vertexX[0] - vertexX[2];
		VecS32 B2 = vertexX[1] - vertexX[0];

		// Compute C = (xa * yb - xb * ya) for the 3 line segments that make up each triangle
		VecS32 C0 = vertexX[1] * vertexY[2] - vertexX[2] * vertexY[1];
		VecS32 C1 = vertexX[2] * vertexY[0] - vertexX[0] * vertexY[2];
		VecS32 C2 = vertexX[0] * vertexY[1] - vertexX[1] * vertexY[0];

		// Use bounding box traversal strategy to determine which pixels to rasterize 
		VecS32 minX = vmax(vmin(vmin(vertexX[0], vertexX[1]), vertexX[2]), tileMinXSimd) & VecS32(~1);
		VecS32 maxX   = vmin(vmax(vmax(vertexX[0], vertexX[1]), vertexX[2]), tileMaxXSimd);

		VecS32 minY = vmax(vmin(vmin(vertexY[0], vertexY[1]), vertexY[2]), tileMinYSimd) & VecS32(~1);
		VecS32 maxY = vmin(vmax(vmax(vertexY[0], vertexY[1]), vertexY[2]), tileMaxYSimd);

		//Rasterize each triangle individually
		for(uint32 lane = 0;lane < numSimdTris;++lane){
			//Rasterize in 2x2 quads.
			VecF32 zz[3];
			zz[0] = VecF32(vertexZ[lane].lane[0]);
			zz[1] = VecF32(vertexZ[lane].lane[1]);
			zz[2] = VecF32(vertexZ[lane].lane[2]);

			VecS32 a0(A0.lane[lane]);
			VecS32 a1(A1.lane[lane]);
			VecS32 a2(A2.lane[lane]);
			VecS32 b0(B0.lane[lane]);
			VecS32 b1(B1.lane[lane]);
			VecS32 b2(B2.lane[lane]);

			int32 minx = minX.lane[lane];
			int32 maxx = maxX.lane[lane];
			int32 miny = minY.lane[lane];
			int32 maxy = maxY.lane[lane];

			VecS32 col = VecS32(minx) + colOffset;
			VecS32 row = VecS32(miny) + rowOffset;
			auto rowIdx = miny*size_.x + 2 * minx;
			VecS32 w0_row  = a0 * col + b0 * row + VecS32(C0.lane[lane]);
			VecS32 w1_row  = a1 * col + b1 * row + VecS32(C1.lane[lane]);
			VecS32 w2_row  = a2 * col + b2 * row + VecS32(C2.lane[lane]);

			//Multiply each weight by two(rasterize 2x2 quad at once).
			a0 = shiftl<1>(a0);
			a1 = shiftl<1>(a1);
			a2 = shiftl<1>(a2);
			b0 = shiftl<1>(b0);
			b1 = shiftl<1>(b1);
			b2 = shiftl<1>(b2);

			VecF32 zInc = itof(a1)*zz[1] + itof(a2)*zz[2];
	
			for(int32 y = miny;y<=maxy;y+=2,rowIdx += 2 * size_.x){
				auto w0 = w0_row;
				auto w1 = w1_row;
				auto w2 = w2_row;

				VecF32 depth = zz[0] + itof(w1)*zz[1] + itof(w2)*zz[2];
				auto idx = rowIdx;
				
				for(int32 x = minx;x<=maxx;x+=2,idx+=4){
					auto mask = w0|w1|w2;
					VecF32 previousDepth = VecF32::load(data_+idx);
					VecF32 mergedDepth = vmin(depth,previousDepth);
					previousDepth = select(mergedDepth,previousDepth,mask);
					previousDepth.store(data_+idx);
	
					w0+=a0;
					w1+=a1;
					w2+=a2;
					depth+=zInc;
				}
				w0_row += b0;
				w1_row += b1;
				w2_row += b2;
			}
		}
	}
#endif
}
コード例 #5
0
ファイル: softwareOcclusion.cpp プロジェクト: hyp/Arpheg
void DepthBuffer::rasterizeTile(int32 x,int32 y,uint32 pass) {
	if(pass == 0){
		//init tile(clear depth).	
		//auto tilePixels = data_ + x*tileSize_.x*tileSize_.y + (y*tileSize_.x*tileSize_.y)*tileCount_.x;
		//clearDepth(tilePixels,tileSize_.x*tileSize_.y,1.0f);
	}
	if(mode_ == kModeDepthPackedQuads){
		rasterizeTile2x2(x,y,pass);
		return;
	}
	auto tileIndex = x + y*tileCount_.x;
	auto count = tileTriangleCount_[tileIndex];
	tileTriangleCount_[tileIndex] = 0;
	auto faces = triangleBins_ + x*kMaxTrianglesPerTile + y*tileCount_.x*kMaxTrianglesPerTile;
	vec2i tilePos(x*tileSize_.x,y*tileSize_.y);
	vec2i tileEnd(tilePos + tileSize_);
#ifdef ARPHEG_ARCH_X86
	enum { kNumLanes = 4 };

	//Flush denormals to zero
	//_mm_setcsr( _mm_getcsr() | 0x8040 );

	VecS32 colOffset(0, 1, 0, 1);
	VecS32 rowOffset(0, 0, 1, 1);

	//Process the 4 binned triangles at a time
	VecS32 vertexX[3];
	VecS32 vertexY[3];
	VecF32  vertexZ[4];
	VecS32 tileMinXSimd(tilePos.x);
	VecS32 tileMaxXSimd(tilePos.x+tileSize_.x-1);
	VecS32 tileMinYSimd(tilePos.y);
	VecS32 tileMaxYSimd(tilePos.y+tileSize_.y-1);

	for(uint32 i = 0;i<count;i += kNumLanes){

		uint32 numSimdTris = std::min(uint32(kNumLanes),count-i);
		auto f = faces+i;
		for(uint32 ii = 0;ii< numSimdTris;++ii){
			vertexX[0].lane[ii] = f[ii].v[0].x;
			vertexY[0].lane[ii] = f[ii].v[0].y;
			vertexX[1].lane[ii] = f[ii].v[1].x;
			vertexY[1].lane[ii] = f[ii].v[1].y;
			vertexX[2].lane[ii] = f[ii].v[2].x;
			vertexY[2].lane[ii] = f[ii].v[2].y;
			vertexZ[ii] = VecF32(f[ii].z[0],f[ii].z[1],f[ii].z[2],0.0f);
		}

		// Fab(x, y) =     Ax       +       By     +      C              = 0
		// Fab(x, y) = (ya - yb)x   +   (xb - xa)y + (xa * yb - xb * ya) = 0
		// Compute A = (ya - yb) for the 3 line segments that make up each triangle
		VecS32 A0 = vertexY[1] - vertexY[2];
		VecS32 A1 = vertexY[2] - vertexY[0];
		VecS32 A2 = vertexY[0] - vertexY[1];

		// Compute B = (xb - xa) for the 3 line segments that make up each triangle
		VecS32 B0 = vertexX[2] - vertexX[1];
		VecS32 B1 = vertexX[0] - vertexX[2];
		VecS32 B2 = vertexX[1] - vertexX[0];

		// Compute C = (xa * yb - xb * ya) for the 3 line segments that make up each triangle
		VecS32 C0 = vertexX[1] * vertexY[2] - vertexX[2] * vertexY[1];
		VecS32 C1 = vertexX[2] * vertexY[0] - vertexX[0] * vertexY[2];
		VecS32 C2 = vertexX[0] * vertexY[1] - vertexX[1] * vertexY[0];

		// Use bounding box traversal strategy to determine which pixels to rasterize 
		VecS32 minX = vmax(vmin(vmin(vertexX[0], vertexX[1]), vertexX[2]), tileMinXSimd); 
		VecS32 maxX   = vmin(vmax(vmax(vertexX[0], vertexX[1]), vertexX[2]), tileMaxXSimd);

		VecS32 minY = vmax(vmin(vmin(vertexY[0], vertexY[1]), vertexY[2]), tileMinYSimd); 
		VecS32 maxY   = vmin(vmax(vmax(vertexY[0], vertexY[1]), vertexY[2]), tileMaxYSimd);

		//Rasterize each triangle individually
		for(uint32 lane = 0;lane < numSimdTris;++lane){
			float zz[3] = { vertexZ[lane].lane[0],vertexZ[lane].lane[1],vertexZ[lane].lane[2] };

			int32 a0 = A0.lane[lane]; 
			int32 a1 = A1.lane[lane]; 
			int32 a2 = A2.lane[lane]; 
			int32 b0 = B0.lane[lane];
			int32 b1 = B1.lane[lane];
			int32 b2 = B2.lane[lane];

			int32 minx = minX.lane[lane];
			int32 maxx = maxX.lane[lane];
			int32 miny = minY.lane[lane];
			int32 maxy = maxY.lane[lane];

			auto w0_row = a0 * minx + b0 * miny + C0.lane[lane];
			auto w1_row = a1 * minx + b1 * miny + C1.lane[lane];
			auto w2_row = a2 * minx + b2 * miny + C2.lane[lane];

			float* tilePixels = data_ + tilePos.x*tileSize_.y + (tilePos.y*tileSize_.x)*tileCount_.x;
	
			int32 idx2  = minx-tilePos.x + (miny - tilePos.y)*tileSize_.x;
			int32 spanx = maxx-minx;

	
			for(int32 endIdx2 = idx2+(tileSize_.x)*(maxy-miny);idx2<=endIdx2;idx2+=tileSize_.x){
				auto w0 = w0_row;
				auto w1 = w1_row;
				auto w2 = w2_row;

				auto idx = idx2;
				for(int32 endIdx = idx+spanx;idx<=endIdx;++idx){
					auto mask = w0|w1|w2;
					if(mask >= 0){
						float betaf = float(w1);
						float gamaf = float(w2);
						float depth = zz[0] + betaf*zz[1] + gamaf*zz[2];

						auto d = tilePixels[idx];
						d = depth<d?depth:d;
						tilePixels[idx] = d;
					}

					w0+=a0;
					w1+=a1;
					w2+=a2;
				}
				w0_row += b0;
				w1_row += b1;
				w2_row += b2;
			}
		}
	}
#else
	for(uint32 i = 0;i<count;i ++){
		drawTriangle(faces[i],tilePos);
	}
#endif
}