// --------------------------------------------------------- matrix_frustum --- matrix_t * matrix_frustum( matrix_t *self, float left, float right, float bottom, float top, float z_near, float z_far ) { assert( self ); float dx = right - left; float dy = top - bottom; float dz = z_far - z_near; if ( (z_near <= 0.0) || (z_far <= 0.0) || (dx <= 0.0) || (dy <= 0.0) || (dz <= 0.0) ) { return self; } matrix_t frustum; matrix_load_identity( &frustum ); float *data = frustum.data; data[0*4+0] = 2.0 * z_near / dx; data[1*4+1] = 2.0 * z_near / dy; data[2*4+0] = +(right + left) / dx; data[2*4+1] = +(top + bottom) / dy; data[2*4+2] = -(z_near + z_far) / dz; data[2*4+3] = -1.0; data[3*4+2] = -2.0 * z_near * z_far / dz; matrix_multiply( &frustum, self ); memcpy( self, &frustum, sizeof( matrix_t ) ); return self; }
// ----------------------------------------------------------- matrix_ortho --- matrix_t * matrix_ortho( matrix_t *self, float left, float right, float bottom, float top, float z_near, float z_far ) { assert( self ); float dx = right - left; float dy = top - bottom; float dz = z_far - z_near; if ( (dx == 0.0) || (dy == 0.0) || (dz == 0.0) ) { return self; } matrix_t ortho; matrix_load_identity( &ortho ); float *data = ortho.data; data[0*4+0] = 2.0 / dx; data[3*4+0] = -(right + left) / dx; data[1*4+1] = 2.0 / dy; data[3*4+1] = -(top + bottom) / dy; data[2*4+2] = -2.0 / dz; data[3*4+2] = -(z_near + z_far) / dz; data[3*4+3] = 1.0; matrix_multiply( &ortho, self ); memcpy( self, &ortho, sizeof( matrix_t ) ); return self; }
// --------------------------------------------------------------- reshape --- void reshape(int width, int height) { glViewport( 0, 0, width, height ); matrix_load_identity( &projection ); matrix_ortho( &projection, 0, width, 0, height, -1000, +1000 ); matrix_load_identity( &modelview ); glMatrixMode( GL_PROJECTION ); glLoadMatrixf( projection.data ); glMatrixMode( GL_MODELVIEW ); glLoadMatrixf( modelview.data ); glutPostRedisplay( ); }
// ---------------------------------------------------------- matrix_rotate --- matrix_t * matrix_rotate( matrix_t *self, float angle, float x, float y, float z ) { assert( self ); float mag = sqrt(x*x + y*y + z*z); if( mag <= 0 ) { return self; } float sin_angle = sin( angle * M_PI / 180.0 ); float cos_angle = cos( angle * M_PI / 180.0 ); float one_minus_cos= 1.0 - cos_angle; float xx, yy, zz, xy, yz, zx, xs, ys, zs; matrix_t rotation; matrix_load_identity( &rotation ); float *data = rotation.data; x /= mag; y /= mag; z /= mag; xx = x * x; yy = y * y; zz = z * z; xy = x * y; yz = y * z; zx = z * x; xs = x * sin_angle; ys = y * sin_angle; zs = z * sin_angle; data[0*4+0] = (one_minus_cos * xx) + cos_angle; data[0*4+1] = (one_minus_cos * xy) - zs; data[0*4+2] = (one_minus_cos * zx) + ys; data[1*4+0] = (one_minus_cos * xy) + zs; data[1*4+1] = (one_minus_cos * yy) + cos_angle; data[1*4+2] = (one_minus_cos * yz) - xs; data[2*4+0] = (one_minus_cos * zx) - ys; data[2*4+1] = (one_minus_cos * yz) + xs; data[2*4+2] = (one_minus_cos * zz) + cos_angle; data[3*4+3] = 1.0; matrix_multiply( &rotation, self ); memcpy( self, &rotation, sizeof( matrix_t ) ); return self; }
/** * Propogate OpenVG state changes to the renderer. Only framebuffer, blending * and scissoring states are relevant here. */ void renderer_validate(struct renderer *renderer, VGbitfield dirty, const struct st_framebuffer *stfb, const struct vg_state *state) { assert(renderer->state == RENDERER_STATE_INIT); dirty |= renderer->dirty; renderer->dirty = 0; if (dirty & FRAMEBUFFER_DIRTY) { struct pipe_framebuffer_state *fb = &renderer->g3d.fb; struct matrix *proj = &renderer->projection; memset(fb, 0, sizeof(struct pipe_framebuffer_state)); fb->width = stfb->width; fb->height = stfb->height; fb->nr_cbufs = 1; fb->cbufs[0] = stfb->strb->surface; fb->zsbuf = stfb->dsrb->surface; cso_set_framebuffer(renderer->cso, fb); vg_set_viewport(renderer, VEGA_Y0_BOTTOM); matrix_load_identity(proj); matrix_translate(proj, -1.0f, -1.0f); matrix_scale(proj, 2.0f / fb->width, 2.0f / fb->height); /* we also got a new depth buffer */ if (dirty & DEPTH_STENCIL_DIRTY) { renderer->pipe->clear(renderer->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0); } } /* must be last because it renders to the depth buffer*/ if (dirty & DEPTH_STENCIL_DIRTY) { update_clip_state(renderer, state); cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa); } if (dirty & BLEND_DIRTY) renderer_validate_blend(renderer, state, stfb->strb->format); }
static VGboolean find_angles(struct arc *arc) { double vec0[2], vec1[2]; double lambda1, lambda2; double angle; struct matrix matrix; if (floatIsZero(arc->a) || floatIsZero(arc->b)) { return VG_FALSE; } /* map the points to an identity circle */ matrix_load_identity(&matrix); matrix_scale(&matrix, 1.f, arc->a/arc->b); matrix_rotate(&matrix, -arc->theta); matrix_map_point(&matrix, arc->x1, arc->y1, &arc->x1, &arc->y1); matrix_map_point(&matrix, arc->x2, arc->y2, &arc->x2, &arc->y2); matrix_map_point(&matrix, arc->cx, arc->cy, &arc->cx, &arc->cy); #if DEBUG_ARCS debug_printf("Matrix 3 [%f, %f, %f| %f, %f, %f| %f, %f, %f]\n", matrix.m[0], matrix.m[1], matrix.m[2], matrix.m[3], matrix.m[4], matrix.m[5], matrix.m[6], matrix.m[7], matrix.m[8]); debug_printf("Endpoints [%f, %f], [%f, %f]\n", arc->x1, arc->y1, arc->x2, arc->y2); #endif vec0[0] = arc->x1 - arc->cx; vec0[1] = arc->y1 - arc->cy; vec1[0] = arc->x2 - arc->cx; vec1[1] = arc->y2 - arc->cy; #if DEBUG_ARCS debug_printf("Vec is [%f, %f], [%f, %f], [%f, %f]\n", vec0[0], vec0[1], vec1[0], vec1[1], arc->cx, arc->cy); #endif lambda1 = vector_orientation(vec0); if (isnan(lambda1)) lambda1 = 0.f; if (arc->type == VG_SCWARC_TO || arc->type == VG_SCCWARC_TO) angle = vector_angles(vec0, vec1); else if (arc->type == VG_LCWARC_TO || arc->type == VG_LCCWARC_TO) { angle = 2*M_PI - vector_angles(vec0, vec1); } else abort(); if (isnan(angle)) angle = M_PI; if (arc->type == VG_SCWARC_TO || arc->type == VG_LCWARC_TO) lambda2 = lambda1 - angle; else lambda2 = lambda1 + angle; #if DEBUG_ARCS debug_printf("Angle is %f and (%f, %f)\n", angle, lambda1, lambda2); #endif #if 0 arc->eta1 = atan2(sin(lambda1) / arc->b, cos(lambda1) / arc->a); arc->eta2 = atan2(sin(lambda2) / arc->b, cos(lambda2) / arc->a); /* make sure we have eta1 <= eta2 <= eta1 + 2 PI */ arc->eta2 -= two_pi * floor((arc->eta2 - arc->eta1) / two_pi); /* the preceding correction fails if we have exactly et2 - eta1 = 2 PI it reduces the interval to zero length */ if ((lambda2 - lambda1 > M_PI) && (arc->eta2 - arc->eta1 < M_PI)) { arc->eta2 += 2 * M_PI; } #else arc->eta1 = lambda1; arc->eta2 = lambda2; #endif return VG_TRUE; }
void vg_init_state(struct vg_state *state) { state->matrix_mode = VG_MATRIX_PATH_USER_TO_SURFACE; state->fill_rule = VG_EVEN_ODD; state->image_quality = VG_IMAGE_QUALITY_FASTER; state->rendering_quality = VG_RENDERING_QUALITY_BETTER; state->blend_mode = VG_BLEND_SRC_OVER; state->image_mode = VG_DRAW_IMAGE_NORMAL; memset(state->scissor_rects, 0, sizeof(state->scissor_rects)); state->scissor_rects_num = 0; state->color_transform = VG_FALSE; state->color_transform_values[0] = 1.0f; state->color_transform_values[1] = 1.0f; state->color_transform_values[2] = 1.0f; state->color_transform_values[3] = 1.0f; state->color_transform_values[4] = 0.0f; state->color_transform_values[5] = 0.0f; state->color_transform_values[6] = 0.0f; state->color_transform_values[7] = 0.0f; /* Stroke parameters */ state->stroke.line_width.f = 1.0f; state->stroke.line_width.i = 1; state->stroke.cap_style = VG_CAP_BUTT; state->stroke.join_style = VG_JOIN_MITER; state->stroke.miter_limit.f = 4.0f; state->stroke.miter_limit.i = 4; state->stroke.dash_pattern_num = 0; state->stroke.dash_phase.f = 0.0f; state->stroke.dash_phase.i = 0; state->stroke.dash_phase_reset = VG_FALSE; /* Edge fill color for VG_TILE_FILL tiling mode */ state->tile_fill_color[0] = 0.0f; state->tile_fill_color[1] = 0.0f; state->tile_fill_color[2] = 0.0f; state->tile_fill_color[3] = 0.0f; /* Color for vgClear */ state->clear_color[0] = 0.0f; state->clear_color[1] = 0.0f; state->clear_color[2] = 0.0f; state->clear_color[3] = 0.0f; /* Glyph origin */ state->glyph_origin[0].f = 0.0f; state->glyph_origin[1].f = 0.0f; state->glyph_origin[0].i = 0; state->glyph_origin[1].i = 0; /* Enable/disable alpha masking and scissoring */ state->masking = VG_FALSE; state->scissoring = VG_FALSE; /* Pixel layout information */ state->pixel_layout = VG_PIXEL_LAYOUT_UNKNOWN; state->screen_layout = VG_PIXEL_LAYOUT_UNKNOWN; /* Source format selection for image filters */ state->filter_format_linear = VG_FALSE; state->filter_format_premultiplied = VG_FALSE; /* Destination write enable mask for image filters */ state->filter_channel_mask = (VG_RED | VG_GREEN | VG_BLUE | VG_ALPHA); matrix_load_identity(&state->path_user_to_surface_matrix); matrix_load_identity(&state->image_user_to_surface_matrix); matrix_load_identity(&state->fill_paint_to_user_matrix); matrix_load_identity(&state->stroke_paint_to_user_matrix); matrix_load_identity(&state->glyph_user_to_surface_matrix); }