First off is just the prefix, Loading a texture in its simplest form.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | private Bitmap texture_source; private int texture; protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Load texture from file texture_source = new Bitmap("texture.png"); //Generate empty texture texture = GL.GenTexture(); //Link empty texture to texture2d GL.BindTexture(TextureTarget.Texture2D, texture); //Must be set else the texture will show glColor GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); //Describe to gl what we want the bound texture to look like GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texture_source.Width, texture_source.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); //Lock pixel data to memory and prepare for pass through System.Drawing.Imaging.BitmapData bitmap_data = texture_source.LockBits(new Rectangle(0, 0, texture_source.Width, texture_source.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //Tell gl to write the data from are bitmap image/data to the bound texture GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, texture_source.Width, texture_source.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bitmap_data.Scan0); //Release from memory texture_source.UnlockBits(bitmap_data); //Release texture GL.BindTexture(TextureTarget.Texture2D, 0); //Enable textures from texture2d target GL.Enable(EnableCap.Texture2D); } |
Method
For convenience
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | private int LoadTexture(string path, int quality = 0, bool repeat = true, bool flip_y = false) { Bitmap bitmap = new Bitmap(path); //Flip the image if (flip_y) bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); //Generate a new texture target in gl int texture = GL.GenTexture(); //Will bind the texture newly/empty created with GL.GenTexture //All gl texture methods targeting Texture2D will relate to this texture GL.BindTexture(TextureTarget.Texture2D, texture); //The reason why your texture will show up glColor without setting these parameters is actually //TextureMinFilters fault as its default is NearestMipmapLinear but we have not established mipmapping //We are only using one texture at the moment since mipmapping is a collection of textures pre filtered //I'm assuming it stops after not having a collection to check. switch (quality) { case 0: default://Low quality GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); break; case 1://High quality //This is in my opinion the best since it doesnt average the result and not blurred to shit //but most consider this low quality... GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest); break; } if (repeat) { //This will repeat the texture past its bounds set by TexImage2D GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Repeat); } else { //This will clamp the texture to the edge, so manipulation will result in skewing //It can also be useful for getting rid of repeating texture bits at the borders GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); } //Creates a definition of a texture object in opengl /* Parameters * Target - Since we are using a 2D image we specify the target Texture2D * MipMap Count / LOD - 0 as we are not using mipmapping at the moment * InternalFormat - The format of the gl texture, Rgba is a base format it works all around * Width; * Height; * Border - must be 0; * * Format - this is the images format not gl's the format Bgra i believe is only language specific * C# uses little-endian so you have ARGB on the image A 24 R 16 G 8 B, B is the lowest * So it gets counted first, as with a language like Java it would be PixelFormat.Rgba * since Java is big-endian default meaning A is counted first. * but i could be wrong here it could be cpu specific :P * * PixelType - The type we are using, eh in short UnsignedByte will just fill each 8 bit till the pixelformat is full * (don't quote me on that...) * you can be more specific and say for are RGBA to little-endian BGRA -> PixelType.UnsignedInt8888Reversed * this will mimic are 32bit uint in little-endian. * * Data - No data at the moment it will be written with TexSubImage2D */ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bitmap.Width, bitmap.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); //Load the data from are loaded image into virtual memory so it can be read at runtime System.Drawing.Imaging.BitmapData bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //Writes data to are texture target /* Target; * MipMap; * X Offset - Offset of the data on the x axis * Y Offset - Offset of the data on the y axis * Width; * Height; * Format; * Type; * Data - Now we have data from the loaded bitmap image we can load it into are texture data */ GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bitmap.Width, bitmap.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bitmap_data.Scan0); //Release from memory bitmap.UnlockBits(bitmap_data); //get rid of bitmap object its no longer needed in this method bitmap.Dispose(); /*Binding to 0 is telling gl to use the default or null texture target *This is useful to remember as you may forget that a texture is targeted *And may overflow to functions that you dont necessarily want to *Say you bind a texture * * Bind(Texture); * DrawObject1(); * <-- Insert Bind(NewTexture) or Bind(0) * DrawObject2(); * * Object2 will use Texture if not set to 0 or another. */ GL.BindTexture(TextureTarget.Texture2D, 0); return texture; } |
Usage Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | private int current_texture; protected override void OnLoad(EventArgs e) { base.OnLoad(e); GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); current_texture = LoadTexture("texture.png", 1); GL.Enable(EnableCap.Texture2D); //Basically enables the alpha channel to be used in the color buffer GL.Enable(EnableCap.Blend); //The operation/order to blend GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); //Use for pixel depth comparing before storing in the depth buffer GL.Enable(EnableCap.DepthTest); } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.PushMatrix(); GL.Translate(0, 0, -5); GL.Color4(Color.White); GL.BindTexture(TextureTarget.Texture2D, current_texture); GL.Begin(BeginMode.Quads); //Bind texture coordinates to vertices in ccw order //Top-Right GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(1.0f, 1.0f); //Top-Left GL.TexCoord2(0f, 0f); GL.Vertex2(-1.0f, 1.0f); //Bottom-Left GL.TexCoord2(0f, 1f); GL.Vertex2(-1.0f, -1.0f); //Bottom-Right GL.TexCoord2(1f, 1f); GL.Vertex2(1.0f, -1.0f); GL.End(); GL.BindTexture(TextureTarget.Texture2D, 0); GL.PopMatrix(); SwapBuffers(); } |
Your LoadTexture method has memory leaks, checkout Memory profiling in MS Studio.
ReplyDeletePlease please use Shader and Program! Do not use Begin and End! Because my display card is supports only Shader and Program - Thanks!
ReplyDeletei tried this, and it didn't work all i got was white boxes or "Parameter is not valid" errors. I thought this was because i tweaked a bit to fit a simple opentk wrapper i'm making, but even when i copied the code character for character, i still got the same issues. Does anyone have any ideas. To begin im using .jng and they are powers of two
ReplyDeletenvm. forgot to GL.Enable(EnableCap.Texture2D);
ReplyDeleteMango Sauce with the right amount of heat, without the heat
ReplyDeleteThe mango sauce with mango was discontinued. I'm not sure if it's good gold titanium but it's not. It titanium grinder was titanium gr 2 one race tech titanium of the hottest sauce that you can ecm titanium find on the market.