Beispiel #1
0
	void setAffineAndOrientation(Sifteo::VideoBuffer &v, uint16_t angle, Sifteo::Side orientation)
	{
		float f = (M_TAU*angle)/65536.0f;
		AffineMatrix m = AffineMatrix::identity();

		m.translate(64,64);			// move center to origin
		m.rotate(f);				// do the rotation
		m.translate(-64,-64);		// move it back
		syncMatrixAndOrientation(v, m, orientation);
	}
Beispiel #2
0
	void setAffine(Sifteo::VideoBuffer &v, uint16_t angle)
	{
		float f = (M_TAU*angle)/65536.0f;
		AffineMatrix m = AffineMatrix::identity();

		m.translate(64,64);			// move center to origin
		m.rotate(f);				// do the rotation
		m.translate(-64,-64);		// move it back

		v.bg2.setMatrix( m );
	}
Beispiel #3
0
    void GLSLStaticViewer::render(const Camera& cam, const bouge::AffineMatrix& model) const
    {
        // This is a small, but effective, optimization that unfortunately GCC doesn't do.
        static const std::string uModelViewProjectionMatrix = "uModelViewProjectionMatrix";
        static const std::string uModelViewMatrix = "uModelViewMatrix";
        static const std::string uNormalMatrix = "uNormalMatrix";
        static const std::string uAmbient = "uAmbient";
        static const std::string ambient = "ambient";
        static const std::string ambient2 = "uMaterialAmbient";
        static const std::string uDiffuse = "uDiffuse";
        static const std::string diffuse = "diffuse";
        static const std::string diffuse2 = "uMaterialDiffuse";
        static const std::string uSpecular = "uSpecular";
        static const std::string specular = "specular";
        static const std::string specular2 = "uMaterialSpecular";
        static const std::string uShininess = "uShininess";
        static const std::string shininess = "shininess";
        static const std::string uDiffTex = "uDiffTex";

        Viewer::render(cam, model);

        m_shaderToUse->use();

        AffineMatrix mv = cam.view() * model;
        AffineMatrix id = mv * mv.inverse();
        m_shaderToUse->uniformMatrix4fv(uModelViewProjectionMatrix, 1, false, (cam.viewproj() * model).array16f());
        m_shaderToUse->uniformMatrix4fv(uModelViewMatrix, 1, false, mv.array16f());
        m_shaderToUse->uniformMatrix3fv(uNormalMatrix, 1, true, mv.array9fInverse());

        gl_BindVertexArray(m_VAOIds[0]);

        // Now, render each submesh of the mesh one after. It may need to get split
        // for example if it has too many bones.
        for(CoreHardwareMesh::iterator i = m_hwmesh->begin() ; i != m_hwmesh->end() ; ++i) {
            const CoreHardwareSubMesh& submesh = *i;

            // We set the per-submesh material options.

            // Here, we can assume the material exists, as we did the
            // "integrity checks" after the loading already.
            CoreMaterialPtr pMat = m_modelInst->materialForSubmesh(submesh.submeshName());

            if(pMat->hasProprety(ambient)) {
                m_shaderToUse->uniform3fv(uAmbient, 1, &pMat->propretyAsFvec(ambient)[0]);
            } else if(pMat->hasProprety(ambient2)) {
                m_shaderToUse->uniform3fv(uAmbient, 1, &pMat->propretyAsFvec(ambient2)[0]);
            }

            if(pMat->hasProprety(diffuse)) {
                m_shaderToUse->uniform3fv(uDiffuse, 1, &pMat->propretyAsFvec(diffuse)[0]);
            } else if(pMat->hasProprety(diffuse2)) {
                m_shaderToUse->uniform3fv(uDiffuse, 1, &pMat->propretyAsFvec(diffuse2)[0]);
            }

            if(pMat->hasProprety(specular)) {
                m_shaderToUse->uniform3fv(uSpecular, 1, &pMat->propretyAsFvec(specular)[0]);
                if(pMat->hasProprety(shininess)) {
                    m_shaderToUse->uniformf(uShininess, pMat->propretyAsFvec(shininess)[0]);
                }
            } else if(pMat->hasProprety(specular2)) {
                m_shaderToUse->uniform3fv(uSpecular, 1, &pMat->propretyAsFvec(specular2)[0]);
                m_shaderToUse->uniformf(uShininess, pMat->propretyAsFvec(specular2)[3]);
            }

            if(pMat->userData) {
                static_cast<TextureUserData*>(pMat->userData.get())->tex->selectTexture(0);
                m_shaderToUse->uniformi(uDiffTex, 0);
            }

            glDrawElements(GL_TRIANGLES, submesh.faceCount() * m_hwmesh->indicesPerFace(), BOUGE_FACE_INDEX_TYPE_GL, (const GLvoid*)(submesh.startIndex()*sizeof(BOUGE_FACE_INDEX_TYPE)));
        }

        gl_BindVertexArray(0);
        gl_BindBuffer(GL_ARRAY_BUFFER, 0);
        gl_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        checkError("GLSLStaticViewer::render");
    }
Beispiel #4
0
void AffineUnit::process_package(LoadPackage *package)
{
	AffinePackage *pkg = (AffinePackage*)package;
	int min_in_x = server->in_x;
	int min_in_y = server->in_y;
	int max_in_x = server->in_x + server->in_w - 1;
	int max_in_y = server->in_y + server->in_h - 1;

	int min_out_x = server->out_x;
	int min_out_y = server->out_y;
	int max_out_x = server->out_x + server->out_w;
	int max_out_y = server->out_y + server->out_h;

// Amount to shift the input coordinates relative to the output coordinates
// To get the pivots to line up
	int pivot_offset_x = server->in_pivot_x - server->out_pivot_x;
	int pivot_offset_y = server->in_pivot_y - server->out_pivot_y;

// Calculate real coords
	float out_x1, out_y1, out_x2, out_y2, out_x3, out_y3, out_x4, out_y4;
	if(server->mode == AffineEngine::STRETCH ||
		server->mode == AffineEngine::PERSPECTIVE ||
		server->mode == AffineEngine::ROTATE)
	{
		out_x1 = (float)server->in_x + (float)server->x1 * server->in_w / 100;
		out_y1 = (float)server->in_y + (float)server->y1 * server->in_h / 100;
		out_x2 = (float)server->in_x + (float)server->x2 * server->in_w / 100;
		out_y2 = (float)server->in_y + (float)server->y2 * server->in_h / 100;
		out_x3 = (float)server->in_x + (float)server->x3 * server->in_w / 100;
		out_y3 = (float)server->in_y + (float)server->y3 * server->in_h / 100;
		out_x4 = (float)server->in_x + (float)server->x4 * server->in_w / 100;
		out_y4 = (float)server->in_y + (float)server->y4 * server->in_h / 100;
	}
	else
	{
		out_x1 = (float)server->in_x + (float)server->x1 * server->in_w / 100;
		out_y1 = server->in_y;
		out_x2 = out_x1 + server->in_w;
		out_y2 = server->in_y;
		out_x4 = (float)server->in_x + (float)server->x4 * server->in_w / 100;
		out_y4 = server->in_y + server->in_h;
		out_x3 = out_x4 + server->in_w;
		out_y3 = server->in_y + server->in_h;
	}
// Rotation with OpenGL uses a simple quad.
	if(server->mode == AffineEngine::ROTATE &&
		server->use_opengl)
	{
#ifdef HAVE_GL
		server->output->to_texture();
		server->output->enable_opengl();
		server->output->init_screen();
		server->output->bind_texture(0);
		server->output->clear_pbuffer();

		int texture_w = server->output->get_texture_w();
		int texture_h = server->output->get_texture_h();
		float output_h = server->output->get_h();
		float in_x1 = (float)server->in_x / texture_w;
		float in_x2 = (float)(server->in_x + server->in_w) / texture_w;
		float in_y1 = (float)server->in_y / texture_h;
		float in_y2 = (float)(server->in_y + server->in_h) / texture_h;

		glBegin(GL_QUADS);
		glNormal3f(0, 0, 1.0);

		glTexCoord2f(in_x1, in_y1);
		glVertex3f(out_x1, -output_h+out_y1, 0);

		glTexCoord2f(in_x2, in_y1);
		glVertex3f(out_x2, -output_h+out_y2, 0);

		glTexCoord2f(in_x2, in_y2);
		glVertex3f(out_x3, -output_h+out_y3, 0);

		glTexCoord2f(in_x1, in_y2);
		glVertex3f(out_x4, -output_h+out_y4, 0);

		glEnd();

		server->output->set_opengl_state(VFrame::SCREEN);
#endif
	}
	else
	if(server->mode == AffineEngine::PERSPECTIVE ||
		server->mode == AffineEngine::SHEER ||
		server->mode == AffineEngine::ROTATE)
	{
		AffineMatrix matrix;
		float temp;
// swap points 3 & 4
		temp = out_x4;
		out_x4 = out_x3;
		out_x3 = temp;
		temp = out_y4;
		out_y4 = out_y3;
		out_y3 = temp;

		calculate_matrix(
			server->in_x,
			server->in_y,
			server->in_x + server->in_w,
			server->in_y + server->in_h,
			out_x1,
			out_y1,
			out_x2,
			out_y2,
			out_x3,
			out_y3,
			out_x4,
			out_y4,
			&matrix);

		int interpolate = 1;
		int reverse = !server->forward;
		float tx, ty, tw;
		float xinc, yinc, winc;
		AffineMatrix m, im;
		float ttx = 0, tty = 0;
		int itx = 0, ity = 0;
		int tx1 = 0, ty1 = 0, tx2 = 0, ty2 = 0;

		if(reverse)
		{
			m.copy_from(&matrix);
			m.invert(&im);
			matrix.copy_from(&im);
		}
		else
		{
			matrix.invert(&m);
		}

		float dx1 = 0, dy1 = 0;
		float dx2 = 0, dy2 = 0;
		float dx3 = 0, dy3 = 0;
		float dx4 = 0, dy4 = 0;
		matrix.transform_point(server->in_x, server->in_y, &dx1, &dy1);
		matrix.transform_point(server->in_x + server->in_w, server->in_y, &dx2, &dy2);
		matrix.transform_point(server->in_x, server->in_y + server->in_h, &dx3, &dy3);
		matrix.transform_point(server->in_x + server->in_w, server->in_y + server->in_h, &dx4, &dy4);

		if(server->use_opengl)
		{
#ifdef HAVE_GL
			static char *affine_frag =
				(char*)"uniform sampler2D tex;\n"
				"uniform mat3 affine_matrix;\n"
				"uniform vec2 texture_extents;\n"
				"uniform vec2 image_extents;\n"
				"uniform vec4 border_color;\n"
				"void main()\n"
				"{\n"
				"	vec2 outcoord = gl_TexCoord[0].st;\n"
				"	outcoord *= texture_extents;\n"
				"	mat3 coord_matrix = mat3(\n"
				"		outcoord.x, outcoord.y, 1.0, \n"
				"		outcoord.x, outcoord.y, 1.0, \n"
				"		outcoord.x, outcoord.y, 1.0);\n"
				"	mat3 incoord_matrix = affine_matrix * coord_matrix;\n"
				"	vec2 incoord = vec2(incoord_matrix[0][0], incoord_matrix[0][1]);\n"
				"	incoord /= incoord_matrix[0][2];\n"
				"	incoord /= texture_extents;\n"
				"	if(incoord.x > image_extents.x || incoord.y > image_extents.y)\n"
				"		gl_FragColor = border_color;\n"
				"	else\n"
				"		gl_FragColor = texture2D(tex, incoord);\n"
				"}\n";

			float affine_matrix[9] = {
				(float)m.values[0][0], (float)m.values[1][0], (float)m.values[2][0],
				(float)m.values[0][1], (float)m.values[1][1], (float)m.values[2][1],
				(float)m.values[0][2], (float)m.values[1][2], (float)m.values[2][2]
			};

			server->output->to_texture();
			server->output->enable_opengl();
			unsigned int frag_shader = VFrame::make_shader(0,
					affine_frag,
					0);
			if(frag_shader > 0)
			{
				glUseProgram(frag_shader);
				glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0);
				glUniformMatrix3fv(glGetUniformLocation(frag_shader, "affine_matrix"), 
					1,
					0,
					affine_matrix);
				glUniform2f(glGetUniformLocation(frag_shader, "texture_extents"), 
					(GLfloat)server->output->get_texture_w(),
					(GLfloat)server->output->get_texture_h());
				glUniform2f(glGetUniformLocation(frag_shader, "image_extents"), 
					(GLfloat)server->output->get_w() / server->output->get_texture_w(),
					(GLfloat)server->output->get_h() / server->output->get_texture_h());
				float border_color[] = { 0, 0, 0, 0 };
				if(BC_CModels::is_yuv(server->output->get_color_model()))
				{
					border_color[1] = 0.5;
					border_color[2] = 0.5;
				}
				if(!BC_CModels::has_alpha(server->output->get_color_model()))
				{
					border_color[3] = 1.0;
				}

				glUniform4fv(glGetUniformLocation(frag_shader, "border_color"), 
					1,
					(GLfloat*)border_color);
				server->output->init_screen();
				server->output->bind_texture(0);
				glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
				server->output->draw_texture();
				glUseProgram(0);
				server->output->set_opengl_state(VFrame::SCREEN);
			}
			return;
#endif // HAVE_GL
		}

#define ROUND(x) ((int)((x > 0) ? (x) + 0.5 : (x) - 0.5))
#define MIN4(a,b,c,d) MIN(MIN(MIN(a,b),c),d)
#define MAX4(a,b,c,d) MAX(MAX(MAX(a,b),c),d)

		tx1 = ROUND(MIN4(dx1 - pivot_offset_x, dx2 - pivot_offset_x, dx3 - pivot_offset_x, dx4 - pivot_offset_x));
		ty1 = ROUND(MIN4(dy1 - pivot_offset_y, dy2 - pivot_offset_y, dy3 - pivot_offset_y, dy4 - pivot_offset_y));

		tx2 = ROUND(MAX4(dx1 - pivot_offset_x, dx2 - pivot_offset_x, dx3 - pivot_offset_x, dx4 - pivot_offset_x));
		ty2 = ROUND(MAX4(dy1 - pivot_offset_y, dy2 - pivot_offset_y, dy3 - pivot_offset_y, dy4 - pivot_offset_y));

		CLAMP(ty1, pkg->y1, pkg->y2);
		CLAMP(ty2, pkg->y1, pkg->y2);
		CLAMP(tx1, server->out_x, server->out_x + server->out_w);
		CLAMP(tx2, server->out_x, server->out_x + server->out_w);

		xinc = m.values[0][0];
		yinc = m.values[1][0];
		winc = m.values[2][0];

#define CUBIC_ROW(in_row, chroma_offset) \
	transform_cubic(dx, \
		in_row[col1_offset] - chroma_offset, \
		in_row[col2_offset] - chroma_offset, \
		in_row[col3_offset] - chroma_offset, \
		in_row[col4_offset] - chroma_offset)


#define TRANSFORM(components, type, temp_type, chroma_offset, max) \
{ \
	type **in_rows = (type**)server->input->get_rows(); \
	float round_factor = 0.0; \
	if(sizeof(type) < 4) round_factor = 0.5; \
	for(int y = ty1; y < ty2; y++) \
	{ \
		type *out_row = (type*)server->output->get_rows()[y]; \
 \
		if(!interpolate) \
		{ \
        	tx = xinc * (tx1 + 0.5) + \
				m.values[0][1] * (y + pivot_offset_y + 0.5) + \
				m.values[0][2] + \
				pivot_offset_x * xinc; \
        	ty = yinc * (tx1 + 0.5) + \
				m.values[1][1] * (y + pivot_offset_y + 0.5) + \
				m.values[1][2] + \
				pivot_offset_x * yinc; \
        	tw = winc * (tx1 + 0.5) + \
				m.values[2][1] * (y + pivot_offset_y + 0.5) + \
				m.values[2][2] + \
				pivot_offset_x * winc; \
		} \
		else \
		{ \
			tx = xinc * tx1 + \
				m.values[0][1] * (y + pivot_offset_y) + \
				m.values[0][2] + \
				pivot_offset_x * xinc; \
			ty = yinc * tx1 + \
				m.values[1][1] * (y + pivot_offset_y) + \
				m.values[1][2] + \
				pivot_offset_x * yinc; \
			tw = winc * tx1 + \
				m.values[2][1] * (y + pivot_offset_y) + \
				m.values[2][2] + \
				pivot_offset_x * winc; \
		} \
 \
		out_row += tx1 * components; \
		for(int x = tx1; x < tx2; x++) \
		{ \
/* Normalize homogeneous coords */ \
			if(tw == 0.0) \
			{ \
				ttx = 0.0; \
				tty = 0.0; \
			} \
			else \
			if(tw != 1.0) \
			{ \
				ttx = tx / tw; \
				tty = ty / tw; \
			} \
			else \
			{ \
				ttx = tx; \
				tty = ty; \
			} \
			itx = (int)ttx; \
			ity = (int)tty; \
 \
			int row1 = ity - 1; \
			int row2 = ity; \
			int row3 = ity + 1; \
			int row4 = ity + 2; \
			CLAMP(row1, min_in_y, max_in_y); \
			CLAMP(row2, min_in_y, max_in_y); \
			CLAMP(row3, min_in_y, max_in_y); \
			CLAMP(row4, min_in_y, max_in_y); \
 \
/* Set destination pixels if in clipping region */ \
			if(!interpolate && \
				x >= min_out_x && \
				x < max_out_x) \
			{ \
				if(itx >= min_in_x && \
					itx <= max_in_x && \
					ity >= min_in_y && \
					ity <= max_in_y) \
				{ \
					type *src = in_rows[ity] + itx * components; \
					*out_row++ = *src++; \
					*out_row++ = *src++; \
					*out_row++ = *src++; \
					if(components == 4) *out_row++ = *src; \
				} \
				else \
/* Fill with chroma */ \
				{ \
					*out_row++ = 0; \
					*out_row++ = chroma_offset; \
					*out_row++ = chroma_offset; \
					if(components == 4) *out_row++ = 0; \
				} \
			} \
			else \
/* Bicubic algorithm */ \
			if(interpolate &&  \
				x >= min_out_x &&  \
				x < max_out_x) \
			{ \
/* clipping region */ \
				if ((itx + 2) >= min_in_x && \
					(itx - 1) <= max_in_x && \
					(ity + 2) >= min_in_y && \
					(ity - 1) <= max_in_y) \
				{ \
					float dx, dy; \
 \
/* the fractional error */ \
					dx = ttx - itx; \
					dy = tty - ity; \
 \
/* Row and column offsets in cubic block */ \
					int col1 = itx - 1; \
					int col2 = itx; \
					int col3 = itx + 1; \
					int col4 = itx + 2; \
					CLAMP(col1, min_in_x, max_in_x); \
					CLAMP(col2, min_in_x, max_in_x); \
					CLAMP(col3, min_in_x, max_in_x); \
					CLAMP(col4, min_in_x, max_in_x); \
					int col1_offset = col1 * components; \
					int col2_offset = col2 * components; \
					int col3_offset = col3 * components; \
					int col4_offset = col4 * components; \
 \
					type *row1_ptr = in_rows[row1]; \
					type *row2_ptr = in_rows[row2]; \
					type *row3_ptr = in_rows[row3]; \
					type *row4_ptr = in_rows[row4]; \
					temp_type r, g, b, a; \
 \
					r = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, 0x0), \
						CUBIC_ROW(row2_ptr, 0x0), \
						CUBIC_ROW(row3_ptr, 0x0), \
						CUBIC_ROW(row4_ptr, 0x0)) + \
						round_factor); \
 \
					row1_ptr++; \
					row2_ptr++; \
					row3_ptr++; \
					row4_ptr++; \
					g = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, chroma_offset), \
						CUBIC_ROW(row2_ptr, chroma_offset), \
						CUBIC_ROW(row3_ptr, chroma_offset), \
						CUBIC_ROW(row4_ptr, chroma_offset)) + \
						round_factor); \
					g += chroma_offset; \
 \
					row1_ptr++; \
					row2_ptr++; \
					row3_ptr++; \
					row4_ptr++; \
					b = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, chroma_offset), \
						CUBIC_ROW(row2_ptr, chroma_offset), \
						CUBIC_ROW(row3_ptr, chroma_offset), \
						CUBIC_ROW(row4_ptr, chroma_offset)) + \
						round_factor); \
					b += chroma_offset; \
 \
					if(components == 4) \
					{ \
						row1_ptr++; \
						row2_ptr++; \
						row3_ptr++; \
						row4_ptr++; \
						a = (temp_type)(transform_cubic(dy, \
							CUBIC_ROW(row1_ptr, 0x0), \
							CUBIC_ROW(row2_ptr, 0x0), \
							CUBIC_ROW(row3_ptr, 0x0), \
							CUBIC_ROW(row4_ptr, 0x0)) +  \
							round_factor); \
					} \
 \
 					if(sizeof(type) < 4) \
					{ \
						*out_row++ = CLIP(r, 0, max); \
						*out_row++ = CLIP(g, 0, max); \
						*out_row++ = CLIP(b, 0, max); \
						if(components == 4) *out_row++ = CLIP(a, 0, max); \
					} \
					else \
					{ \
						*out_row++ = r; \
						*out_row++ = g; \
						*out_row++ = b; \
						if(components == 4) *out_row++ = a; \
					} \
				} \
				else \
/* Fill with chroma */ \
				{ \
					*out_row++ = 0; \
					*out_row++ = chroma_offset; \
					*out_row++ = chroma_offset; \
					if(components == 4) *out_row++ = 0; \
				} \
			} \
			else \
			{ \
				out_row += components; \
			} \
 \
/*  increment the transformed coordinates  */ \
			tx += xinc; \
			ty += yinc; \
			tw += winc; \
		} \
	} \
}

		switch(server->input->get_color_model())
		{
		case BC_RGB_FLOAT:
			TRANSFORM(3, float, float, 0x0, 1.0)
			break;
		case BC_RGB888:
			TRANSFORM(3, unsigned char, int, 0x0, 0xff)
			break;
		case BC_RGBA_FLOAT:
			TRANSFORM(4, float, float, 0x0, 1.0)
			break;
		case BC_RGBA8888:
			TRANSFORM(4, unsigned char, int, 0x0, 0xff)
			break;
		case BC_YUV888:
			{
				unsigned char **in_rows = (unsigned char**)server->input->get_rows();
				float round_factor = 0.0;
				if(sizeof(unsigned char) < 4) round_factor = 0.5;
				for(int y = ty1; y < ty2; y++)
				{
					unsigned char *out_row = (unsigned char*)server->output->get_rows()[y];

					if(!interpolate)
					{
						tx = xinc * (tx1 + 0.5) +
							m.values[0][1] * (y + pivot_offset_y + 0.5) +
							m.values[0][2] +
							pivot_offset_x * xinc;
						ty = yinc * (tx1 + 0.5) +
							m.values[1][1] * (y + pivot_offset_y + 0.5) +
							m.values[1][2] +
							pivot_offset_x * yinc;
						tw = winc * (tx1 + 0.5) +
							m.values[2][1] * (y + pivot_offset_y + 0.5) +
							m.values[2][2] +
							pivot_offset_x * winc;
					}
					else
					{
						tx = xinc * tx1 +
							m.values[0][1] * (y + pivot_offset_y) +
							m.values[0][2] +
							pivot_offset_x * xinc;
						ty = yinc * tx1 +
							m.values[1][1] * (y + pivot_offset_y) +
							m.values[1][2] +
							pivot_offset_x * yinc;
						tw = winc * tx1 +
							m.values[2][1] * (y + pivot_offset_y) +
							m.values[2][2] +
							pivot_offset_x * winc;
					}

					out_row += tx1 * 3;
					for(int x = tx1; x < tx2; x++)
					{
// Normalize homogeneous coords
						if(tw == 0.0)
						{
							ttx = 0.0;
							tty = 0.0;
						}
						else
						if(tw != 1.0)
						{
							ttx = tx / tw;
							tty = ty / tw;
						}
						else
						{
							ttx = tx;
							tty = ty;
						}
						itx = (int)ttx;
						ity = (int)tty;

						int row1 = ity - 1;
						int row2 = ity;
						int row3 = ity + 1;
						int row4 = ity + 2;
						CLAMP(row1, min_in_y, max_in_y);
						CLAMP(row2, min_in_y, max_in_y);
						CLAMP(row3, min_in_y, max_in_y);
						CLAMP(row4, min_in_y, max_in_y);
// Set destination pixels if in clipping region
						if(!interpolate &&
							x >= min_out_x &&
							x < max_out_x)
						{
							if(itx >= min_in_x &&
								itx <= max_in_x &&
								ity >= min_in_y &&
								ity <= max_in_y)
							{
								unsigned char *src = in_rows[ity] + itx * 3;
								*out_row++ = *src++;
								*out_row++ = *src++;
								*out_row++ = *src++;
							}
							else
// Fill with chroma
							{
								*out_row++ = 0;
								*out_row++ = 0x80;
								*out_row++ = 0x80;
							}
						}
						else
// Bicubic algorithm
						if(interpolate &&
							x >= min_out_x &&
							x < max_out_x)
						{
// clipping region
							if((itx + 2) >= min_in_x &&
								(itx - 1) <= max_in_x &&
								(ity + 2) >= min_in_y &&
								(ity - 1) <= max_in_y)
							{
								float dx, dy;
// the fractional error
								dx = ttx - itx;
								dy = tty - ity;
// Row and column offsets in cubic block
								int col1 = itx - 1;
								int col2 = itx;
								int col3 = itx + 1;
								int col4 = itx + 2;
								CLAMP(col1, min_in_x, max_in_x);
								CLAMP(col2, min_in_x, max_in_x);
								CLAMP(col3, min_in_x, max_in_x);
								CLAMP(col4, min_in_x, max_in_x);

								int col1_offset = col1 * 3;
								int col2_offset = col2 * 3;
								int col3_offset = col3 * 3;
								int col4_offset = col4 * 3;

								unsigned char *row1_ptr = in_rows[row1];
								unsigned char *row2_ptr = in_rows[row2];
								unsigned char *row3_ptr = in_rows[row3];
								unsigned char *row4_ptr = in_rows[row4];
								int r, g, b, a;

								r = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x0),
									CUBIC_ROW(row2_ptr, 0x0),
									CUBIC_ROW(row3_ptr, 0x0),
									CUBIC_ROW(row4_ptr, 0x0)) +
									round_factor);

								row1_ptr++;
								row2_ptr++;
								row3_ptr++;
								row4_ptr++;
								g = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x80),
									CUBIC_ROW(row2_ptr, 0x80),
									CUBIC_ROW(row3_ptr, 0x80),
									CUBIC_ROW(row4_ptr, 0x80)) +
									round_factor);
								g += 0x80;

								row1_ptr++;
								row2_ptr++;
								row3_ptr++;
								row4_ptr++;
								b = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x80),
									CUBIC_ROW(row2_ptr, 0x80),
									CUBIC_ROW(row3_ptr, 0x80),
									CUBIC_ROW(row4_ptr, 0x80)) +
									round_factor);
								b += 0x80;

								if(sizeof(unsigned char) < 4)
								{
									*out_row++ = CLIP(r, 0, 0xff);
									*out_row++ = CLIP(g, 0, 0xff);
									*out_row++ = CLIP(b, 0, 0xff);
								}
								else
								{
									*out_row++ = r;
									*out_row++ = g;
									*out_row++ = b;
								}
							}
							else
// Fill with chroma
							{
								*out_row++ = 0;
								*out_row++ = 0x80;
								*out_row++ = 0x80;
							}
						}
						else
						{
							out_row += 3;
						}

//  increment the transformed coordinates
						tx += xinc;
						ty += yinc;
						tw += winc;
					}
				}
			}

			break;
		case BC_YUVA8888:
			TRANSFORM(4, unsigned char, int, 0x80, 0xff)
			break;
		case BC_RGB161616:
			TRANSFORM(3, uint16_t, int, 0x0, 0xffff)
			break;
		case BC_RGBA16161616:
			TRANSFORM(4, uint16_t, int, 0x0, 0xffff)
			break;
		case BC_YUV161616:
			TRANSFORM(3, uint16_t, int, 0x8000, 0xffff)
			break;
		case BC_YUVA16161616:
			TRANSFORM(4, uint16_t, int, 0x8000, 0xffff)
			break;
		}
	}
Beispiel #5
0
void AffineUnit::calculate_matrix(
	double in_x1,
	double in_y1,
	double in_x2,
	double in_y2,
	double out_x1,
	double out_y1,
	double out_x2,
	double out_y2,
	double out_x3,
	double out_y3,
	double out_x4,
	double out_y4,
	AffineMatrix *result)
{
	AffineMatrix matrix;
	double scalex;
	double scaley;

	scalex = scaley = 1.0;

	if((in_x2 - in_x1) > 0)
		scalex = 1.0 / (double)(in_x2 - in_x1);

	if((in_y2 - in_y1) > 0)
		scaley = 1.0 / (double)(in_y2 - in_y1);

// Determine the perspective transform that maps from
// the unit cube to the transformed coordinates
	double dx1, dx2, dx3, dy1, dy2, dy3;
	double det1, det2;

	dx1 = out_x2 - out_x4;
	dx2 = out_x3 - out_x4;
	dx3 = out_x1 - out_x2 + out_x4 - out_x3;

	dy1 = out_y2 - out_y4;
	dy2 = out_y3 - out_y4;
	dy3 = out_y1 - out_y2 + out_y4 - out_y3;

//  Is the mapping affine?
	if((dx3 == 0.0) && (dy3 == 0.0))
	{
		matrix.values[0][0] = out_x2 - out_x1;
		matrix.values[0][1] = out_x4 - out_x2;
		matrix.values[0][2] = out_x1;
		matrix.values[1][0] = out_y2 - out_y1;
		matrix.values[1][1] = out_y4 - out_y2;
		matrix.values[1][2] = out_y1;
		matrix.values[2][0] = 0.0;
		matrix.values[2][1] = 0.0;
	}
	else
	{
		det1 = dx3 * dy2 - dy3 * dx2;
		det2 = dx1 * dy2 - dy1 * dx2;
		matrix.values[2][0] = det1 / det2;
		det1 = dx1 * dy3 - dy1 * dx3;
		det2 = dx1 * dy2 - dy1 * dx2;
		matrix.values[2][1] = det1 / det2;

		matrix.values[0][0] = out_x2 - out_x1 + matrix.values[2][0] * out_x2;
		matrix.values[0][1] = out_x3 - out_x1 + matrix.values[2][1] * out_x3;
		matrix.values[0][2] = out_x1;

		matrix.values[1][0] = out_y2 - out_y1 + matrix.values[2][0] * out_y2;
		matrix.values[1][1] = out_y3 - out_y1 + matrix.values[2][1] * out_y3;
		matrix.values[1][2] = out_y1;
	}

	matrix.values[2][2] = 1.0;

	result->identity();
	result->translate(-in_x1, -in_y1);
	result->scale(scalex, scaley);
	matrix.multiply(result);
}
void AffineUnit::calculate_matrix(
	double in_x1,
	double in_y1,
	double in_x2,
	double in_y2,
	double out_x1,
	double out_y1,
	double out_x2,
	double out_y2,
	double out_x3,
	double out_y3,
	double out_x4,
	double out_y4,
	AffineMatrix *result)
{
	AffineMatrix matrix;
	double scalex;
	double scaley;

	scalex = scaley = 1.0;

	if((in_x2 - in_x1) > 0)
      	scalex = 1.0 / (double)(in_x2 - in_x1);

	if((in_y2 - in_y1) > 0)
      	scaley = 1.0 / (double)(in_y2 - in_y1);

/* Determine the perspective transform that maps from
 * the unit cube to the transformed coordinates
 */
    double dx1, dx2, dx3, dy1, dy2, dy3;
    double det1, det2;

    dx1 = out_x2 - out_x4;
    dx2 = out_x3 - out_x4;
    dx3 = out_x1 - out_x2 + out_x4 - out_x3;

    dy1 = out_y2 - out_y4;
    dy2 = out_y3 - out_y4;
    dy3 = out_y1 - out_y2 + out_y4 - out_y3;
// printf("AffineUnit::calculate_matrix %f %f %f %f %f %f\n",
// dx1,
// dx2,
// dx3,
// dy1,
// dy2,
// dy3
// );

/*  Is the mapping affine?  */
    if((dx3 == 0.0) && (dy3 == 0.0))
    {
        matrix.values[0][0] = out_x2 - out_x1;
        matrix.values[0][1] = out_x4 - out_x2;
        matrix.values[0][2] = out_x1;
        matrix.values[1][0] = out_y2 - out_y1;
        matrix.values[1][1] = out_y4 - out_y2;
        matrix.values[1][2] = out_y1;
        matrix.values[2][0] = 0.0;
        matrix.values[2][1] = 0.0;
    }
    else
    {
        det1 = dx3 * dy2 - dy3 * dx2;
        det2 = dx1 * dy2 - dy1 * dx2;
        matrix.values[2][0] = det1 / det2;
        det1 = dx1 * dy3 - dy1 * dx3;
        det2 = dx1 * dy2 - dy1 * dx2;
        matrix.values[2][1] = det1 / det2;

        matrix.values[0][0] = out_x2 - out_x1 + matrix.values[2][0] * out_x2;
        matrix.values[0][1] = out_x3 - out_x1 + matrix.values[2][1] * out_x3;
        matrix.values[0][2] = out_x1;

        matrix.values[1][0] = out_y2 - out_y1 + matrix.values[2][0] * out_y2;
        matrix.values[1][1] = out_y3 - out_y1 + matrix.values[2][1] * out_y3;
        matrix.values[1][2] = out_y1;
    }

    matrix.values[2][2] = 1.0;

// printf("AffineUnit::calculate_matrix 1 %f %f\n", dx3, dy3);
// matrix.dump();

	result->identity();
	result->translate(-in_x1, -in_y1);
	result->scale(scalex, scaley);
	matrix.multiply(result);
// double test[3][3] = { { 0.0896, 0.0, 0.0 },
// 				  { 0.0, 0.0896, 0.0 },
// 				  { -0.00126, 0.0, 1.0 } };
// memcpy(&result->values[0][0], test, sizeof(test));
// printf("AffineUnit::calculate_matrix 4 %p\n", result);
// result->dump();


}