Example #1
0
/* Draw a special object on all viewports */
static void draw_special (struct SpecialObj *object)
{
    int p;
    for(p=0;p<4;p++) {
        if (players[p].state==ALIVE||players[p].state==DEAD) {
            SDL_Rect rect = {0,0, object->gfx[0]->w, object->gfx[0]->h};
            SDL_Rect rect2;
            if(object->secret && p!=object->owner) continue;
            rect.x = object->x - rect.w/2 - cam_rects[p].x + viewport_rects[p].x;
            rect.y = object->y - rect.h/2 - cam_rects[p].y + viewport_rects[p].y;
            if ((rect.x > viewport_rects[p].x - rect.w
                 && rect.x < viewport_rects[p].x + cam_rects[p].w)
                && (rect.y > viewport_rects[p].y - rect.h
                    && rect.y < viewport_rects[p].y + cam_rects[p].h)) {
                rect2 =
                    cliprect (rect.x, rect.y, rect.w, rect.h, viewport_rects[p].x,
                              viewport_rects[p].y, viewport_rects[p].x + cam_rects[p].w,
                              viewport_rects[p].y + cam_rects[p].h);
                if (rect.x < viewport_rects[p].x)
                    rect.x = viewport_rects[p].x;
                if (rect.y < viewport_rects[p].y)
                    rect.y = viewport_rects[p].y;
                SDL_BlitSurface (object->gfx[object->frame], &rect2, screen,
                                 &rect);
            }
        }
    }
}
Example #2
0
void
drawtri(Image *img, Rect r, short *a, short *b, short *c, uchar *color)
{
	img->dirty = 1;
	r = cliprect(r, img->r);
	rect_trisetup(&r, a, b, c);
	drawtri_horse(img, &r, a, b, c, color);
}
Example #3
0
void plotPathsToPainter(QPainter& painter, QPainterPath& path,
			const Numpy1DObj& x, const Numpy1DObj& y,
			const Numpy1DObj* scaling,
			const QRectF* clip,
			const QImage* colorimg)
{
  QRectF cliprect( QPointF(-32767,-32767), QPointF(32767,32767) );
  if( clip != 0 )
    {
      qreal x1, y1, x2, y2;
      clip->getCoords(&x1, &y1, &x2, &y2);
      cliprect.setCoords(x1, y1, x2, y2);
    }
  QRectF pathbox = path.boundingRect();
  cliprect.adjust(pathbox.left(), pathbox.top(),
		  pathbox.bottom(), pathbox.right());

  // keep track of duplicate points
  QPointF lastpt(-1e6, -1e6);
  // keep original transformation for restoration after each iteration
  QTransform origtrans(painter.worldTransform());

  // number of iterations
  int size = min(x.dim, y.dim);

  // if few color points, trim down number of paths
  if( colorimg != 0 )
    size = min(size, colorimg->width());
  // too few scaling points
  if( scaling != 0 )
    size = min(size, scaling->dim);

  // draw each path
  for(int i = 0; i < size; ++i)
    {
      const QPointF pt(x(i), y(i));
      if( cliprect.contains(pt) && ! smallDelta(lastpt, pt) )
	{
	  painter.translate(pt);
	  if( scaling != 0 )
	    {
	      // scale point if requested
	      const qreal s = (*scaling)(i);
	      painter.scale(s, s);
	    }
	  if( colorimg != 0 )
	    {
	      // get color from pixel and create a new brush
	      QBrush b( QColor::fromRgba(colorimg->pixel(i, 0)) );
	      painter.setBrush(b);
	    }

	  painter.drawPath(path);
	  painter.setWorldTransform(origtrans);
	  lastpt = pt;
	}
    }
}
Example #4
0
/* Draw a critter on all active viewports */
static void draw_critter (struct Critter * critter)
{
    int p;
    for (p = 0; p < 4; p++) {
        if (players[p].state==ALIVE || players[p].state==DEAD) {
            SDL_Rect rect, rect2;
            rect.x = critter->physics.x - critter->gfx_rect.w/2;
            rect.y = critter->physics.y;
            if(critter->type==GROUNDCRITTER)
                rect.y -= critter->gfx_rect.h;
            else
                rect.y -= critter->gfx_rect.h/2;

            rect.x = rect.x - cam_rects[p].x + viewport_rects[p].x;
            rect.y = rect.y - cam_rects[p].y + viewport_rects[p].y;
            if ((rect.x > viewport_rects[p].x - critter->gfx_rect.w
                 && rect.x < viewport_rects[p].x + cam_rects[p].w)
                && (rect.y > viewport_rects[p].y - critter->gfx_rect.h
                    && rect.y < viewport_rects[p].y + cam_rects[p].h)) {
                rect2 =
                    cliprect (rect.x, rect.y, critter->gfx_rect.w,
                            critter->gfx_rect.h, viewport_rects[p].x,
                            viewport_rects[p].y,
                            viewport_rects[p].x + cam_rects[p].w,
                            viewport_rects[p].y + cam_rects[p].h);
                rect2.x += critter->gfx_rect.x;
                rect2.y += critter->gfx_rect.y;
                if (rect.x < viewport_rects[p].x)
                    rect.x = viewport_rects[p].x;
                if (rect.y < viewport_rects[p].y)
                    rect.y = viewport_rects[p].y;
                SDL_BlitSurface (critter->gfx[critter->frame],
                        &rect2, screen, &rect);
                if(critter->frozen && iceblock) {
                    rect.x = rect.x + critter->gfx_rect.w/2 - iceblock->w/2;
                    rect.y = rect.y + critter->gfx_rect.h/2 - iceblock->h/2;
                    SDL_BlitSurface(iceblock, NULL, screen, &rect);
                }
#if 0
                /* Debugging aid: display critter target */
                if(critter->type!=GROUNDCRITTER) {
                    int x = critter->flyer.targx-cam_rects[p].x;
                    int y = critter->flyer.targy-cam_rects[p].y;
                    if(x>0 && x<cam_rects[p].w && y>0 && y<cam_rects[p].h)
                        putpixel(screen,x+viewport_rects[p].x,y+viewport_rects[p].y,col_red);
                        putpixel(screen,x+2+viewport_rects[p].x,y+viewport_rects[p].y,col_red);
                        putpixel(screen,x-2+viewport_rects[p].x,y+viewport_rects[p].y,col_red);
                        putpixel(screen,x+viewport_rects[p].x,y+2+viewport_rects[p].y,col_red);
                        putpixel(screen,x+viewport_rects[p].x,y-2+viewport_rects[p].y,col_red);
                }
#endif
            }
        }
    }
}
Example #5
0
void MTOSWindow::draw(MTRect &rect)
{
    MTBitmap *mb;
    int ox = left;
    int oy = top;
    HDC ddc;
    MTRect r = {0,0,width,height};

    if ((!compat) || (!active)) {
        if (&rect) cliprect(r,rect);
        preparedraw(&mb,ox,oy);
        ddc = (HDC)mb->open(0);
        BitBlt(ddc,ox+r.left,oy+r.top,r.right-r.left,r.bottom-r.top,dc,r.left,r.top,SRCCOPY);
        mb->close(ddc);
    };
    MTControl::draw(rect);
}
Example #6
0
bool TextureSource::generateImage(std::string part_of_name, video::IImage *& baseimg)
{
	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	// Stuff starting with [ are special commands
	if(part_of_name.size() == 0 || part_of_name[0] != '[')
	{
		video::IImage *image = m_sourcecache.getOrLoad(part_of_name, m_device);

		if(image == NULL)
		{
			if(part_of_name != ""){
				errorstream<<"generateImage(): Could not load image \""
						<<part_of_name<<"\""<<" while building texture"<<std::endl;
				errorstream<<"generateImage(): Creating a dummy"
						<<" image for \""<<part_of_name<<"\""<<std::endl;
			}

			// Just create a dummy image
			//core::dimension2d<u32> dim(2,2);
			core::dimension2d<u32> dim(1,1);
			image = driver->createImage(video::ECF_A8R8G8B8, dim);
			assert(image);
			/*image->setPixel(0,0, video::SColor(255,255,0,0));
			image->setPixel(1,0, video::SColor(255,0,255,0));
			image->setPixel(0,1, video::SColor(255,0,0,255));
			image->setPixel(1,1, video::SColor(255,255,0,255));*/
			image->setPixel(0,0, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			/*image->setPixel(1,0, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			image->setPixel(0,1, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			image->setPixel(1,1, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));*/
		}

		// If base image is NULL, load as base.
		if(baseimg == NULL)
		{
			//infostream<<"Setting "<<part_of_name<<" as base"<<std::endl;
			/*
				Copy it this way to get an alpha channel.
				Otherwise images with alpha cannot be blitted on
				images that don't have alpha in the original file.
			*/
			core::dimension2d<u32> dim = image->getDimension();
			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
			image->copyTo(baseimg);
		}
		// Else blit on base.
		else
		{
			//infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
			// Size of the copied area
			core::dimension2d<u32> dim = image->getDimension();
			//core::dimension2d<u32> dim(16,16);
			// Position to copy the blitted to in the base image
			core::position2d<s32> pos_to(0,0);
			// Position to copy the blitted from in the blitted image
			core::position2d<s32> pos_from(0,0);
			// Blit
			/*image->copyToWithAlpha(baseimg, pos_to,
					core::rect<s32>(pos_from, dim),
					video::SColor(255,255,255,255),
					NULL);*/
			blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
		}
		//cleanup
		image->drop();
	}
	else
	{
		// A special texture modification

		/*infostream<<"generateImage(): generating special "
				<<"modification \""<<part_of_name<<"\""
				<<std::endl;*/

		/*
			[crack:N:P
			[cracko:N:P
			Adds a cracking texture
			N = animation frame count, P = crack progression
		*/
		if(part_of_name.substr(0,6) == "[crack")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generateImage(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			// Crack image number and overlay option
			bool use_overlay = (part_of_name[6] == 'o');
			Strfnd sf(part_of_name);
			sf.next(":");
			s32 frame_count = stoi(sf.next(":"));
			s32 progression = stoi(sf.next(":"));

			/*
				Load crack image.

				It is an image with a number of cracking stages
				horizontally tiled.
			*/
			video::IImage *img_crack = m_sourcecache.getOrLoad(
					"crack_anylength.png", m_device);

			if(img_crack && progression >= 0)
			{
				draw_crack(img_crack, baseimg,
						use_overlay, frame_count,
						progression, driver);
				img_crack->drop();
			}
		}
		/*
			[combine:WxH:X,Y=filename:X,Y=filename2
			Creates a bigger texture from an amount of smaller ones
		*/
		else if(part_of_name.substr(0,8) == "[combine")
		{
			Strfnd sf(part_of_name);
			sf.next(":");
			u32 w0 = stoi(sf.next("x"));
			u32 h0 = stoi(sf.next(":"));
			infostream<<"combined w="<<w0<<" h="<<h0<<std::endl;
			core::dimension2d<u32> dim(w0,h0);
			if(baseimg == NULL)
			{
				baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
				baseimg->fill(video::SColor(0,0,0,0));
			}
			while(sf.atend() == false)
			{
				u32 x = stoi(sf.next(","));
				u32 y = stoi(sf.next("="));
				std::string filename = sf.next(":");
				infostream<<"Adding \""<<filename
						<<"\" to combined ("<<x<<","<<y<<")"
						<<std::endl;
				video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
				if(img)
				{
					core::dimension2d<u32> dim = img->getDimension();
					infostream<<"Size "<<dim.Width
							<<"x"<<dim.Height<<std::endl;
					core::position2d<s32> pos_base(x, y);
					video::IImage *img2 =
							driver->createImage(video::ECF_A8R8G8B8, dim);
					img->copyTo(img2);
					img->drop();
					/*img2->copyToWithAlpha(baseimg, pos_base,
							core::rect<s32>(v2s32(0,0), dim),
							video::SColor(255,255,255,255),
							NULL);*/
					blit_with_alpha(img2, baseimg, v2s32(0,0), pos_base, dim);
					img2->drop();
				}
				else
				{
					infostream<<"img==NULL"<<std::endl;
				}
			}
		}
		/*
			"[brighten"
		*/
		else if(part_of_name.substr(0,9) == "[brighten")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generateImage(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			brighten(baseimg);
		}
		/*
			"[noalpha"
			Make image completely opaque.
			Used for the leaves texture when in old leaves mode, so
			that the transparent parts don't look completely black
			when simple alpha channel is used for rendering.
		*/
		else if(part_of_name.substr(0,8) == "[noalpha")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generateImage(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			core::dimension2d<u32> dim = baseimg->getDimension();

			// Set alpha to full
			for(u32 y=0; y<dim.Height; y++)
			for(u32 x=0; x<dim.Width; x++)
			{
				video::SColor c = baseimg->getPixel(x,y);
				c.setAlpha(255);
				baseimg->setPixel(x,y,c);
			}
		}
		/*
			"[makealpha:R,G,B"
			Convert one color to transparent.
		*/
		else if(part_of_name.substr(0,11) == "[makealpha:")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generateImage(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			Strfnd sf(part_of_name.substr(11));
			u32 r1 = stoi(sf.next(","));
			u32 g1 = stoi(sf.next(","));
			u32 b1 = stoi(sf.next(""));
			std::string filename = sf.next("");

			core::dimension2d<u32> dim = baseimg->getDimension();

			/*video::IImage *oldbaseimg = baseimg;
			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
			oldbaseimg->copyTo(baseimg);
			oldbaseimg->drop();*/

			// Set alpha to full
			for(u32 y=0; y<dim.Height; y++)
			for(u32 x=0; x<dim.Width; x++)
			{
				video::SColor c = baseimg->getPixel(x,y);
				u32 r = c.getRed();
				u32 g = c.getGreen();
				u32 b = c.getBlue();
				if(!(r == r1 && g == g1 && b == b1))
					continue;
				c.setAlpha(0);
				baseimg->setPixel(x,y,c);
			}
		}
		/*
			"[transformN"
			Rotates and/or flips the image.

			N can be a number (between 0 and 7) or a transform name.
			Rotations are counter-clockwise.
			0  I      identity
			1  R90    rotate by 90 degrees
			2  R180   rotate by 180 degrees
			3  R270   rotate by 270 degrees
			4  FX     flip X
			5  FXR90  flip X then rotate by 90 degrees
			6  FY     flip Y
			7  FYR90  flip Y then rotate by 90 degrees

			Note: Transform names can be concatenated to produce
			their product (applies the first then the second).
			The resulting transform will be equivalent to one of the
			eight existing ones, though (see: dihedral group).
		*/
		else if(part_of_name.substr(0,10) == "[transform")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generateImage(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			u32 transform = parseImageTransform(part_of_name.substr(10));
			core::dimension2d<u32> dim = imageTransformDimension(
					transform, baseimg->getDimension());
			video::IImage *image = driver->createImage(
					baseimg->getColorFormat(), dim);
			assert(image);
			imageTransform(transform, baseimg, image);
			baseimg->drop();
			baseimg = image;
		}
		/*
			[inventorycube{topimage{leftimage{rightimage
			In every subimage, replace ^ with &.
			Create an "inventory cube".
			NOTE: This should be used only on its own.
			Example (a grass block (not actually used in game):
			"[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png"
		*/
		else if(part_of_name.substr(0,14) == "[inventorycube")
		{
			if(baseimg != NULL)
			{
				errorstream<<"generateImage(): baseimg!=NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			str_replace_char(part_of_name, '&', '^');
			Strfnd sf(part_of_name);
			sf.next("{");
			std::string imagename_top = sf.next("{");
			std::string imagename_left = sf.next("{");
			std::string imagename_right = sf.next("{");

			// Generate images for the faces of the cube
			video::IImage *img_top =
				generateImageFromScratch(imagename_top);
			video::IImage *img_left =
				generateImageFromScratch(imagename_left);
			video::IImage *img_right =
				generateImageFromScratch(imagename_right);
			assert(img_top && img_left && img_right);

			// Create textures from images
			video::ITexture *texture_top = driver->addTexture(
					(imagename_top + "__temp__").c_str(), img_top);
			video::ITexture *texture_left = driver->addTexture(
					(imagename_left + "__temp__").c_str(), img_left);
			video::ITexture *texture_right = driver->addTexture(
					(imagename_right + "__temp__").c_str(), img_right);
			assert(texture_top && texture_left && texture_right);

			// Drop images
			img_top->drop();
			img_left->drop();
			img_right->drop();

			/*
				Draw a cube mesh into a render target texture
			*/
			scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1));
			setMeshColor(cube, video::SColor(255, 255, 255, 255));
			cube->getMeshBuffer(0)->getMaterial().setTexture(0, texture_top);
			cube->getMeshBuffer(1)->getMaterial().setTexture(0, texture_top);
			cube->getMeshBuffer(2)->getMaterial().setTexture(0, texture_right);
			cube->getMeshBuffer(3)->getMaterial().setTexture(0, texture_right);
			cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left);
			cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left);

			TextureFromMeshParams params;
			params.mesh = cube;
			params.dim.set(64, 64);
			params.rtt_texture_name = part_of_name + "_RTT";
			// We will delete the rtt texture ourselves
			params.delete_texture_on_shutdown = false;
			params.camera_position.set(0, 1.0, -1.5);
			params.camera_position.rotateXZBy(45);
			params.camera_lookat.set(0, 0, 0);
			// Set orthogonal projection
			params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
					1.65, 1.65, 0, 100);

			params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
			params.light_position.set(10, 100, -50);
			params.light_color.set(1.0, 0.5, 0.5, 0.5);
			params.light_radius = 1000;

			video::ITexture *rtt = generateTextureFromMesh(params);

			// Drop mesh
			cube->drop();

			// Free textures of images
			driver->removeTexture(texture_top);
			driver->removeTexture(texture_left);
			driver->removeTexture(texture_right);

			if(rtt == NULL)
			{
				baseimg = generateImageFromScratch(imagename_top);
				return true;
			}

			// Create image of render target
			video::IImage *image = driver->createImage(rtt, v2s32(0,0), params.dim);
			assert(image);

			// Cleanup texture
			driver->removeTexture(rtt);

			baseimg = driver->createImage(video::ECF_A8R8G8B8, params.dim);

			if(image)
			{
				image->copyTo(baseimg);
				image->drop();
			}
		}
		/*
			[lowpart:percent:filename
			Adds the lower part of a texture
		*/
		else if(part_of_name.substr(0,9) == "[lowpart:")
		{
			Strfnd sf(part_of_name);
			sf.next(":");
			u32 percent = stoi(sf.next(":"));
			std::string filename = sf.next(":");
			//infostream<<"power part "<<percent<<"%% of "<<filename<<std::endl;

			if(baseimg == NULL)
				baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16));
			video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
			if(img)
			{
				core::dimension2d<u32> dim = img->getDimension();
				core::position2d<s32> pos_base(0, 0);
				video::IImage *img2 =
						driver->createImage(video::ECF_A8R8G8B8, dim);
				img->copyTo(img2);
				img->drop();
				core::position2d<s32> clippos(0, 0);
				clippos.Y = dim.Height * (100-percent) / 100;
				core::dimension2d<u32> clipdim = dim;
				clipdim.Height = clipdim.Height * percent / 100 + 1;
				core::rect<s32> cliprect(clippos, clipdim);
				img2->copyToWithAlpha(baseimg, pos_base,
						core::rect<s32>(v2s32(0,0), dim),
						video::SColor(255,255,255,255),
						&cliprect);
				img2->drop();
			}
		}
		/*
			[verticalframe:N:I
			Crops a frame of a vertical animation.
			N = frame count, I = frame index
		*/
		else if(part_of_name.substr(0,15) == "[verticalframe:")
		{
			Strfnd sf(part_of_name);
			sf.next(":");
			u32 frame_count = stoi(sf.next(":"));
			u32 frame_index = stoi(sf.next(":"));

			if(baseimg == NULL){
				errorstream<<"generateImage(): baseimg!=NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			v2u32 frame_size = baseimg->getDimension();
			if (frame_count)
			frame_size.Y /= frame_count;

			video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
					frame_size);
			if(!img){
				errorstream<<"generateImage(): Could not create image "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			// Fill target image with transparency
			img->fill(video::SColor(0,0,0,0));

			core::dimension2d<u32> dim = frame_size;
			core::position2d<s32> pos_dst(0, 0);
			core::position2d<s32> pos_src(0, frame_index * frame_size.Y);
			baseimg->copyToWithAlpha(img, pos_dst,
					core::rect<s32>(pos_src, dim),
					video::SColor(255,255,255,255),
					NULL);
			// Replace baseimg
			baseimg->drop();
			baseimg = img;
		}
		else
		{
			errorstream<<"generateImage(): Invalid "
					" modification: \""<<part_of_name<<"\""<<std::endl;
		}
	}

	return true;
}
Example #7
0
void base_window::draw(const point& offset, const Rect& clip)
{
	if(m_visible)
	{
		if(m_area.getWidth() < 1.f)
			return;

		Rect destrect(m_area);
		destrect.offset(offset);
		Rect cliprect(destrect);
		cliprect = cliprect.getIntersection(clip);

		//if (m_invalidated)
		{
			m_system.getRenderer().startCaptureForCache(this);


			render(destrect, cliprect); // render self first
			m_system.getRenderer().endCaptureForCache(this);		
			m_invalidated = false;
		}
		//else 
		//{
		//	//if (!m_system.getRenderer().isExistInCache(this))
		//	//{
		//	//	m_system.getRenderer().startCaptureForCache(this);			
		//	//	if(m_customDraw && !m_drawhandler.empty())
		//	//	{
		//	//		EventArgs a;
		//	//		a.name = "On_Draw";
		//	//		luabind::globals (m_system.getScriptSystem().LuaState())["eventArgs"] = &a;
		//	//		ExecuteScript(a.name, m_drawhandler);
		//	//		luabind::globals (m_system.getScriptSystem().LuaState())["eventArgs"] = 0;
		//	//	}

		//	//	render(destrect, cliprect); // render self first
		//	//	m_system.getRenderer().endCaptureForCache(this);
		//	//}
		//	//else 
		//		m_system.getRenderer().drawFromCache(this);
		//}

		child_iter i = m_children.begin();
		child_iter end = m_children.end();
		while(i != end)
		{
			(*i)->draw(destrect.getPosition(), cliprect);
			++i;
		}

		if (m_customDraw && !m_drawhandler.empty())
		{
			EventArgs a;
			a.name = "On_Draw";

			luabind::object globals = luabind::globals(m_system.getScriptSystem().getLuaState());

			globals["eventArgs"] = &a;
			ExecuteScript(a.name, m_drawhandler);
			globals["eventArgs"] = 0;
		}

		// теперь скажем, что тут коллбак при отрисовке нужно сделать
		CallAfterRenderCallback(destrect,cliprect);
	}	
}
Example #8
0
void
ContainerLayerD3D9::RenderLayer()
{
  nsRefPtr<IDirect3DSurface9> previousRenderTarget;
  nsRefPtr<IDirect3DTexture9> renderTexture;
  float previousRenderTargetOffset[4];
  RECT containerClipRect;
  float renderTargetOffset[] = { 0, 0, 0, 0 };
  float oldViewMatrix[4][4];

  device()->GetScissorRect(&containerClipRect);

  ReadbackProcessor readback;
  readback.BuildUpdates(this);

  nsIntRect visibleRect = mVisibleRegion.GetBounds();
  PRBool useIntermediate = UseIntermediateSurface();

  mSupportsComponentAlphaChildren = PR_FALSE;
  gfxMatrix contTransform;
  if (useIntermediate) {
    device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
    device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
                            D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
                            D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
                            NULL);
    nsRefPtr<IDirect3DSurface9> renderSurface;
    renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
    device()->SetRenderTarget(0, renderSurface);

    if (mVisibleRegion.GetNumRects() == 1 && (GetContentFlags() & CONTENT_OPAQUE)) {
      // don't need a background, we're going to paint all opaque stuff
      mSupportsComponentAlphaChildren = PR_TRUE;
    } else {
      const gfx3DMatrix& transform3D = GetEffectiveTransform();
      gfxMatrix transform;
      // If we have an opaque ancestor layer, then we can be sure that
      // all the pixels we draw into are either opaque already or will be
      // covered by something opaque. Otherwise copying up the background is
      // not safe.
      HRESULT hr = E_FAIL;
      if (HasOpaqueAncestorLayer(this) &&
          transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) {
        // Copy background up from below
        RECT dest = { 0, 0, visibleRect.width, visibleRect.height };
        RECT src = dest;
        ::OffsetRect(&src,
                     visibleRect.x + PRInt32(transform.x0),
                     visibleRect.y + PRInt32(transform.y0));
        hr = device()->
          StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE);
      }
      if (hr == S_OK) {
        mSupportsComponentAlphaChildren = PR_TRUE;
      } else {
        device()->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
      }
    }

    device()->GetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
    renderTargetOffset[0] = (float)visibleRect.x;
    renderTargetOffset[1] = (float)visibleRect.y;
    device()->SetVertexShaderConstantF(CBvRenderTargetOffset, renderTargetOffset, 1);

    gfx3DMatrix viewMatrix;
    /*
     * Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
     * <1.0, -1.0> bottomright)
     */
    viewMatrix._11 = 2.0f / visibleRect.width;
    viewMatrix._22 = -2.0f / visibleRect.height;
    viewMatrix._41 = -1.0f;
    viewMatrix._42 = 1.0f;

    device()->GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);
    device()->SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4);
  } else {
#ifdef DEBUG
    PRBool is2d =
#endif
    GetEffectiveTransform().Is2D(&contTransform);
    NS_ASSERTION(is2d, "Transform must be 2D");
    mSupportsComponentAlphaChildren = (GetContentFlags() & CONTENT_OPAQUE) ||
        (mParent && mParent->SupportsComponentAlphaChildren());
  }

  /*
   * Render this container's contents.
   */
  for (LayerD3D9* layerToRender = GetFirstChildD3D9();
       layerToRender != nsnull;
       layerToRender = GetNextSiblingD3D9(layerToRender)) {

    const nsIntRect* clipRect = layerToRender->GetLayer()->GetClipRect();
    if ((clipRect && clipRect->IsEmpty()) ||
        layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
      continue;
    }

    if (clipRect || useIntermediate) {
      RECT r;
      if (clipRect) {
        r.left = (LONG)(clipRect->x - renderTargetOffset[0]);
        r.top = (LONG)(clipRect->y - renderTargetOffset[1]);
        r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width);
        r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height);
      } else {
        r.left = 0;
        r.top = 0;
        r.right = visibleRect.width;
        r.bottom = visibleRect.height;
      }

      nsRefPtr<IDirect3DSurface9> renderSurface;
      device()->GetRenderTarget(0, getter_AddRefs(renderSurface));

      D3DSURFACE_DESC desc;
      renderSurface->GetDesc(&desc);

      if (!useIntermediate) {
        // Transform clip rect
        if (clipRect) {
          gfxRect cliprect(r.left, r.top, r.right - r.left, r.bottom - r.top);
          gfxRect trScissor = contTransform.TransformBounds(cliprect);
          trScissor.Round();
          nsIntRect trIntScissor;
          if (gfxUtils::GfxRectToIntRect(trScissor, &trIntScissor)) {
            r.left = trIntScissor.x;
            r.top = trIntScissor.y;
            r.right = trIntScissor.XMost();
            r.bottom = trIntScissor.YMost();
          } else {
            r.left = 0;
            r.top = 0;
            r.right = visibleRect.width;
            r.bottom = visibleRect.height;
            clipRect = nsnull;
          }
        }
        // Intersect with current clip rect.
        r.left = NS_MAX<PRInt32>(containerClipRect.left, r.left);
        r.right = NS_MIN<PRInt32>(containerClipRect.right, r.right);
        r.top = NS_MAX<PRInt32>(containerClipRect.top, r.top);
        r.bottom = NS_MIN<PRInt32>(containerClipRect.bottom, r.bottom);
      } else {
        // > 0 is implied during the intersection when useIntermediate == true;
        r.left = NS_MAX<LONG>(0, r.left);
        r.top = NS_MAX<LONG>(0, r.top);
      }
      r.bottom = NS_MIN<LONG>(r.bottom, desc.Height);
      r.right = NS_MIN<LONG>(r.right, desc.Width);

      device()->SetScissorRect(&r);
    }

    if (layerToRender->GetLayer()->GetType() == TYPE_THEBES) {
      static_cast<ThebesLayerD3D9*>(layerToRender)->RenderThebesLayer(&readback);
    } else {
      layerToRender->RenderLayer();
    }

    if (clipRect && !useIntermediate) {
      // In this situation we've set a new scissor rect and we will continue
      // to render directly to our container. We need to restore its scissor.
      // Not setting this when useIntermediate is true is an optimization since
      // we'll get a new one set anyway.
      device()->SetScissorRect(&containerClipRect);
    }
  }

  if (useIntermediate) {
    device()->SetRenderTarget(0, previousRenderTarget);
    device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
    device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);

    device()->SetVertexShaderConstantF(CBvLayerQuad,
                                       ShaderConstantRect(visibleRect.x,
                                                          visibleRect.y,
                                                          visibleRect.width,
                                                          visibleRect.height),
                                       1);

    SetShaderTransformAndOpacity();

    mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER);

    device()->SetScissorRect(&containerClipRect);
    device()->SetTexture(0, renderTexture);
    device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
  }
}