Color of texture skybox unity - colors

I'm working with google cardboard in unity.
In my main scene I have a skybox with an image as texture.
How can I get the color of the pixel I'm looking?
The skybox is an element of mainCamera, that is child of "Head".
I put also GvrReticle as child of head; is it useful for my purpose?
Thanks

Basically you wait for the end of the frame so that the camera has rendered. Then you read the rendered data into a texture and get the center pixel.
edit Be aware that if you have a UI element rendered in the center it will show the UI element color not the color behind.
private Texture2D tex;
public Color center;
void Awake()
{
StartCoroutine(GetCenterPixel());
}
private void CreateTexture()
{
tex = new Texture2D(1, 1, TextureFormat.RGB24, false);
}
private IEnumerator GetCenterPixel()
{
CreateTexture();
while (true)
{
yield return new WaitForEndOfFrame();
tex.ReadPixels(new Rect(Screen.width / 2f, Screen.height / 2f, 1, 1), 0, 0);
tex.Apply();
center = tex.GetPixel(0,0);
}
}

Related

How do I change the background color of a tabbed page in Xamarin iOS?

I need to change the background color of the currently tabbed page in my UITabBarController. I've searched through every stackoverflow post I could find but nothing worked for me. I thought there would be something like UITabBar.Appearance.SelectedImageTintColor, just for the background color but it doesn't seem so.
For example, I want to change the color of that part when I am on the right tab:
Does someone know how to do that?
You could invoked the following code in your UITabBarController
public xxxTabBarController()
{
//...set ViewControllers
this.TabBar.BarTintColor = UIColor.Red;
}
Update
//3.0 here is if you have three child page in tab , set it as the current value in your project
//
var size = new CGSize(TabBar.Frame.Width / 3.0, IsFullScreen());
this.TabBar.SelectionIndicatorImage = ImageWithColor(size,UIColor.Green);
double IsFullScreen()
{
double height = 64;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 84;
}
}
return height;
}
UIImage ImageWithColor(CGSize size, UIColor color)
{
var rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContextWithOptions(size, false, 0);
CGContext context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
The trick is to use the SelectionIndicatorImage Property of the UITabBar and generate a completely filled image with your desired color using the following method:
private UIImage ImageWithColor(CGSize size)
{
CGRect rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContext(size);
using (CGContext context = UIGraphics.GetCurrentContext())
{
context.SetFillColor(UIColor.Green); //change color if necessary
context.FillRect(rect);
}
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
To initialize everything we override ViewWillLayoutSubviews() like this:
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
// The tabbar height will always be 49 unless we force it to reevaluate it's size on runtime ...
myTabBar.InvalidateIntrinsicContentSize();
double height = myTabBar.Frame.Height;
CGSize size = new CGSize(new nfloat(myTabBar.Frame.Width / myTabBar.Items.Length, height));
// Now get our all-green image...
UIImage image = ImageWithColor(size);
// And set it as the selection indicator
myTabBar.SelectionIndicatorImage = image;
}
As mentioned in this article (google translating it step by step when necessary lol) calling InvalidateIntrinsicContentSize() will force the UITabBar to reevaluate it's size and will get you the actual runtime height of the tab bar (instead of the constant 49 height value from XCode).

Qt3d svg or png Texture with opacity=0 QTextureMaterial on QPlaneMesh

I tried to add the svg image which contains opacity=0 area into QTextureMaterial on QPlaneMesh, but it shows that the Plane's background is always in gray.
I want that the plane can cantain my image and penetrate to other object in opacity=0 area.
The svg file like https://image.flaticon.com/icons/svg/3154/3154348.svg .
code:
// Background
Qt3DCore::QEntity *planeEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh(planeEntity);
planeMesh->setHeight(2);
planeMesh->setWidth(2);
Qt3DExtras::QTextureMaterial *planeMaterial = new Qt3DExtras::QTextureMaterial(planeEntity);
Qt3DRender::QTexture2D *planeTexture = new Qt3DRender::QTexture2D(planeMaterial);
FlippedTextureImage *planeTextureImage = new FlippedTextureImage(planeTexture);
planeTextureImage->setSize(QSize(3507, 3000));
planeTexture->addTextureImage(planeTextureImage);
planeMaterial->setTexture(planeTexture);
Qt3DCore::QTransform *planeTransform = new Qt3DCore::QTransform(planeEntity);
planeTransform->setRotationX(90);
planeTransform->setTranslation(QVector3D(0, 0, 0));
Qt3DExtras::QPhongAlphaMaterial *pam2 = new Qt3DExtras::QPhongAlphaMaterial(planeEntity);
pam2->setAlpha(0);
planeEntity->addComponent(planeMesh);
planeEntity->addComponent(pam2);
planeEntity->addComponent(planeMaterial);
planeEntity->addComponent(planeTransform);
class FlippedTextureImage : public Qt3DRender::QPaintedTextureImage
{
public:
FlippedTextureImage(Qt3DCore::QNode *parent = Q_NULLPTR):Qt3DRender::QPaintedTextureImage(parent) {}
void paint(QPainter *painter) override {
QSvgRenderer renderer(QString(qApp->applicationDirPath() + "/gift.svg"));
QImage image(3000, 3000, QImage::Format_RGBA64); // 512x512 RGBA
image.fill(0x00ffffff); // white background
QPainter painter2(&image);
renderer.render(&painter2);
painter->drawImage(0, 0, image);
}
};
and run code like this
QTextureMaterial doesn't support transparency in the textures.
Check out my answer to this question to see how to implement transparency in textures yourself. There is not out-of-the-box solution in Qt3D.

C#/XNA/HLSL - Applying a pixel shader on 2D sprites affects the other sprites on the same render target

Background information
I have just started learning HLSL and decided to test what I have learned from the Internet by writing a simple 2D XNA 4.0 bullet-hell game.
I have written a pixel shader in order to change the color of bullets.
Here is the idea: the original texture of the bullet is mainly black, white and red. With the help of my pixel shader, bullets can be much more colorful.
But, I'm not sure how and when the shader is applied on spriteBatch in XNA 4.0, and when it ends. This may be the cause of problem.
There were pass.begin() and pass.end() in XNA 3.x, but pass.apply() in XNA 4.0 confuses me.
In addition, it is the first time for me to use renderTarget. It may cause problems.
Symptom
It works, but only if there are bullets of the same color in the bullet list.
If bullets of different colors are rendered, it produces wrong colors.
It seems that the pixel shader is not applied on the bullet texture, but applied on the renderTarget, which contains all the rendered bullets.
For an example:
Here I have some red bullets and blue bullets. The last created bullet is a blue one. It seems that the pixel shader have added blue color on the red ones, making them to be blue-violet.
If I continuously create bullets, the red bullets will appear to be switching between red and blue-violet. (I believe that the blue ones are also switching, but not obvious.)
Code
Since I am new to HLSL, I don't really know what I have to provide.
Here are all the things that I believe or don't know if they are related to the problem.
C# - Enemy bullet (or just Bullet):
protected SpriteBatch spriteBatch;
protected Texture2D texture;
protected Effect colorEffect;
protected Color bulletColor;
... // And some unrelated variables
public EnemyBullet(SpriteBatch spriteBatch, Texture2D texture, Effect colorEffect, BulletType bulletType, (and other data, like velocity)
{
this.spriteBatch = spriteBatch;
this.texture = texture;
this.colorEffect = colorEffect;
if(bulletType == BulletType.ARROW_S)
{
bulletColor = Color.Red; // The bullet will be either red
}
else
{
bulletColor = Color.Blue; // or blue.
}
}
public void Update()
{
... // Update positions and other properties, but not the color.
}
public void Draw()
{
colorEffect.Parameters["DestColor"].SetValue(bulletColor.ToVector4());
int l = colorEffect.CurrentTechnique.Passes.Count();
for (int i = 0; i < l; i++)
{
colorEffect.CurrentTechnique.Passes[i].Apply();
spriteBatch.Draw(texture, Position, sourceRectangle, Color.White, (float)Math.PI - rotation_randian, origin, Scale, SpriteEffects.None, 0.0f);
}
}
C# - Bullet manager:
private Texture2D bulletTexture;
private List<EnemyBullet> enemyBullets;
private const int ENEMY_BULLET_CAPACITY = 10000;
private RenderTarget2D bulletsRenderTarget;
private Effect colorEffect;
...
public EnemyBulletManager()
{
enemyBullets = new List<EnemyBullet>(ENEMY_BULLET_CAPACITY);
}
public void LoadContent(ContentManager content, SpriteBatch spriteBatch)
{
bulletTexture = content.Load<Texture2D>(#"Textures\arrow_red2");
bulletsRenderTarget = new RenderTarget2D(spriteBatch.GraphicsDevice, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
colorEffect = content.Load<Effect>(#"Effects\ColorTransform");
colorEffect.Parameters["ColorMap"].SetValue(bulletTexture);
}
public void Update()
{
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Update();
}
else
{
enemyBullets.RemoveAt(i);
i--;
l--;
}
}
}
// This function is called before Draw()
public void PreDraw()
{
// spriteBatch.Begin() is called outside this class, for reference:
// spriteBatch.Begin(SpriteSortMode.Immediate, null);
spriteBatch.GraphicsDevice.SetRenderTarget(bulletsRenderTarget);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Draw();
}
}
spriteBatch.GraphicsDevice.SetRenderTarget(null);
}
public void Draw()
{
// Before this function is called,
// GraphicsDevice.Clear(Color.Black);
// is called outside.
spriteBatch.Draw(bulletsRenderTarget, Vector2.Zero, Color.White);
// spriteBatch.End();
}
// This function will be responsible for creating new bullets.
public EnemyBullet CreateBullet(EnemyBullet.BulletType bulletType, ...)
{
EnemyBullet eb = new EnemyBullet(spriteBatch, bulletTexture, colorEffect, bulletType, ...);
enemyBullets.Add(eb);
return eb;
}
HLSL - Effects\ColorTransform.fx
float4 DestColor;
texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
};
struct PixelShaderInput
{
float2 TexCoord : TEXCOORD0;
};
float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
float4 srcRGBA = tex2D(ColorMapSampler, input.TexCoord);
float fmax = max(srcRGBA.r, max(srcRGBA.g, srcRGBA.b));
float fmin = min(srcRGBA.r, min(srcRGBA.g, srcRGBA.b));
float delta = fmax - fmin;
float4 originalDestColor = float4(1, 0, 0, 1);
float4 deltaDestColor = originalDestColor - DestColor;
float4 finalRGBA = srcRGBA - (deltaDestColor * delta);
return finalRGBA;
}
technique Technique1
{
pass ColorTransform
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
I would be appreciate if anyone can help solving the problem. (Or optimizing my shader. I really know very little about HLSL.)
In XNA 4 you should pass the effect directly to the SpriteBatch, as explained on Shawn Hargreaves' Blog.
That said, it seems to me like the problem is, that after rendering your bullets to bulletsRenderTarget, you then draw that RenderTarget using the same spriteBatch with the last effect still in action. That would explain why the entire image is painted blue.
A solution would be to use two Begin()/End() passes of SpriteBatch, one with the effect and the other without. Or just don't use a separate RenderTarget to begin with, which seems pointless in this case.
I'm also very much a beginner with pixel shaders so, just my 2c.

How to use lwuit Painter

I want create a set of buttons with Painter. I wrote next code
class ListButton extends Button{
int id;
ListButton(int id, final Image unsel, final Image sel, final Image pres) {
this.id = id;
getUnselectedStyle().setBgTransparency(255);
getSelectedStyle().setBgTransparency(255);
getPressedStyle().setBgTransparency(255);
getUnselectedStyle().setAlignment(Component.LEFT);
getSelectedStyle().setAlignment(Component.LEFT);
getPressedStyle().setAlignment(Component.LEFT);
getUnselectedStyle().setBgPainter(new Painter(){
public void paint(Graphics graphics, Rectangle rectangle) {
graphics.drawImage(buttonBgImage, 0, 0);
int w= rectangle.getSize().getWidth();
int h= rectangle.getSize().getHeight();
graphics.drawImage(unsel, w- unsel.getWidth()-10, (h- unsel.getHeight())/2+ 3);
}
});
getSelectedStyle().setBgPainter(new Painter(){
public void paint(Graphics graphics, Rectangle rectangle) {
graphics.drawImage(buttonBgImage, 0, 0);
int w= rectangle.getSize().getWidth();
int h= rectangle.getSize().getHeight();
graphics.drawImage(sel, w- sel.getWidth()-10, (h- sel.getHeight())/2+ 3);
}
});
getPressedStyle().setBgPainter(new Painter(){
public void paint(Graphics graphics, Rectangle rectangle) {
graphics.drawImage(buttonBgImage, 0, 0);
int w= rectangle.getSize().getWidth();
int h= rectangle.getSize().getHeight();
graphics.drawImage(pres, w- pres.getWidth()-10, (h- pres.getHeight())/2+ 3);
}
});
}
}
If I insert 2 buttons into the Form only first button is showed well. Second button is without background image (buttonBgImage) and without icon (sel, unsel or pres). I found randomly that second button will be painted if it will be inserted in some Container. What the strange behavior? Sorry for my English.
List has a specific optimization for Renderers/Painters in place that breaks this. We generally recommend people stick with Styles and UIID manipulation and avoid using painters for tasks like these.
E.g. in Codename One/LWUIT we even have specific support in the GUI builder for pinstripe UI in the list renderer.
If you insist on this approach try using list.setMutableRendererBackgrounds(true); to disable this optimization.

Draw string vertically with transparent background

I would like to draw a string on the screen, rotated by 90 degrees, on a transparent background:
public static void drawStringWithTransformROT90(String text, int x, int y, int color, Graphics g) {
// create a mutable image with white background color
Image im = Image.createImage(g.getFont().stringWidth(text), g.getFont().getHeight());
Graphics imGraphics = im.getGraphics();
// set text color to black
imGraphics.setColor(0x00000000);
imGraphics.drawString(text, 0, 0, Graphics.TOP|Graphics.LEFT);
int[] rgbData = new int[im.getWidth() * im.getHeight()];
im.getRGB(rgbData, 0, im.getWidth(), 0, 0, im.getWidth(), im.getHeight());
for (int i = 0; i < rgbData.length; i++) {
// if it is the background color (white), set it to transparent
if (rgbData[i] == 0xffffffff) {
rgbData[i] = 0x00000000;
} else {
// otherwise (black), change the text color
rgbData[i] = color;
}
}
Image imageWithAlpha = Image.createRGBImage(rgbData, im.getWidth(), im.getHeight(), true);
Sprite s = new Sprite(imageWithAlpha);
// rotate the text
s.setTransform(Sprite.TRANS_ROT90);
s.setPosition(x, y);
s.paint(g);
}
Is there any better way to do this? Should I create a transparent image with the alphabet rotated, and draw it using a Sprite object?
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.Sprite;
public class MyCanvas extends Canvas {
public void paint(Graphics g) {
//The text that will be displayed
String s="java";
//Create the blank image, specifying its size
Image img=Image.createImage(50,50);
//Create an instance of the image's Graphics class and draw the string to it
Graphics gr=img.getGraphics();
gr.drawString(s, 0, 0, Graphics.TOP|Graphics.LEFT);
//Display the image, specifying the rotation value. For example, 90 degrees
g.drawRegion(img, 0, 0, 50, 50, Sprite.TRANS_ROT90, 0, 0, Graphics.TOP|Graphics.LEFT);
}
}
As found at http://wiki.forum.nokia.com/index.php/How_to_display_rotated_text_in_Java_ME
If you use Java2D for drawing you can specify java.awt.Graphics2D#setTransform.

Resources