Main() { isClicked = false; screen = Vec2<unsigned int>(800, 600); std::setlocale(LC_ALL, "en_US.UTF-8"); glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); GLFWwindow* window = glfwCreateWindow(screen.x, screen.y, "test", nullptr, nullptr); if (window == nullptr) { printf("cant create window"); return; } glfwSetWindowSizeCallback(window, windowSizeCallback); glfwSetKeyCallback(window, keyCallback); glfwSetMouseButtonCallback(window, clickCallback); glfwSetCursorPosCallback(window, mouseCallback); glfwMakeContextCurrent(window); glewExperimental = true; glewInit(); //glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback(debugCallback, nullptr); glEnable(GL_DEBUG_OUTPUT); printf("%s\n", glGetString(GL_VERSION)); Shader* fs = new Shader("res/shader/fragment.c", true, GL_FRAGMENT_SHADER); Shader* vs = new Shader("res/shader/vertex.c", true, GL_VERTEX_SHADER); Program* p = new Program(); p->attach(fs); p->attach(vs); p->build(); p->use(); tm = new TextureManager(); font = new Font(512, "res/font/DroidSans.woff", 32, tm); print = new Print(font); //print.set(&font, "res/shader/fontVertex.c", "res/shader/fontFragment.c"); print->setScreenSize(screen); glm::vec2* vert = new glm::vec2[1024]; uint32_t vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); uint32_t vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(0); glBufferData(GL_ARRAY_BUFFER, 1024 * sizeof(glm::vec2), vert, GL_DYNAMIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_BLEND); glfwSetWindowUserPointer(window, this); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); tr = new TileRenderer(); d = new Drawing(tr); tr->setScreenSize(screen); //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); double time, timeo; glfwSwapInterval(0); while(!glfwWindowShouldClose(window)) { timeo = time; time = glfwGetTime(); glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); d->render(); //tr->renderTile(t); print->printfAt(-0.3f, 0.7f, 16.0f, 16.0f, u8"Fps:%03.3f", 1/(time-timeo)); glfwSwapBuffers(window); glfwWaitEvents(); } std::cout << "Hello World. I'm Peach." << std::endl; }
void FilterImage::render_cairo(FilterSlot &slot) { if (!feImageHref) return; //cairo_surface_t *input = slot.getcairo(_input); // Viewport is filter primitive area (in user coordinates). // Note: viewport calculation in non-trivial. Do not rely // on get_matrix_primitiveunits2pb(). Geom::Rect vp = filter_primitive_area( slot.get_units() ); slot.set_primitive_area(_output, vp); // Needed for tiling double feImageX = vp.min()[Geom::X]; double feImageY = vp.min()[Geom::Y]; double feImageWidth = vp.width(); double feImageHeight = vp.height(); // feImage is suppose to use the same parameters as a normal SVG image. // If a width or height is set to zero, the image is not suppose to be displayed. // This does not seem to be what Firefox or Opera does, nor does the W3C displacement // filter test expect this behavior. If the width and/or height are zero, we use // the width and height of the object bounding box. Geom::Affine m = slot.get_units().get_matrix_user2filterunits().inverse(); Geom::Point bbox_00 = Geom::Point(0,0) * m; Geom::Point bbox_w0 = Geom::Point(1,0) * m; Geom::Point bbox_0h = Geom::Point(0,1) * m; double bbox_width = Geom::distance(bbox_00, bbox_w0); double bbox_height = Geom::distance(bbox_00, bbox_0h); if( feImageWidth == 0 ) feImageWidth = bbox_width; if( feImageHeight == 0 ) feImageHeight = bbox_height; // Internal image, like <use> if (from_element) { if (!SVGElem) return; // TODO: do not recreate the rendering tree every time // TODO: the entire thing is a hack, we should give filter primitives an "update" method // like the one for DrawingItems document->ensureUpToDate(); Drawing drawing; Geom::OptRect optarea = SVGElem->visualBounds(); if (!optarea) return; unsigned const key = SPItem::display_key_new(1); DrawingItem *ai = SVGElem->invoke_show(drawing, key, SP_ITEM_SHOW_DISPLAY); if (!ai) { g_warning("feImage renderer: error creating DrawingItem for SVG Element"); return; } drawing.setRoot(ai); Geom::Rect area = *optarea; Geom::Affine user2pb = slot.get_units().get_matrix_user2pb(); /* FIXME: These variables are currently unused. Why were they calculated? double scaleX = feImageWidth / area.width(); double scaleY = feImageHeight / area.height(); */ Geom::Rect sa = slot.get_slot_area(); cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, sa.width(), sa.height()); Inkscape::DrawingContext dc(out, sa.min()); dc.transform(user2pb); // we are now in primitive units dc.translate(feImageX, feImageY); // dc.scale(scaleX, scaleY); No scaling should be done Geom::IntRect render_rect = area.roundOutwards(); // dc.translate(render_rect.min()); This seems incorrect // Update to renderable state drawing.update(render_rect); drawing.render(dc, render_rect); SVGElem->invoke_hide(key); // For the moment, we'll assume that any image is in sRGB color space set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); slot.set(_output, out); cairo_surface_destroy(out); return; } // External image, like <image> if (!image && !broken_ref) { broken_ref = true; /* TODO: If feImageHref is absolute, then use that (preferably handling the * case that it's not a file URI). Otherwise, go up the tree looking * for an xml:base attribute, and use that as the base URI for resolving * the relative feImageHref URI. Otherwise, if document->base is valid, * then use that as the base URI. Otherwise, use feImageHref directly * (i.e. interpreting it as relative to our current working directory). * (See http://www.w3.org/TR/xmlbase/#resolution .) */ gchar *fullname = feImageHref; if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) { // Try to load from relative postion combined with document base if( document ) { fullname = g_build_filename( document->getBase(), feImageHref, NULL ); } } if ( !g_file_test( fullname, G_FILE_TEST_EXISTS ) ) { // Should display Broken Image png. g_warning("FilterImage::render: Can not find: %s", feImageHref ); return; } image = Inkscape::Pixbuf::create_from_file(fullname); if( fullname != feImageHref ) g_free( fullname ); if ( !image ) { g_warning("FilterImage::render: failed to load image: %s", feImageHref); return; } broken_ref = false; } if (broken_ref) { return; } cairo_surface_t *image_surface = image->getSurfaceRaw(); Geom::Rect sa = slot.get_slot_area(); cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, sa.width(), sa.height()); // For the moment, we'll assume that any image is in sRGB color space // set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); // This seemed like a sensible thing to do but it breaks filters-displace-01-f.svg cairo_t *ct = cairo_create(out); cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]); // now ct is in pb coordinates, note the feWidth etc. are in user units ink_cairo_transform(ct, slot.get_units().get_matrix_user2pb()); // now ct is in the coordinates of feImageX etc. // Now that we have the viewport, we must map image inside. // Partially copied from sp-image.cpp. // Do nothing if preserveAspectRatio is "none". if( aspect_align != SP_ASPECT_NONE ) { // Check aspect ratio of image vs. viewport double feAspect = feImageHeight/feImageWidth; double aspect = (double)image->height()/(double)image->width(); bool ratio = (feAspect < aspect); double ax, ay; // Align side switch( aspect_align ) { case SP_ASPECT_XMIN_YMIN: ax = 0.0; ay = 0.0; break; case SP_ASPECT_XMID_YMIN: ax = 0.5; ay = 0.0; break; case SP_ASPECT_XMAX_YMIN: ax = 1.0; ay = 0.0; break; case SP_ASPECT_XMIN_YMID: ax = 0.0; ay = 0.5; break; case SP_ASPECT_XMID_YMID: ax = 0.5; ay = 0.5; break; case SP_ASPECT_XMAX_YMID: ax = 1.0; ay = 0.5; break; case SP_ASPECT_XMIN_YMAX: ax = 0.0; ay = 1.0; break; case SP_ASPECT_XMID_YMAX: ax = 0.5; ay = 1.0; break; case SP_ASPECT_XMAX_YMAX: ax = 1.0; ay = 1.0; break; default: ax = 0.0; ay = 0.0; break; } if( aspect_clip == SP_ASPECT_SLICE ) { // image clipped by viewbox if( ratio ) { // clip top/bottom feImageY -= ay * (feImageWidth * aspect - feImageHeight); feImageHeight = feImageWidth * aspect; } else { // clip sides feImageX -= ax * (feImageHeight / aspect - feImageWidth); feImageWidth = feImageHeight / aspect; } } else { // image fits into viewbox if( ratio ) { // fit to height feImageX += ax * (feImageWidth - feImageHeight / aspect ); feImageWidth = feImageHeight / aspect; } else { // fit to width feImageY += ay * (feImageHeight - feImageWidth * aspect); feImageHeight = feImageWidth * aspect; } } } double scaleX = feImageWidth / image->width(); double scaleY = feImageHeight / image->height(); cairo_translate(ct, feImageX, feImageY); cairo_scale(ct, scaleX, scaleY); cairo_set_source_surface(ct, image_surface, 0, 0); cairo_paint(ct); cairo_destroy(ct); slot.set(_output, out); }