Micah's picture

Texture problems

Hello everyone,

I am having troubles getting my texture to display on my quad. i have look at a bunch of topics in on these forums and also general opengl forums and have not found anything that has helped me fix my problems.

i made a ball class that contains all my object code including loading textures and drawing the object.
am i able to call GL functions in another class? or should i keep all my drawing code inside the main class?

here is my code that im using to load the texture

		public void loadTexture(string File)
		{
			textureId = GL.GenTexture();
			GL.BindTexture(TextureTarget.Texture2D,textureId);
			Bitmap bmp = new Bitmap(File);
			System.Drawing.Imaging.BitmapData bmp_data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
			GL.TexImage2D(TextureTarget.Texture2D,0,PixelInternalFormat.Rgba,bmp.Width,bmp.Height,0,OpenTK.Graphics.OpenGL.PixelFormat.Bgra,PixelType.UnsignedByte,bmp_data.Scan0);
 
			bmp.UnlockBits(bmp_data);
			GL.TexParameter(TextureTarget.Texture2D,TextureParameterName.TextureMinFilter,(int)TextureMinFilter.Linear);
			GL.TexParameter(TextureTarget.Texture2D,TextureParameterName.TextureMagFilter,(int)TextureMagFilter.Linear);
		}

and here is the draw code

public void Draw()
		{
 
			GL.BindTexture(TextureTarget.Texture2D,textureId);
			GL.Enable(EnableCap.Texture2D);
 
			GL.Begin(BeginMode.Quads);
			GL.TexCoord2(0,0); GL.Vertex2(-(radius) + position.X,(radius * 2) + position.Y);
			GL.TexCoord2(0,1f); GL.Vertex2((radius) + position.X,(radius * 2) + position.Y);
			GL.TexCoord2(1f,1f); GL.Vertex2((radius) + position.X,position.Y);
			GL.TexCoord2(1f,0); GL.Vertex2(-(radius) + position.X, position.Y);
                        GL.End();
		}

i can get the square to draw but it just draws solid red...but i never told it to draw red. i changed the ball image to a purple to see if somehow the texture was loading but just not mapping right but the square remained red.

also im using ubuntu linux 9.10 and monodevelop.

any help would be great!

thank you ,

Micah.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

You can call GL commands wherever you want, as long as they are in a thread which contains a "current" GraphicsContext.

Try changing System.Drawing.Imaging.PixelFormat.Format24bppRgb to PixelFormat.Format32bppRgba (in the following line you are calling GL.TexImage2D(..., OpenTK.Graphics.OpenGL.PixelFormat.Bgra, ...), which matches 32bppRgba, rather than 24bppRgb.) I can't see anything else wrong in your code, but you can try the debug version of OpenTK.dll (included in the zip) which will notify you of OpenGL errors immediately. Makes debugging quite a bit easier!

Snorkel's picture
             GL.Color3(Color.White);       //  <------- The lack of this line might be causing it to turn red!
            GL.Begin(BeginMode.Quads);
 
            GL.TexCoord2(new Vector2(0, 0));
            GL.Vertex2(new Vector2(pos.X, pos.Y));
 
            GL.TexCoord2(new Vector2(1, 0));
            GL.Vertex2(new Vector2(pos.X + width, pos.Y));
 
            GL.TexCoord2(new Vector2(1, 1));
            GL.Vertex2(new Vector2(pos.X + width, pos.Y + height));
 
            GL.TexCoord2(new Vector2(0, 1));
            GL.Vertex2(new Vector2(pos.X, pos.Y + height));
 
            GL.End();

And for the texture loading :

                GL.GenTextures(1, out _id); 
                GL.BindTexture(TextureTarget.Texture2D, _id);
 
                // Get image data.
                BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                                  ImageLockMode.ReadOnly,
                                                  System.Drawing.Imaging.PixelFormat.Format32bppArgb);     //  <------------ Like  the Fiddler said
 
                // Copy image data in a OGL texture.
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
                              OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
 
 
                // Texture parameters.
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
 
                // Clean up.
                bitmap.UnlockBits(data);
                bitmap.Dispose();
Micah's picture

Edit... just messed around with stuff and somehow it just started working! i have no idea what made it work but it's working now. that for all the help :)

Thanks for the replys.

now i have a white square :) texture is still not showing.

here is my full code for both the main class and the GameObject... if i really need to i can keep all the drawing code inside the main class but the reason behind this little project is to make some general game objects for a game i am working on. so if i can keep the drawing code for each object seperate from all the rest that would be best. but if thats just not possible does anyone have any ideas on what i could do?

Game.cs..

// Released to the public domain. Use, modify and relicense at will.
 
using System;
using System.Drawing;
 
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using OpenTK.Input;
namespace BouncyBall
{
 
    class Game : GameWindow
    { 
		Vector2 move;
 
 
 
		GameObject2d ball = new GameObject2d(new Vector2(-.5f,0.5f),Color4.Gray,.01f,new Vector2(0.0f,0.0f));
 
        /// <summary>Creates a 800x600 window with the specified title.</summary>
        public Game()
            : base(800, 600, GraphicsMode.Default, "OpenTK Quick Start Sample")
        {
            VSync = VSyncMode.On;
			move = new Vector2(0.0f,0.0f);
       }
 
        /// <summary>Load resources here.</summary>
        /// <param name="e">Not used.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
			GL.Disable(EnableCap.DepthTest);
            ball.loadTexture("Ball.png");
        }
 
        /// <summary>
        /// Called when your window is resized. Set your viewport here. It is also
        /// a good place to set up your projection matrix (which probably changes
        /// along when the aspect ratio of your window).
        /// </summary>
        /// <param name="e">Not used.</param>
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
 
            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
            Matrix4 projection = Matrix4.CreateOrthographicOffCenter(0,1.3333f,0,1,-1,1);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
        }
 
        /// <summary>
        /// Called when it is time to setup the next frame. Add you game logic here.
        /// </summary>
        /// <param name="e">Contains timing information for framerate independent logic.</param>
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
			base.OnUpdateFrame(e);
 
            if (Keyboard[Key.Escape])
                Exit();
 
		    ball.ApplyForce(.016666666);		
 
 
 
        }
 
        /// <summary>
        /// Called when it is time to render the next frame. Add your rendering code here.
        /// </summary>
        /// <param name="e">Contains timing information.</param>
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
			GL.LoadMatrix(ref modelview);
 
			GL.Enable(EnableCap.Texture2D);
			GL.Enable(EnableCap.Blend);
			GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
 
 
			ball.Draw();
 
            SwapBuffers();
        }
 
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // The 'using' idiom guarantees proper resource cleanup.
            // We request 30 UpdateFrame events per second, and unlimited
            // RenderFrame events (as fast as the computer can handle).
            using (Game game = new Game())
            {
                game.Run(60.0);
            }
        }
    }
}

GameObject2d.cs...

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
namespace BouncyBall
{
	public class GameObject2d
	{
		Vector2 position;
		Color4 color;
		float radius;
		Vector2 velocity;
		int textureId;
 
		public GameObject2d()
		{
			position = new Vector2(0.0f,0.0f);
			color = Color4.Green;
			radius = 10;
			velocity = new Vector2(0.0f,0.0f);
			textureId = 0;
		}
		public GameObject2d(Vector2 Position,Color4 Color,float Radius, Vector2 Velocity)
		{
			position = Position;
			color = Color;
			radius = Radius;
			velocity = Velocity;
			textureId = 0;
		}
 
		public void loadTexture(string File)
		{
			textureId = GL.GenTexture();
			GL.BindTexture(TextureTarget.Texture2D,textureId);
			Bitmap bmp = new Bitmap(File);
			System.Drawing.Imaging.BitmapData bmp_data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
			GL.TexImage2D(TextureTarget.Texture2D,0,PixelInternalFormat.Rgba,bmp.Width,bmp.Height,0,OpenTK.Graphics.OpenGL.PixelFormat.Bgra,PixelType.UnsignedByte,bmp_data.Scan0);
 
			bmp.UnlockBits(bmp_data);
			GL.TexParameter(TextureTarget.Texture2D,TextureParameterName.TextureMinFilter,(int)TextureMinFilter.Linear);
			GL.TexParameter(TextureTarget.Texture2D,TextureParameterName.TextureMagFilter,(int)TextureMagFilter.Linear);
		}
 
		public void Draw()
		{
 
			GL.BindTexture(TextureTarget.Texture2D,textureId);
			GL.Color3(Color.White);
			GL.Begin(BeginMode.Quads);
			GL.TexCoord2(0,0); GL.Vertex2(-(radius) + position.X,(radius * 2) + position.Y);
			GL.TexCoord2(0,1f); GL.Vertex2((radius) + position.X,(radius * 2) + position.Y);
			GL.TexCoord2(1f,1f); GL.Vertex2((radius) + position.X,position.Y);
			GL.TexCoord2(1f,0); GL.Vertex2(-(radius) + position.X, position.Y);
            GL.End();
		}
			public void ApplyForce(double timePassed)
		{
			timePassed = timePassed / 2;
			for(int i = 0;i < 2;i++)
			{
			if(position.Y >= 0)
			{
				position.Y = (float)(-4.8*timePassed*timePassed + velocity.Y*timePassed + position.Y);
				velocity.Y = (float)(-9.8*timePassed + velocity.Y);
			}
			else
			{
				position.Y = 0;
				if(velocity.Y > 2)
					velocity.Y = 0;
				else
				velocity.Y = velocity.Y * -0.8f; //simulated elasticity
			}
			}
		}
 
	}
}

note that i have been building my code from modifying the quickstart code.

also i may have some GL calls that may not need to be called... i have been trying to get textures working for a couple days and so have been throwing anything i find into there hoping it will work...

also little side question.

my coord system right looks like this
-----------------------------------
|0,1................ -1.333,1 |
| .................................|
| .................................|
|0,0_________ -1.333,0|

what should i do to make it like this?...
-----------------------------------
|0,1................. 1.333,1 |
|................................. |
|................................. |
|0,0___________1.333,0|

i have been playing around with the orthoprojection but all i have managed to do is flip the coord system on the x axis(in other words my 0,0 is on the right and my -1.333,0 is on the left)

sorry for the noobness i have been programming for years but am new to openGL and am having a hard time finding any documentation that is current or that is relative to opentk.

thanks for the help,

Micah.

Micah's picture

i figured out my coord error. needed to set the right coord to -1.3333 instead of 1.3333.

kinda feel dumb for that one lol :)