locked
Drawing just one pixel RRS feed

  • Question

  • Hello all, I'm just getting into XNA, and all I want to do at this point is create an object that will basically just represent one pixel on the screen, with a variable for RGB color that can be modified easily. Then I can simply draw the pixel to the screen, and change it's color if need be.

    Any help is appreciated.
    Saturday, October 21, 2006 6:51 PM

Answers

  • That's actually not as simple as it seems... You would have to work the shaders.

    I would suggest first trying to render a sprite or a 3D object like a cube... Then maybe have it move around any way you like.


    Saturday, October 21, 2006 7:58 PM
  • XNA is a wrapper for Direct3D, so drawing a single pixel isn't actually the easiest thing in the world. Direct3D (like all hardware accelerated graphics systems) ultimately works in terms of triangles, so eventually, anything you want to draw has to be turned into one or more triangles. To draw a single pixel, you'll have to set up a tiny triangle in just the right place, which is possible but not exactly very fast if you're planning on drawing a lot of pixels! To get good performance, you generally want to be thinking in terms of larger objects like sprites or triangle meshes, rather than just single pixels.

    That said, if you do need to draw just one pixel, probably the easiest way is to create a texture that is solid white, then use SpriteBatch to draw this with the destination rectangle parameter specifying to stretch the texture over just one pixel.
    Saturday, October 21, 2006 7:59 PM
  • Depending on how many you want to draw you can checkout how I did the stars in the spacewar Retro version. Its a vertex buffer that uses Points as primitives.
    Saturday, October 21, 2006 9:24 PM

All replies

  • That's actually not as simple as it seems... You would have to work the shaders.

    I would suggest first trying to render a sprite or a 3D object like a cube... Then maybe have it move around any way you like.


    Saturday, October 21, 2006 7:58 PM
  • XNA is a wrapper for Direct3D, so drawing a single pixel isn't actually the easiest thing in the world. Direct3D (like all hardware accelerated graphics systems) ultimately works in terms of triangles, so eventually, anything you want to draw has to be turned into one or more triangles. To draw a single pixel, you'll have to set up a tiny triangle in just the right place, which is possible but not exactly very fast if you're planning on drawing a lot of pixels! To get good performance, you generally want to be thinking in terms of larger objects like sprites or triangle meshes, rather than just single pixels.

    That said, if you do need to draw just one pixel, probably the easiest way is to create a texture that is solid white, then use SpriteBatch to draw this with the destination rectangle parameter specifying to stretch the texture over just one pixel.
    Saturday, October 21, 2006 7:59 PM
  • Using the sprite batch method, would I be able to change the pixel's colour? Because that's really all I care about.
    Saturday, October 21, 2006 8:18 PM
  • Yes. SpriteBatch.Draw has a color parameter.

    Be warned this is going to be very slow if you are drawing a lot of pixels, though!
    Saturday, October 21, 2006 8:55 PM
  • Hmm, okay, thanks.

    I probably should just use the old 2d Graphics class, since this entire program is about drawing one pixel at a time w/ varying colors.

    Thanks a bunch though.
    Saturday, October 21, 2006 8:57 PM
  • Depending on how many you want to draw you can checkout how I did the stars in the spacewar Retro version. Its a vertex buffer that uses Points as primitives.
    Saturday, October 21, 2006 9:24 PM
  • This is as close as you'll really get. A single point.

     

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Components;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Storage;
    
    namespace PixelTest
    {
        /// 
        /// This is the main type for your game
        /// 
        partial class Game1 : Microsoft.Xna.Framework.Game
        {
    
            public Game1()
            {
                InitializeComponent();
            }
    
            Vector3 pixel = new Vector3(0.0f, 0.0f, 0.0f);
    
            VertexPositionColor[] vpos = new VertexPositionColor[1];
    
    
    
    
            protected override void  OnStarting()
            {
     	        base.OnStarting();
                vpos[0] = new VertexPositionColor(pixel, Color.White);            
            }
            protected override void Update()
            {
                // The time since Update was called last
                float elapsed = (float)ElapsedTime.TotalSeconds;
    
                // TODO: Add your game logic here
    
                // Let the GameComponents update
                UpdateComponents();
            }
    
            protected override void Draw()
            {
                // Make sure we have a valid device
                if (!graphics.EnsureDevice())
                    return;
    
                graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
                graphics.GraphicsDevice.BeginScene();
    
                // TODO: Add your drawing code here
    
    
                using (VertexDeclaration decl = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionColor.VertexElements))
                {
                    graphics.GraphicsDevice.VertexDeclaration = decl;
                    graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
                    graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.PointList, 1, vpos);
                }
    
                // Let the GameComponents draw
                DrawComponents();
    
                graphics.GraphicsDevice.EndScene();
                graphics.GraphicsDevice.Present();
            }
        }
    }
    Saturday, October 21, 2006 11:14 PM
  • There is an example using a spritebatch to draw colored lines and rectangles located in this thread:



    Sunday, October 22, 2006 11:05 AM
  • If you really really must do a single 'pixel' you could do it by having a render target texture the same size as the backbuffer.

    Then you could render this texture on a screen aligned quad (consider pixel:texel mapping), then change your pixel color if it matches the coordinate you specify. A very strange way to use a render pipeline though.

    Sunday, October 22, 2006 6:15 PM
  • I haven't looked into this, but isn't there a way to get the memory of a texture and just treating that as the framebuffer like we did in the old days? Then rendering that to a fullscreen quad?
    Sunday, October 29, 2006 2:47 AM