void FillTxm(Db2Element elem, TxmHeader txm) { Tex0 tex0 = new Tex0 { Packed = BitConverter.ToUInt64(elem.GsRegs, 0x10) }; txm.ImageSourcePixelFormat = (TxmPixelFormat)tex0.Psm; txm.ImageVideoPixelFormat = txm.ImageSourcePixelFormat; txm.ImageWidth = (short)(1 << tex0.Tw); txm.ImageHeight = (short)(1 << tex0.Th); txm.Misc = tex0.Tbw; if (txm.ImageSourcePixelFormat == TxmPixelFormat.PSMT4 || txm.ImageSourcePixelFormat == TxmPixelFormat.PSMT8) { txm.ClutPixelFormat = (TxmPixelFormat)tex0.Cpsm; if (txm.ImageSourcePixelFormat == TxmPixelFormat.PSMT4) { txm.ClutWidth = 8; txm.ClutHeight = 2; } else { txm.ClutWidth = 16; txm.ClutHeight = 16; } } else { txm.ClutPixelFormat = TxmPixelFormat.None; } }
public Btx0() { this.nitro = new NitroFile("BTX0", "1.0", BlockTypes) { HasOffsets = true }; this.tex0 = new Tex0(this.nitro); this.nitro.Blocks.Add(this.tex0); this.images = new List <Image>(); }
private void GetInfo() { this.tex0 = this.nitro.GetBlock <Tex0>(0); this.images = new List <Image>(this.tex0.TextureInfo.NumObjects); for (int i = 0; i < tex0.TextureInfo.NumObjects; i++) { Image img = new Image(); img.Width = (int)tex0.TextureInfo.Data[i].Width; img.Height = (int)tex0.TextureInfo.Data[i].Height; img.SetData( tex0.TextureData[i], Ninoimager.Format.PixelEncoding.Lineal, tex0.TextureInfo.Data[i].Format ); this.images.Add(img); } }
public GsProcessor() { operations = new List<Operation>(); Verbose = false; Memory = new uint[MemorySize]; PageBuffer = new List<uint>(PageBufferSize); Tex0_1 = new Tex0(1); Tex0_2 = new Tex0(2); TexFlush = new TexFlush(this); BitBlfBuf = new BitBlfBuf(); TrxPos = new TrxPos(); TrxReg = new TrxReg(); TrxDir = new TrxDir(); HwReg = new HwReg(this); }
private void SetTarget(MDL0MaterialRefNode texture) { if (_targetMatRef != texture && texture != null) { CurrentViewport.Camera.Reset(); } if (_attached == null) { _attached = new List <ResourceNode>(); } if (Tex0 != null) { Tex0.Unbind(); } _attached.Clear(); _targetMatRef = texture; if (_targetMatRef == null) { return; } _attached.Add(_targetMatRef); if (Tex0 != null) { Tex0.Prepare(_targetMatRef, -1); } //Dispose of all old UV buffers if (_renderInfo != null) { foreach (RenderInfo info in _renderInfo) { if (info._renderBuffer != null) { info._renderBuffer.Dispose(); } } } //Recreate lists _objIndices = new List <int>(); _uvSetIndices = new List <int>(); _renderInfo = new List <RenderInfo>(); _objNames.Clear(); _uvSetNames.Clear(); int coordID = _targetMatRef.TextureCoordId; if (coordID < 0) { _objNames.Add("None"); _uvSetNames.Add("None"); Invalidate(); return; } if (_targetMatRef.Material.Objects.Length > 1) { _objNames.Add("All"); //TODO: need to change the UV dropdown box to show only texcoords 0-7 that exist //not the uv set names coordID = -1; } Vector2 min = new Vector2(float.MaxValue); Vector2 max = new Vector2(float.MinValue); foreach (MDL0ObjectNode obj in _targetMatRef.Material.Objects) { _objNames.Add(obj.Name); RenderInfo info = new RenderInfo(obj._manager); _renderInfo.Add(info); min.Min(info._min); max.Max(info._max); } if (_objNames.Count == 0) { _objNames.Add("None"); _uvSetNames.Add("None"); Invalidate(); return; } //TODO: zoom the camera out to the nearest whole texture repetition //to display all texture coordinates. //Change from [0, 1] to [-0.5, 0.5] //min -= 0.5f; //max -= 0.5f; //float xCorrect = 1.0f, yCorrect = 1.0f; //GLTexture t = _targetMatRef.TextureNode.Texture; //float texWidth = t.Width; //float texHeight = t.Height; //float tAspect = (float)texWidth / texHeight; //float wAspect = (float)Width / Height; //int minXmult = (int)(min._x + (min._x < 0 ? -1 : 0)); //int maxXmult = (int)(max._x + (max._x < 0 ? 0 : 1)); //int minYmult = (int)(min._y + (min._y < 0 ? -1 : 0)); //int maxYmult = (int)(max._y + (max._y < 0 ? 0 : 1)); //if (tAspect > wAspect) //{ // yCorrect = tAspect / wAspect; //} //else //{ // xCorrect = wAspect / tAspect; //} //CurrentViewport.Camera.Translate( // ((float)(minXmult + maxXmult) / 2.0f - 0.5f) / xCorrect * Width, // ((float)(minYmult + maxYmult) / 2.0f - 0.5f) / yCorrect * -Height, 0); //float scale = Math.Max(maxXmult - minXmult, maxYmult - minYmult); //CurrentViewport.Camera.Scale(scale, scale, scale); SetObjectIndex(-1); SetUVIndex(coordID); }
public void Render(GLCamera cam, bool renderBG) { cam.LoadProjection(); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Color4(Color.White); GL.Enable(EnableCap.Texture2D); float halfW = (float)Width / 2.0f, halfH = (float)Height / 2.0f; GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.MatrixMode(MatrixMode.Texture); GL.LoadIdentity(); if (renderBG) { GL.PushAttrib(AttribMask.TextureBit); GLTexture bgTex = TKContext.FindOrCreate <GLTexture>("TexBG", GLTexturePanel.CreateBG); bgTex.Bind(); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); float s = (float)Width / (float)bgTex.Width, t = (float)Height / (float)bgTex.Height; GL.Begin(BeginMode.Quads); GL.TexCoord2(0.0f, 0.0f); GL.Vertex2(-halfW, -halfH); GL.TexCoord2(s, 0.0f); GL.Vertex2(halfW, -halfH); GL.TexCoord2(s, t); GL.Vertex2(halfW, halfH); GL.TexCoord2(0.0f, t); GL.Vertex2(-halfW, halfH); GL.End(); GL.PopAttrib(); } if (Tex0 == null) { return; } Tex0.Prepare(_targetMatRef, -1); GLTexture texture = GLTex; if (texture == null || texture._texId <= 0) { return; } MDL0TextureNode.ApplyGLTextureParameters(_targetMatRef); //These are used to match up the UV overlay to the texture underneath Vector2 topLeft = new Vector2(); Vector2 bottomRight = new Vector2(); float texWidth = texture.Width; float texHeight = texture.Height; float tAspect = (float)texWidth / texHeight; float wAspect = (float)Width / Height; float[] texCoord = new float[8]; //These are used to compensate for padding added on an axis float xCorrect = 1.0f, yCorrect = 1.0f; if (tAspect > wAspect) { //Texture is wider, use horizontal fit //X touches the edges of the window, Y has top and bottom padding //X texCoord[0] = texCoord[6] = 0.0f; texCoord[2] = texCoord[4] = 1.0f; //Y texCoord[1] = texCoord[3] = (yCorrect = tAspect / wAspect) / 2.0f + 0.5f; texCoord[5] = texCoord[7] = 1.0f - texCoord[1]; bottomRight = new Vector2(halfW, (((float)Height - ((float)Width / texWidth * texHeight)) / (float)Height / 2.0f - 0.5f) * (float)Height); topLeft = new Vector2(-halfW, -bottomRight._y); } else { //Window is wider, use vertical fit //Y touches the edges of the window, X has left and right padding //Y texCoord[1] = texCoord[3] = 1.0f; texCoord[5] = texCoord[7] = 0.0f; //X texCoord[2] = texCoord[4] = (xCorrect = wAspect / tAspect) / 2.0f + 0.5f; texCoord[0] = texCoord[6] = 1.0f - texCoord[2]; bottomRight = new Vector2(1.0f - (((float)Width - ((float)Height / texHeight * texWidth)) / Width / 2.0f - 0.5f) * (float)Width, -halfH); topLeft = new Vector2(-bottomRight._x, halfH); } //Apply the texcoord bind transform first TextureFrameState state = _targetMatRef._bindState; GL.MultMatrix((float *)&state._transform); //Translate the texture coordinates to match where the user dragged the camera //Divide by width and height to convert window units (0 to w, 0 to h) to texcoord units (0 to 1) //Then multiply by the correction value if the window is bigger than the texture on an axis Vector3 point = cam.GetPoint(); GL.Translate(point._x / Width * xCorrect, -point._y / Height * yCorrect, 0); //Now to scale the texture after translating. //The scale origin is the top left of the texture on the window (not of the window itself), //so we need to translate the center of the texture to that origin, //scale it up or down, then translate it back to where it was. OpenTK.Vector3 trans = new OpenTK.Vector3(-topLeft._x / Width * xCorrect, topLeft._y / Height * yCorrect, 0.0f); GL.Translate(trans); GL.Scale((OpenTK.Vector3)cam._scale); GL.Translate(-trans); //Bind the material ref's texture GL.BindTexture(TextureTarget.Texture2D, texture._texId); //Draw a quad across the screen and render the texture with the calculated texcoords GL.Begin(BeginMode.Quads); GL.TexCoord2(texCoord[0], texCoord[1]); GL.Vertex2(-halfW, -halfH); GL.TexCoord2(texCoord[2], texCoord[3]); GL.Vertex2(halfW, -halfH); GL.TexCoord2(texCoord[4], texCoord[5]); GL.Vertex2(halfW, halfH); GL.TexCoord2(texCoord[6], texCoord[7]); GL.Vertex2(-halfW, halfH); GL.End(); GL.Disable(EnableCap.Texture2D); //Now load the camera transform and draw the UV overlay over the texture cam.LoadModelView(); //Color the lines limegreen, a bright color that probably won't be in a texture GL.Color4(Color.LimeGreen); Vector2 mdlScale = new Vector2(bottomRight._x - topLeft._x, bottomRight._y - topLeft._y); GL.Translate(topLeft._x, topLeft._y, 0.0f); GL.Scale(mdlScale._x, mdlScale._y, 1.0f); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); GL.LineWidth(1); //Render texture coordinates as vertex points foreach (RenderInfo info in _renderInfo) { info.PrepareStream(); } }