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); }
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 ); }
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"); }
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; } }
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(); }