I have the following declaration:
ResolveTexture2D rightTex;
And I use it in the Draw method like so:
GraphicsDevice.ResolveBackBuffer(rightTex);
Now, I then draw it out using the SpriteBatch:
spriteBatch.Draw(rightTex, new Rectangle(0, 0, 800, 600), Color.Cyan);
This works fantastic in XNA 3.1. But, now I'm converting to XNA 4, ResolveTexture2D and the ResolveBackBuffer method have been removed. How would I re-code this in order to work in XNA 4.0?
EDIT
So, here is some more code to maybe help. Here I initialise the RenderTargets:
PresentationParameters pp = GraphicsDevice.PresentationParameters;
leftTex = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, pp.BackBufferFormat, pp.DepthStencilFormat);
rightTex = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, true, pp.BackBufferFormat, pp.DepthStencilFormat);
Then, in my Draw method I do:
GraphicsDevice.Clear(Color.Gray);
rightCam.render(model, Matrix.CreateScale(0.1f), modelAbsTrans);
GraphicsDevice.SetRenderTarget(rightTex);
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.Gray);
leftCam.render(model, Matrix.CreateScale(0.1f), modelAbsTrans);
GraphicsDevice.SetRenderTarget(leftTex);
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.Black);
//start the SpriteBatch with Additive Blend Mode
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive);
spriteBatch.Draw(rightTex, new Rectangle(0, 0, 800, 600), Color.Cyan);
spriteBatch.Draw(leftTex, new Rectangle(0, 0, 800, 600), Color.Red);
spriteBatch.End();
The removal of ResolveTexture2D from XNA 4.0 is explained here.
Basically you should use render targets. The gist of the process goes like this:
Create a render target to use.
RenderTarget2D renderTarget = new RenderTarget2D(graphicsDevice, width, height);
Then set it onto the device:
graphicsDevice.SetRenderTarget(renderTarget);
Then render your scene.
Then un-set the render target:
graphicsDevice.SetRenderTarget(null);
Finally, you can use a RenderTarget2D as a Texture2D, like so:
spriteBatch.Draw(renderTarget, new Rectangle(0, 0, 800, 600), Color.Cyan);
You may also find this overview of RenderTarget changes in XNA 4.0 worth reading.
ahhh, here you go:
Move the GraphicsDevice.SetRenderTarget() before the GraphicsDevice.Clear() call
Related
I'm just new to stagexl, I know these are very basic questions, but I couldn't find an answer real quick, so I thought it would be nice to have this answered for anybody in the same position as I am.
How do I create a line from x to y in stagexl ?
And how do I create a circle with center x and radius y ?
You have to use the Shape display object. To draw a circle you just need to write this code:
var shape = new Shape();
shape.graphics.beginPath();
shape.graphics.circle(100, 100, 50);
shape.graphics.closePath();
shape.graphics.fillColor(Color.Red);
stage.addChild(shape);
To draw a line you have to do this:
var shape = new Shape();
shape.graphics.beginPath();
shape.graphics.moveTo(50, 50);
shape.graphics.lineTo(250, 150);
shape.graphics.closePath();
shape.graphics.strokeColor(Color.Red);
stage.addChild(shape);
You can learn more about it here:
http://www.stagexl.org/docs/wiki-articles.html?article=graphics
Please keep in mind that vector shapes are currently only supported with the Canvas2D renderer in StageXL. We are currently working on the WebGL renderer implementation too. You can use Shapes with the WebGL renderer too, if you use the applyCache method on the Shape. This will draw the Shape to a texture which can be used in WebGL too. This is also a much faster way to draw vector graphics.
Here is a full example, that you can also clone from gist if you want to try it out: https://gist.github.com/kasperpeulen/5cd660b5088311c64872
I'm not really sure if I do the WebGL example correct though, it seems like the WebGL graphic is blurry if I do it in this way.
import 'dart:html' as html;
import 'package:stagexl/stagexl.dart';
main() {
initWebGL();
initCanvas2D();
}
initWebGL() {
Stage stage = new Stage(html.querySelector('#WebGL'));
new RenderLoop().addStage(stage);
stage.addChild(circle(new Point(100, 100), 50));
stage.addChild(line(new Point(50, 50), new Point(250, 150)));
stage.applyCache(0,0,stage.sourceWidth,stage.sourceHeight);
}
initCanvas2D() {
Stage stage = new Stage(html.querySelector('#Canvas2D'),
options: new StageOptions()..renderEngine = RenderEngine.Canvas2D);
new RenderLoop().addStage(stage);
stage.addChild(circle(new Point(100, 100), 50));
stage.addChild(line(new Point(50, 50), new Point(250, 150)));
}
Shape line(Point from, Point to, {color: Color.Black}) {
return new Shape()
..graphics.beginPath()
..graphics.moveTo(from.x, from.y)
..graphics.lineTo(to.x, to.y)
..graphics.closePath()
..graphics.strokeColor(color);
}
Shape circle(Point<num> point, num radius, {color: Color.Black}) {
return new Shape()
..graphics.beginPath()
..graphics.circle(point.x, point.y, radius)
..graphics.closePath()
..graphics.fillColor(color);
}
I try to draw an image on the screen with render target.
I used this code:
_renderTarget = new RenderTarget2D(
this._graphicsDevice,
this._graphicsDevice.PresentationParameters.BackBufferWidth,
this._graphicsDevice.PresentationParameters.BackBufferHeight,
false,
this._graphicsDevice.PresentationParameters.BackBufferFormat,
DepthFormat.None, 0, RenderTargetUsage.PreserveContents);
_graphicsDevice.SetRenderTarget(_renderTarget);
_spriteBatch.Begin();
_spriteBatch.Draw(texture, drawPoint, null, Color.Red, 0.0f
, new Vector2(texture.Width / 2, texture.Height / 2), 0.5f, SpriteEffects.None, 0 .0f);
_spriteBatch.End();
_graphicsDevice.SetRenderTarget(null);
But, the result image is always black!
Could you help me to change the color of this image.
Thanks.
From the code shown, _spriteBatch.Draw is only rendering content to _renderTarget.
Next you need to render the resulting RenderTarget2D to your screen so you can see it.
You already have _graphicsDevice.SetRenderTarget(null) in place. You then just need to make a separate SpriteBatch.Draw call passing in your _renderTarget.
You can do this because RenderTarget2D extends Texture2D.
I'm new to Cocos2d and am trying out some of the basic drawing functions. When I draw a straight line with a high width (50 in this case), the ends of the line are not what I'd expect. What I'd like is for the line to be the same as it would be if I were using CoreGraphics, like this:
however what I see in Cocos2d is this:
The code I'm using to draw the line is in the layer's draw method:
-(void)draw
{
glColor4f(1, 0, 0, 1);
glLineWidth(50);
ccDrawLine(ccp(50, 50), ccp(250, 250));
}
Can anyone tell me how I can get cocos2d to draw a line with the same shape as the green image, rather than the red image?
Try drawing it antialiased.
glColor4f(1, 0, 0, 1);
glLineWidth(50);
glEnable(GL_LINE_SMOOTH);
ccDrawLine(ccp(50, 50), ccp(250, 250));
I am facing issue while drawing semitransparent object with RenderToSurface(While it working file when i am drawing object direct on device). Issue is when i m drawing a object with Alpha value 50% on RenderToSurface, and when i am drawing surface to device then transparency of object is not valid. My code is as follow.
[code] RenderingSurface.BeginScene(RenderTexture.GetSurfaceLevel(0), view);
_device.Clear(ClearFlags.Target| ClearFlags.ZBuffer, Color.FromArgb(0, Color.Black), 1.0f, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(ObjecTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
RenderingSurface.EndScene(Filter.None);
RenderSurface have same shape with 50% tranparency.
Code to Draw Surface.
_device.BeginScene();
_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, BackgroundColor, 1, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(RenderTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
Make sure your RenderSurface render target is created with a PixelFormat that has an alpha channel (A8R8G8B8 rather than X8R8G8B8).
Also, when rendering in the render target, make sure the resulting alpha is being written to the surface using the right blend mode render states for the alpha channel. Please note that blend modes for alpha (AlphaDestinationBlend, AlphaSourceBlend, ...) and colors (DestinationBlend, SourceBlend, ...) are different; make sure you set both.
I want to write a very simple Effect for a DirectX program which uses the ID3DXSprite interface to draw a 2D-Hud. In XNA I simply called
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
effect.Begin();
effect.CurrentTechnique.Passes[0].Begin();
spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.White);
effect.CurrentTechnique.Passes[0].End();
effect.End();
spriteBatch.End();
But in C++, nearly the same code doesnt work
pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE | D3DXSPRITE_SORT_TEXTURE);
anEffect->SetTechnique(technique);
anEffect->Begin(&passes, 0);
anEffect->BeginPass(0);
pSprite->Draw(pTexture, NULL, NULL, &position, 0xFFFFFFFF);
anEffect->EndPass();
anEffect->End();
pSprite->End();
NOTE: The effect is loaded correctly!
Well, first of all the XNA code you have is for XNA 3.1, and it's wrong. This blog post explains how to do it for both XNA 3.1 and 4.0 (the API changes in between).
In XNA 3.1, when using SpriteSortMode.Immediate, SpriteBatch will set up its shaders and other device state in the Begin call, instead of in the End call. This gives you the opportunity to replace parts of the device state before drawing actually takes place (in Draw or End, depending on when it flushes). And then you are supposed to End your effect after you End the sprite batch (so everything gets drawn first).
Now, in DirectX, I would suggest that the same incorrect ordering of your End calls is to blame. Specifically refer to this part of the documentation for the second parameter to ID3DXEffect::Begin
determines if state modified by an effect is saved and restored. The default value 0 specifies that ID3DXEffect::Begin and ID3DXEffect::End will save and restore all state modified by the effect
The upshot is that, when you End the effect, it is resetting the device back to normal sprite drawing, before you call End on the ID3DXSprite, which is what is actually sending your sprite batch to be drawn.
I would guess that the reason your incorrectly-ordered code works on XNA is that XNA is probably doing the equivalent of passing D3DXFX_DONOTSAVESTATE, when beginning the effect, under the hood.
Usage of Sprite with HLSL Effect: (for C++ Game Developers)
Below is the sample code which explains how sprite draw can work with HLSL effect files
Pseudo Code:
ID3DXEffect* g_pEffect = NULL; // D3DX effect interface
void loadTextureEffect() {
D3DXCreateTextureFromFile(gD3dDevice,L"image.png",&gTextureBackdrop);
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
D3DXCreateEffectFromFile( gD3dDevice, "shader.fx", NULL, NULL, dwShaderFlags,
NULL, &g_pEffect, NULL );
}
void Render()
{
unsigned int passes;
gD3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
gD3dDevice->BeginScene();
gSprite->Begin(0);
g_pEffect->SetTechnique("PostProcess");
g_pEffect->SetTexture( "Tex0", gTextureBackdrop );
float blurFactor = 25;
g_pEffect->SetValue("TextureBlur",&blurFactor ,sizeof(float));
g_pEffect->Begin(&passes, 0);
for(unsigned int pass = 0; pass < passes; ++pass)
{
g_pEffect->BeginPass(pass);
D3DXVECTOR3 spritePos(0.0f, 0.0f, 0.0f);
gD3dDevice->SetTexture(0,gTextureBackdrop);
gSprite->Draw(gTextureBackdrop, 0, 0, &spritePos, 0xffffffff);
gSprite->End();
g_pEffect->CommitChanges();
g_pEffect->EndPass();
}
g_pEffect->End();
gD3dDevice->EndScene();
gD3dDevice->Present(NULL,NULL,NULL,NULL);
}