public Texture2d Get(BitmapBuffer bb) { //get the current entry Texture2d CurrentTexture = CurrentTextures[0]; //TODO - its a bit cruddy here that we dont respect the current texture HasAlpha condition (in fact, theres no such concept) //we might need to deal with that in the future to fix some bugs. //check if its rotten and needs recreating if (CurrentTexture == null || CurrentTexture.IntWidth != bb.Width || CurrentTexture.IntHeight != bb.Height) { //needs recreating. be sure to kill the old one... if (CurrentTexture != null) CurrentTexture.Dispose(); //and make a new one CurrentTexture = GL.LoadTexture(bb); } else { //its good! just load in the data GL.LoadTextureData(CurrentTexture, bb); } //now shuffle the buffers CurrentTextures[0] = CurrentTextures[1]; CurrentTextures[1] = CurrentTexture; //deterministic state, i guess CurrentTexture.SetFilterNearest(); return CurrentTexture; }
public Texture2d Get(DisplaySurface ds) { using (var bb = new BitmapBuffer(ds.PeekBitmap(), new BitmapLoadOptions())) { return Get(bb); } }
public Texture2d Get(BitmapBuffer bb) { //get the current entry Texture2d CurrentTexture = CurrentTextures[0]; //check if its rotten and needs recreating if (CurrentTexture == null || CurrentTexture.IntWidth != bb.Width || CurrentTexture.IntHeight != bb.Height) { //needs recreating. be sure to kill the old one... if (CurrentTexture != null) CurrentTexture.Dispose(); //and make a new one CurrentTexture = GL.LoadTexture(bb); } else { //its good! just load in the data GL.LoadTextureData(CurrentTexture, bb); } //now shuffle the buffers CurrentTextures[0] = CurrentTextures[1]; CurrentTextures[1] = CurrentTexture; //deterministic state, i guess CurrentTexture.SetFilterNearest(); return CurrentTexture; }
/// <summary> /// sets the provided buffer as pending. takes control of the supplied buffer /// </summary> public void SetPending(BitmapBuffer newPending) { lock (this) { if (Pending != null) ReleasedSurfaces.Enqueue(Pending); Pending = newPending; } }
public void AddFrame(IVideoProvider source) { using (var bb = new BitmapBuffer(source.BufferWidth, source.BufferHeight, source.GetVideoBuffer())) { string subpath = GetAndCreatePathForFrameNum(mCurrFrame); string path = subpath + ".png"; bb.ToSysdrawingBitmap().Save(path, System.Drawing.Imaging.ImageFormat.Png); } }
Art LoadArtInternal(BitmapBuffer tex) { AssertIsOpen(true); Art a = new Art(this); ArtLooseTextureAssociation[a] = tex; ManagedArts.Add(a); return a; }
/// <summary> /// returns the current buffer, making the most recent pending buffer (if there is such) as the new current first. /// </summary> public BitmapBuffer GetCurrent() { lock (this) { if (Pending != null) { if (Current != null) ReleasedSurfaces.Enqueue(Current); Current = Pending; Pending = null; } } return Current; }
public Texture2d LoadTexture(BitmapBuffer bmp) { Texture2d ret = null; int id = GenTexture(); try { ret = new Texture2d(this, id, bmp.Width, bmp.Height); GL.BindTexture(TextureTarget.Texture2D, id); //picking a color order that matches doesnt seem to help, any. maybe my driver is accelerating it, or maybe it isnt a big deal. but its something to study on another day GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); (this as IGL).LoadTextureData(ret, bmp); } catch { GL.DeleteTexture(id); throw; } //set default filtering.. its safest to do this always ret.SetFilterNearest(); return(ret); }
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { //note - this is dangerous since it changes the bound texture. could we save it? BindTexture2d(tex); var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight); var bmpdata = bb.LockBits(); GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmpdata.Scan0); var err = GL.GetError(); bb.UnlockBits(bmpdata); return bb; }
private void AvFrameAdvance() { GlobalWin.DisplayManager.NeedsToPaint = true; if (_currAviWriter != null) { //TODO ZERO - this code is pretty jacked. we'll want to frugalize buffers better for speedier dumping, and we might want to rely on the GL layer for padding try { //is this the best time to handle this? or deeper inside? if (_currAviWriterFrameList != null) { if (!_currAviWriterFrameList.Contains(Global.Emulator.Frame)) goto HANDLE_AUTODUMP; } IVideoProvider output; IDisposable disposableOutput = null; if (_avwriterResizew > 0 && _avwriterResizeh > 0) { BitmapBuffer bbin = null; Bitmap bmpin = null; Bitmap bmpout = null; try { if (Global.Config.AVI_CaptureOSD) { bbin = CaptureOSD(); } else { bbin = new BitmapBuffer(Global.Emulator.VideoProvider().BufferWidth, Global.Emulator.VideoProvider().BufferHeight, Global.Emulator.VideoProvider().GetVideoBuffer()); } bmpout = new Bitmap(_avwriterResizew, _avwriterResizeh, PixelFormat.Format32bppArgb); bmpin = bbin.ToSysdrawingBitmap(); using (var g = Graphics.FromImage(bmpout)) { if (_avwriterpad) { g.Clear(Color.FromArgb(Global.Emulator.VideoProvider().BackgroundColor)); g.DrawImageUnscaled(bmpin, (bmpout.Width - bmpin.Width) / 2, (bmpout.Height - bmpin.Height) / 2); } else { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; g.DrawImage(bmpin, new Rectangle(0, 0, bmpout.Width, bmpout.Height)); } } output = new BmpVideoProvider(bmpout); disposableOutput = (IDisposable)output; } finally { if (bbin != null) bbin.Dispose(); if (bmpin != null) bmpin.Dispose(); } } else { if (Global.Config.AVI_CaptureOSD) { output = new BitmapBufferVideoProvider(CaptureOSD()); disposableOutput = (IDisposable)output; } else output = Global.Emulator.VideoProvider(); } _currAviWriter.SetFrame(Global.Emulator.Frame); short[] samp; int nsamp; if (_dumpaudiosync) { (_currAviWriter as VideoStretcher).DumpAV(output, Global.Emulator.SyncSoundProvider, out samp, out nsamp); } else { (_currAviWriter as AudioStretcher).DumpAV(output, _aviSoundInput, out samp, out nsamp); } if (disposableOutput != null) { disposableOutput.Dispose(); } _dumpProxy.buffer.enqueue_samples(samp, nsamp); } catch (Exception e) { MessageBox.Show("Video dumping died:\n\n" + e); AbortAv(); } HANDLE_AUTODUMP: if (_autoDumpLength > 0) { _autoDumpLength--; if (_autoDumpLength == 0) // finish { StopAv(); if (_autoCloseOnDump) { _exit = true; } } } GlobalWin.DisplayManager.NeedsToPaint = true; } }
public Texture2d LoadTexture(BitmapBuffer bmp) { //definitely needed (by TextureFrugalizer at least) var sdbmp = bmp.ToSysdrawingBitmap(); IntPtr id = GenTexture(); var tw = new TextureWrapper(); tw.SDBitmap = sdbmp; ResourceIDs.Lookup[id.ToInt32()] = tw; return new Texture2d(this, id, null, bmp.Width, bmp.Height); }
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { //TODO - lazy create and cache resolving target in RT var target = new d3d9.Texture(dev, tex.IntWidth, tex.IntHeight, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.SystemMemory); var tw = tex.Opaque as TextureWrapper; dev.GetRenderTargetData(tw.Texture.GetSurfaceLevel(0), target.GetSurfaceLevel(0)); var dr = target.LockRectangle(0, LockFlags.ReadOnly); if (dr.Pitch != tex.IntWidth * 4) throw new InvalidOperationException(); int[] pixels = new int[tex.IntWidth * tex.IntHeight]; dr.Data.ReadRange(pixels, 0, tex.IntWidth * tex.IntHeight); var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels); target.UnlockRectangle(0); target.Dispose(); //buffer churn warning return bb; }
public unsafe void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { sdi.BitmapData bmp_data = bmp.LockBits(); var tw = tex.Opaque as TextureWrapper; var dr = tw.Texture.LockRectangle(0, LockFlags.None); //TODO - do we need to handle odd sizes, weird pitches here? if (bmp.Width * 4 != bmp_data.Stride) throw new InvalidOperationException(); dr.Data.WriteRange(bmp_data.Scan0, bmp.Width * bmp.Height * 4); dr.Data.Close(); tw.Texture.UnlockRectangle(0); bmp.UnlockBits(bmp_data); }
public Texture2d LoadTexture(BitmapBuffer bmp) { //definitely needed (by TextureFrugalizer at least) var sdbmp = bmp.ToSysdrawingBitmap(); var tw = new TextureWrapper(); tw.SDBitmap = sdbmp; return new Texture2d(this, tw, bmp.Width, bmp.Height); }
public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { var tw = tex.Opaque as TextureWrapper; bmp.ToSysdrawingBitmap(tw.SDBitmap); }
public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { sdi.BitmapData bmp_data = bmp.LockBits(); d3d9.Texture dtex = tex.Opaque as d3d9.Texture; var dr = dtex.LockRectangle(0, LockFlags.None); //TODO - do we need to handle odd sizes, weird pitches here? dr.Data.WriteRange(bmp_data.Scan0, bmp.Width * bmp.Height); dtex.UnlockRectangle(0); bmp.UnlockBits(bmp_data); }
public Texture2d LoadTexture(BitmapBuffer bmp) { var tex = new d3d9.Texture(dev, bmp.Width, bmp.Height, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.Managed); var ret = new Texture2d(this, IntPtr.Zero, tex, bmp.Width, bmp.Height); LoadTextureData(ret, bmp); return ret; }
public void Dispose() { if (bb != null) bb.Dispose(); bb = null; }
public Texture2d LoadTexture(sd.Bitmap bitmap) { using (var bmp = new BitmapBuffer(bitmap, new BitmapLoadOptions())) return((this as IGL).LoadTexture(bmp)); }
/// <summary> /// copies this bitmap and trims out transparent pixels, returning the offset to the topleft pixel /// </summary> public BitmapBuffer Trim(out int xofs, out int yofs) { int minx = int.MaxValue; int maxx = int.MinValue; int miny = int.MaxValue; int maxy = int.MinValue; for (int y = 0; y < Height; y++) for (int x = 0; x < Width; x++) { int pixel = GetPixel(x, y); int a = (pixel >> 24) & 0xFF; if (a != 0) { minx = Math.Min(minx, x); maxx = Math.Max(maxx, x); miny = Math.Min(miny, y); maxy = Math.Max(maxy, y); } } if (minx == int.MaxValue || maxx == int.MinValue || miny == int.MaxValue || minx == int.MinValue) { xofs = yofs = 0; return new BitmapBuffer(0, 0); } int w = maxx - minx + 1; int h = maxy - miny + 1; BitmapBuffer bbRet = new BitmapBuffer(w, h); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { bbRet.SetPixel(x, y, GetPixel(x + minx, y + miny)); } xofs = minx; yofs = miny; return bbRet; }
public Texture2d LoadTexture(sd.Bitmap bitmap) { using (var bmp = new BitmapBuffer(bitmap, new BitmapLoadOptions())) return (this as IGL).LoadTexture(bmp); }
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { var tw = tex.Opaque as TextureWrapper; var blow = new BitmapLoadOptions() { AllowWrap = false //must be an independent resource }; var bb = new BitmapBuffer(tw.SDBitmap,blow); return bb; }
public Texture2d LoadTexture(BitmapBuffer bmp) { var tex = new d3d9.Texture(dev, bmp.Width, bmp.Height, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.Managed); var tw = new TextureWrapper() { Texture = tex }; var ret = new Texture2d(this, tw, bmp.Width, bmp.Height); LoadTextureData(ret, bmp); return ret; }
FilterProgram UpdateSourceInternal(JobInfo job) { _glManager.Activate(CR_GraphicsControl); IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispFixAspectRatio) { if (Global.Config.DispManagerAR == Config.EDispManagerAR.System) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom) { vw = Global.Config.DispCustomUserARWidth; vh = Global.Config.DispCustomUserARHeight; } } int[] videoBuffer = videoProvider.GetVideoBuffer(); TESTEROO: int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; //TODO - need to do some work here for GDI+ to repair gl texture ID importing BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); GL.SetTextureWrapMode(videoTexture, true); } //TEST (to be removed once we have an actual example of bring in a texture ID from opengl emu core): //if (!isGlTextureId) //{ // videoBuffer = new int[1] { videoTexture.Id.ToInt32() }; // goto TESTEROO; //} } //record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chain_insize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter BizHawk.Client.EmuHawk.Filters.SourceImage fInput = filterProgram["input"] as BizHawk.Client.EmuHawk.Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter BizHawk.Client.EmuHawk.Filters.FinalPresentation fPresent = filterProgram["presentation"] as BizHawk.Client.EmuHawk.Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; fPresent.GL = GL; filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen); if (simulate) { } else { CurrentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } //cleanup: if (bb != null) bb.Dispose(); return filterProgram; }
public Texture2d LoadTexture(Stream stream) { using (var bmp = new BitmapBuffer(stream, new BitmapLoadOptions())) return (this as IGL).LoadTexture(bmp); }
public void LoadFrom(BitmapBuffer buffer) { }
public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { bmp.ToSysdrawingBitmap(BitmapForTexture(tex)); }
/// <summary> /// Closes this instance for for further resource loading. Will result in a texture atlasing operation. /// If the close operation is forever, then internal backup copies of resources will be freed, but it can never be reopened. /// This function may take some time to run, as it is /// </summary> public unsafe void Close(bool forever = true) { AssertIsOpen(true); IsOpened = false; IsClosedForever = forever; // first, cleanup old stuff foreach (var tex in ManagedTextures) { tex.Dispose(); } ManagedTextures.Clear(); // prepare input for atlas process and perform atlas // add 2 extra pixels for padding on all sides var atlasItems = new List <TexAtlas.RectItem>(); foreach (var kvp in ArtLooseTextureAssociation) { atlasItems.Add(new TexAtlas.RectItem(kvp.Value.Width + 2, kvp.Value.Height + 2, kvp)); } var results = TexAtlas.PackAtlas(atlasItems); // this isn't supported yet: if (results.Atlases.Count > 1) { throw new InvalidOperationException("Art files too big for atlas"); } // prepare the output buffer BitmapBuffer bmpResult = new BitmapBuffer(results.Atlases[0].Size); //for each item, copy it into the output buffer and set the tex parameters on them for (int i = 0; i < atlasItems.Count; i++) { var item = results.Atlases[0].Items[i]; var artAndBitmap = (KeyValuePair <Art, BitmapBuffer>)item.Item; var art = artAndBitmap.Key; var bitmap = artAndBitmap.Value; int w = bitmap.Width; int h = bitmap.Height; int dx = item.X + 1; int dy = item.Y + 1; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int pixel = bitmap.GetPixel(x, y); bmpResult.SetPixel(x + dx, y + dy, pixel); } } var myDestBitmap = bmpResult; float myDestWidth = (float)myDestBitmap.Width; float myDestHeight = (float)myDestBitmap.Height; art.u0 = dx / myDestWidth; art.v0 = dy / myDestHeight; art.u1 = (dx + w) / myDestWidth; art.v1 = (dy + h) / myDestHeight; art.Width = w; art.Height = h; } //if we're closed forever, then forget all the original bitmaps if (forever) { foreach (var kvp in ArtLooseTextureAssociation) { kvp.Value.Dispose(); } ArtLooseTextureAssociation.Clear(); } //create a physical texture var texture = Owner.LoadTexture(bmpResult); ManagedTextures.Add(texture); //oops, we couldn't do this earlier. foreach (var art in ManagedArts) { art.BaseTexture = texture; } }
FilterProgram UpdateSourceInternal(JobInfo job) { //no drawing actually happens. it's important not to begin drawing on a control if (!job.simulate) { GlobalWin.GLManager.Activate(CR_GraphicsControl); } IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; //simulate = true; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispFixAspectRatio) { if (Global.Config.DispManagerAR == Config.EDispManagerAR.System) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom) { vw = Global.Config.DispCustomUserARWidth; vh = Global.Config.DispCustomUserARHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.CustomRatio) { FixRatio(Global.Config.DispCustomUserARX, Global.Config.DispCustomUserARY, videoProvider.BufferWidth, videoProvider.BufferHeight, out vw, out vh); } } var padding = CalculateCompleteContentPadding(true,false); vw += padding.Horizontal; vh += padding.Vertical; int[] videoBuffer = videoProvider.GetVideoBuffer(); int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { //FYI: this is a million years from happening on n64, since it's all geriatric non-FBO code //is it workable for saturn? videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); bb.DiscardAlpha(); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); //lets not use this. lets define BizwareGL to make clamp by default (TBD: check opengl) //GL.SetTextureWrapMode(videoTexture, true); } } //record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chain_insize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter Filters.SourceImage fInput = filterProgram["input"] as Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter Filters.FinalPresentation fPresent = filterProgram["presentation"] as Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; fPresent.Config_FixAspectRatio = Global.Config.DispFixAspectRatio; fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger; fPresent.Padding = ClientExtraPadding; fPresent.GL = GL; filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen); if (simulate) { } else { CurrentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } //cleanup: if (bb != null) bb.Dispose(); return filterProgram; }
public Texture2d LoadTexture(Stream stream) { using (var bmp = new BitmapBuffer(stream, new BitmapLoadOptions())) return((this as IGL).LoadTexture(bmp)); }
private void btnExport_Click(object sender, EventArgs e) { if(mFrameInfos.Count == 0) return; int width, height; using(var bmp = new Bitmap(mFrameInfos[0].pngPath)) { width = bmp.Width; height = bmp.Height; } var sfd = new SaveFileDialog(); sfd.FileName = Path.ChangeExtension(mSynclessConfigFile, ".avi"); sfd.InitialDirectory = Path.GetDirectoryName(sfd.FileName); if (sfd.ShowDialog() == DialogResult.Cancel) return; using (AviWriter avw = new AviWriter()) { avw.SetAudioParameters(44100, 2, 16); //hacky avw.SetMovieParameters(60, 1); //hacky avw.SetVideoParameters(width, height); var token = avw.AcquireVideoCodecToken(this); avw.SetVideoCodecToken(token); avw.OpenFile(sfd.FileName); foreach (var fi in mFrameInfos) { using (var bb = new BitmapBuffer(fi.pngPath, new BitmapLoadOptions())) { var bbvp = new BitmapBufferVideoProvider(bb); avw.AddFrame(bbvp); } //offset = 44 dec var wavBytes = File.ReadAllBytes(fi.wavPath); var ms = new MemoryStream(wavBytes); ms.Position = 44; var br = new BinaryReader(ms); List<short> sampledata = new List<short>(); while (br.BaseStream.Position != br.BaseStream.Length) { sampledata.Add(br.ReadInt16()); } avw.AddSamples(sampledata.ToArray()); } avw.CloseFile(); } }
private static unsafe BitmapBuffer MakeScreenshotImage() { var bb = new BitmapBuffer(Global.Emulator.VideoProvider().BufferWidth, Global.Emulator.VideoProvider().BufferHeight, Global.Emulator.VideoProvider().GetVideoBuffer()); bb.DiscardAlpha(); return bb; }
public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { sdi.BitmapData bmp_data = bmp.LockBits(); try { GL.BindTexture(TextureTarget.Texture2D, (int)tex.Opaque); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bmp.Width, bmp.Height, PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0); } finally { bmp.UnlockBits(bmp_data); } }
public Texture2d LoadTexture(BitmapBuffer bmp) { Texture2d ret = null; int id = GenTexture(); try { ret = new Texture2d(this, id, bmp.Width, bmp.Height); GL.BindTexture(TextureTarget.Texture2D, id); //picking a color order that matches doesnt seem to help, any. maybe my driver is accelerating it, or maybe it isnt a big deal. but its something to study on another day GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); (this as IGL).LoadTextureData(ret, bmp); } catch { GL.DeleteTexture(id); throw; } //set default filtering.. its safest to do this always ret.SetFilterNearest(); return ret; }