public void on_operation_changed(object o, EventArgs e) { LogFile.GetInstance().WriteLine("on_operation_changed >>> "); if (!settingtexturestagecomboentry) { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); if (maptexturestage != null) { if (operationcombo.Entry.Text != "") { MapTextureStage.OperationType operation = MapTextureStage.OperationType.NoTexture; if (operationcombo.Entry.Text == "Blend") { operation = MapTextureStage.OperationType.Blend; } else if (operationcombo.Entry.Text == "Replace") { operation = MapTextureStage.OperationType.Replace; } else if (operationcombo.Entry.Text == "Nop") { operation = MapTextureStage.OperationType.Nop; } else if (operationcombo.Entry.Text == "NoTexture") { operation = MapTextureStage.OperationType.NoTexture; } maptexturestage.Operation = operation; terrain.OnTerrainModified(); } } } LogFile.GetInstance().WriteLine("on_operation_changed <<<"); }
public RendererTextureStage(MapTextureStage maptexturestage, int maptexturestagepass, bool UsingMultipass, int mapwidth, int mapheight) { this.maptexturestage = maptexturestage; this.maptexturestagepass = maptexturestagepass; this.mapwidth = mapwidth; this.mapheight = mapheight; this.UsingMultipass = UsingMultipass; }
// in-place blendmaptexture editing public void OnBlendMapInPlaceEdited(MapTextureStage maptexturestage, int xleft, int ytop, int xright, int ybottom) // probably could be a little more specific... { //renderableheightmap.MapTexturesModified(Math.Max(0, xleft), Math.Max(0, ytop), Math.Min(HeightMapWidth - 1, xright), Math.Min(HeightMapHeight - 1, ybottom)); if (BlendmapInPlaceEdited != null) { BlendmapInPlaceEdited(maptexturestage, Math.Max(0, xleft), Math.Max(0, ytop), Math.Min(HeightMapWidth - 2, xright), Math.Min(HeightMapHeight - 2, ybottom)); } }
void on_btnLoadBlendTexture_clicked(object o, EventArgs e) { string filepath = GetFilePath("Load blend texture", "*.JPG"); if (filepath != "") { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); maptexturestage.blendtexture.LoadFromFile(filepath); terrain.OnTerrainModified(); } }
void on_btnSaveAsBlendTexture_clicked(object o, EventArgs e) { string filepath = GetFilePath("Save blend texture as", "*.JPG"); if (filepath != "") { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); maptexturestage.blendtexture.SaveAlphaToFile(filepath); blendtexturefilename.Text = filepath; } }
void on_tilesizescale_value_changed(object o, EventArgs e) { if (!settingtexturestagecomboentry) { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); if (maptexturestage != null) { LogFile.GetInstance().WriteLine("changing tilesize to " + (int)tilesizescale.Value); maptexturestage.Tilesize = (int)tilesizescale.Value; } } }
void on_btnSaveBlendTexture_clicked(object o, EventArgs e) { if (blendtexturefilename.Text == "") { on_btnSaveAsBlendTexture_clicked(o, e); } else { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); maptexturestage.blendtexture.SaveAlphaToFile(blendtexturefilename.Text); } }
MapTextureStage GetSelectedMapTextureStage() { try { MapTextureStage maptexturestage = terrain.texturestages[GetSelectedMapTextureStageIndex()]; return(maptexturestage); } catch (Exception) { //Console.WriteLine(e); return(null); } }
void on_btnRemoveStage_clicked(object o, EventArgs e) { if (terrain.texturestages.Count > 1) { MapTextureStage maptexturestage = GetSelectedMapTextureStage(); if (maptexturestage != null) { Terrain.GetInstance().texturestages.Remove(maptexturestage); terrain.OnTerrainModified(); } } else { InfoMessage("You need at least one texture stage for the map to run"); } }
void on_texturestage_changed(object o, EventArgs e) { LogFile.GetInstance().WriteLine("on_texturestage_changed() >>>"); MapTextureStage maptexturestage = GetSelectedMapTextureStage(); if (maptexturestage != null) { texturefilenamelbl.Text = maptexturestage.SplatTextureFilename; blendtexturefilename.Text = maptexturestage.BlendTextureFilename; operationcombo.Entry.Text = maptexturestage.Operation.ToString(); (BrushEffectController.GetInstance() .brusheffects[typeof(PaintTexture)] as PaintTexture) .SetCurrentEditTexture(maptexturestage); tilesizescale.Value = maptexturestage.Tilesize; } LogFile.GetInstance().WriteLine("on_texturestage_changed() <<<"); }
void terrain_BlendmapInPlaceEdited(MapTextureStage maptexturestage, int xleft, int ytop, int xright, int ybottom) { for (int chunkx = xleft / chunksize; chunkx <= xright / chunksize && chunkx < width / chunksize; chunkx++) { for (int chunky = ytop / chunksize; chunky <= ybottom / chunksize && chunky < height / chunksize; chunky++) { // Console.WriteLine("chunk " + chunkx + " " + chunky); //for (int texturestageindex = 0; texturestageindex < maptexturestages.GetLength(0); texturestageindex++) //{ // maptexturestage = maptexturestages[texturestageindex]; if (maptexturestage.Operation == MapTextureStage.OperationType.Blend) { bool texturestageused = false; // go through each point in chunk and check if texturestage is used for (int mapx = chunkx * chunksize; mapx < (chunkx + 1) * chunksize && !texturestageused; mapx++) { for (int mapy = chunky * chunksize; mapy < (chunky + 1) * chunksize && !texturestageused; mapy++) { //if (mapx < width && mapy < height) //{ if (maptexturestage.Affects(mapx, mapy, width, height)) { texturestageused = true; } //} } } chunkusestexturestage[maptexturestage][chunkx, chunky] = texturestageused; // if (chunkusestexturestage[texturestageindex][chunkx, chunky]) //{ // Console.WriteLine("texturestage used: " + texturestageindex + " " + chunkx + " " + chunky); //} } else { chunkusestexturestage[maptexturestage][chunkx, chunky] = true; } //} } } }
void LoadTextureData(MapTextureStage maptexturestage) { thistexture = maptexturestage.blendtexture; if (thistexture != null) { texturewidth = thistexture.Width; textureheight = thistexture.Height; LogFile.GetInstance().WriteLine("edittexture width " + texturewidth + " height " + textureheight); alphadata = new double[texturewidth, textureheight]; for (int x = 0; x < texturewidth; x++) { for (int y = 0; y < textureheight; y++) { alphadata[x, y] = thistexture.AlphaData[x, y]; } } } }
// note to self: move this to subscriber? void DrawMinimap() { Terrain terrain = Terrain.GetInstance(); if (DateTime.Now.Subtract(LastMinimapUpdate).TotalMilliseconds > 1000) //if( true ) { List <RendererPass> rendererpasses = new List <RendererPass>(); bool multipass = true; // force multipass for now for simplicity int maxtexels = RendererSdl.GetInstance().MaxTexelUnits; if (multipass) { for (int i = 0; i < terrain.texturestages.Count; i++) { MapTextureStage maptexturestage = terrain.texturestages[i]; int numtexturestagesrequired = maptexturestage.NumTextureStagesRequired; if (numtexturestagesrequired > 0) // exclude Nops { RendererPass rendererpass = new RendererPass(maxtexels); for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++) { rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, mapwidth * Terrain.SquareSize, mapheight * Terrain.SquareSize)); } rendererpasses.Add(rendererpass); } } } GraphicsHelperGl g = new GraphicsHelperGl(); //g.ApplyOrtho(windowwidth, windowheight, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight); g.EnableBlendSrcAlpha(); Gl.glDepthFunc(Gl.GL_LEQUAL); int chunkwidth = minimapwidth / numchunks; int chunkheight = minimapheight / numchunks; float[] ambientLight = new float[] { 0.4f, 0.4f, 0.4f, 1.0f }; float[] diffuseLight = new float[] { 0.6f, 0.6f, 0.6f, 1.0f }; float[] specularLight = new float[] { 0.2f, 0.2f, 0.2f, 1.0f }; float[] position = new float[] { -1.0f, 0.2f, -0.4f, 1.0f }; Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position); foreach (RendererPass rendererpass in rendererpasses) { rendererpass.Apply(); for (int x = 0; x + chunkwidth < minimapwidth; x += chunkwidth) { for (int y = 0; y + chunkheight < minimapheight; y += chunkheight) { Gl.glBegin(Gl.GL_QUADS); //double ul = 0; //double ur = mapwidth * Terrain.SquareSize; //double vt = 0; //double vb = mapheight * Terrain.SquareSize; double ul = (double)x / minimapwidth * mapwidth * Terrain.SquareSize; double ur = (double)(x + chunkwidth) / minimapwidth * mapwidth * Terrain.SquareSize; double vt = (double)y / minimapheight * mapheight * Terrain.SquareSize; double vb = (double)(y + chunkheight) / minimapheight * mapheight * Terrain.SquareSize; double xl = minimapx + x; double xr = minimapx + x + minimapwidth / (double)numchunks; double yt = minimapy + y; double yb = minimapy + y + minimapheight / (double)numchunks; Gl.glTexCoord2d(ul, vt); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vt); g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, y * mapheight / minimapheight)); //g.Normal(renderableheightmap.normalsperquad[, ]); Gl.glVertex2d(xl, yt); Gl.glTexCoord2d(ul, vb); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vb); g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight)); //g.Normal( renderableheightmap.normalsperquad[x * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight ] ); Gl.glVertex2d(xl, yb); Gl.glTexCoord2d(ur, vb); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vb); g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight)); //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight]); Gl.glVertex2d(xr, yb); Gl.glTexCoord2d(ur, vt); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vt); g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, y * mapheight / minimapheight)); //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, y * mapheight / minimapheight]); Gl.glVertex2d(xr, yt); Gl.glEnd(); } } } g.ActiveTexture(0); Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture); Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, minimapx, RendererSdl.GetInstance().InnerWindowHeight - minimapy - minimapsize, minimapsize, minimapsize, 0); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST); LastMinimapUpdate = DateTime.Now; // g.RemoveOrtho(); g.ActiveTexture(1); g.DisableTexture2d(); g.SetTextureScale(1); g.ActiveTexture(0); g.SetTextureScale(1); g.EnableModulate(); Gl.glDisable(Gl.GL_BLEND); } else { GraphicsHelperGl g = new GraphicsHelperGl(); //Gl.glMatrixMode(Gl.GL_PROJECTION); //Gl.glPushMatrix(); //Gl.glLoadIdentity(); //Gl.glOrtho(0, windowwidth, windowheight - RendererSdl.GetInstance().OuterWindowHeight, 0, -1, 1); // we'll just draw the minimap directly onto our display //Gl.glOrtho(0, windowwidth, windowheight, windowheight - RendererSdl.GetInstance().OuterWindowHeight, -1, 1); // we'll just draw the minimap directly onto our display //Gl.glMatrixMode(Gl.GL_MODELVIEW); //Gl.glPushMatrix(); //Gl.glLoadIdentity(); g.ActiveTexture(0); g.EnableTexture2d(); Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture); //Gl.glBindTexture(Gl.GL_TEXTURE_2D, (terrain.texturestages[0].texture as GlTexture).GlReference); Gl.glDisable(Gl.GL_LIGHTING); Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 1); Gl.glVertex2i(minimapx, minimapy); Gl.glTexCoord2d(0, 1 - minimapwidth / (double)minimapsize); Gl.glVertex2i(minimapx, minimapy + minimapheight); Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1 - minimapheight / (double)minimapsize); Gl.glVertex2i(minimapx + minimapwidth, minimapy + minimapheight); Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1); Gl.glVertex2i(minimapx + minimapwidth, minimapy); Gl.glEnd(); Gl.glEnable(Gl.GL_LIGHTING); //Gl.glMatrixMode(Gl.GL_PROJECTION); //Gl.glPopMatrix(); //Gl.glMatrixMode(Gl.GL_MODELVIEW); //Gl.glPopMatrix(); } }
public void SetCurrentEditTexture(MapTextureStage maptexturestage) { this.maptexturestage = maptexturestage; LoadTextureData(maptexturestage); }
// what we need to do is to render the splatted texture in ortho mode with lighting off // or normals off (to be tested) // then to export the generated bitmap // viewport should be set to heightmapwidth x heightmapheight public void Export(string filepath) { Terrain terrain = Terrain.GetInstance(); int picturewidth = terrain.MapWidth * Terrain.SquareSize; int pictureheight = terrain.MapHeight * Terrain.SquareSize; LogFile.GetInstance().WriteLine("Export to " + filepath + " picturewidth " + picturewidth + " pictureheight: " + pictureheight); //int windowwidth = RendererSdl.GetInstance().WindowWidth; //int windowheight = RendererSdl.GetInstance().WindowHeight; int windowwidth = 256; int windowheight = 256; Gl.glViewport(0, 0, windowwidth, windowheight); byte[] buffer = new byte[windowwidth * windowheight * 4]; //System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap( picturewidth, pictureheight ); //byte[] imagedata = new byte[picturewidth * pictureheight * 4]; Image image = new Image(picturewidth, pictureheight); List <RendererPass> rendererpasses = new List <RendererPass>(); bool multipass = true; // force multipass for now for simplicity int maxtexels = RendererSdl.GetInstance().MaxTexelUnits; if (multipass) { for (int i = 0; i < terrain.texturestages.Count; i++) { MapTextureStage maptexturestage = terrain.texturestages[i]; int numtexturestagesrequired = maptexturestage.NumTextureStagesRequired; if (numtexturestagesrequired > 0) // exclude Nops { RendererPass rendererpass = new RendererPass(maxtexels); for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++) { rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, picturewidth, pictureheight)); } rendererpasses.Add(rendererpass); } } } GraphicsHelperGl g = new GraphicsHelperGl(); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glPushMatrix(); Gl.glLoadIdentity(); Gl.glOrtho(0, windowwidth, windowheight, 0, -1, 1); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glPushMatrix(); Gl.glLoadIdentity(); Gl.glDisable(Gl.GL_CULL_FACE); Gl.glDisable(Gl.GL_LIGHTING); g.EnableBlendSrcAlpha(); Gl.glDepthFunc(Gl.GL_LEQUAL); for (int chunkx = 0; chunkx < Math.Ceiling((double)picturewidth / windowwidth); chunkx++) { for (int chunky = 0; chunky < Math.Ceiling((double)pictureheight / windowheight); chunky++) { Console.WriteLine("chunkx " + chunkx + " chunky " + chunky); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer foreach (RendererPass rendererpass in rendererpasses) { rendererpass.Apply(); Gl.glBegin(Gl.GL_QUADS); double ul = (chunkx * windowwidth); double ur = (chunkx * windowwidth + windowwidth); double vt = (chunky * windowheight); double vb = (chunky * windowheight + windowheight); Gl.glTexCoord2d(ul, vt); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vt); Gl.glVertex2i(0, 0); Gl.glTexCoord2d(ul, vb); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vb); Gl.glVertex2i(0, windowheight); Gl.glTexCoord2d(ur, vb); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vb); Gl.glVertex2i(windowwidth, windowheight); Gl.glTexCoord2d(ur, vt); Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vt); Gl.glVertex2i(windowwidth, 0); Gl.glEnd(); } IntPtr ptr = Marshal.AllocHGlobal(windowwidth * windowheight * 4); Gl.glReadPixels(0, 0, windowwidth, windowheight, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ptr); Marshal.Copy(ptr, buffer, 0, windowwidth * windowheight * 4); Marshal.FreeHGlobal(ptr); for (int x = 0; x < windowwidth; x++) { for (int y = 0; y < windowheight; y++) { if ((chunky * windowheight + y < pictureheight) && (chunkx * windowwidth + x < picturewidth)) { int pixeloffset = (windowheight - y - 1) * windowwidth * 4 + x * 4; //bitmap.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight, System.Drawing.Color.FromArgb(buffer[pixeloffset + 0], //buffer[pixeloffset + 1], buffer[pixeloffset + 2])); image.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight, buffer[pixeloffset + 0], buffer[pixeloffset + 1], buffer[pixeloffset + 2], 255 ); } } } } } if (File.Exists(filepath)) { File.Delete(filepath); } image.Save(filepath); //DevIL.DevIL.SaveBitmap( filepath, bitmap); Gl.glPopMatrix(); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glPopMatrix(); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glEnable(Gl.GL_LIGHTING); g.ActiveTexture(1); g.DisableTexture2d(); g.SetTextureScale(1); g.ActiveTexture(0); g.SetTextureScale(1); Gl.glEnable(Gl.GL_CULL_FACE); Gl.glEnable(Gl.GL_LIGHTING); Gl.glDisable(Gl.GL_BLEND); g.EnableModulate(); Gl.glViewport(0, 0, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight); g.CheckError(); MainUI.GetInstance().uiwindow.InfoMessage("Exported blended terrain texture to " + filepath); }
// determine which chunks are used by each texture stage // only affects blend really void CacheChunkTextureStageUsage() { int numxchunks = width / chunksize; int numychunks = height / chunksize; chunkusestexturestage = new Dictionary <MapTextureStage, bool[, ]>(); foreach (MapTextureStage maptexturestage in maptexturestages) { chunkusestexturestage.Add(maptexturestage, new bool[numxchunks, numychunks]); } for (int chunkx = 0; chunkx < numxchunks; chunkx++) { for (int chunky = 0; chunky < numychunks; chunky++) { // Console.WriteLine("chunk " + chunkx + " " + chunky); for (int texturestageindex = 0; texturestageindex < maptexturestages.Count; texturestageindex++) { MapTextureStage texturestage = maptexturestages[texturestageindex]; //Console.WriteLine("texturestage " + texturestageindex + " " + texturestage.Operation ); if (texturestage.Operation == MapTextureStage.OperationType.Blend) { bool texturestageused = false; // go through each point in chunk and check if texturestage is used for (int mapx = chunkx * chunksize; mapx < (chunkx + 1) * chunksize && !texturestageused; mapx++) { for (int mapy = chunky * chunksize; mapy < (chunky + 1) * chunksize && !texturestageused; mapy++) { if (texturestage.Affects(mapx, mapy, width, height)) { texturestageused = true; } } } chunkusestexturestage[texturestage][chunkx, chunky] = texturestageused; // if (chunkusestexturestage[texturestageindex][chunkx, chunky]) //{ // Console.WriteLine("texturestage used: " + texturestageindex + " " + chunkx + " " + chunky); //} } else if (texturestage.Operation == MapTextureStage.OperationType.Nop) { chunkusestexturestage[texturestage][chunkx, chunky] = false; } else { //Console.WriteLine("RenderableHeightMap,, cache chunk usage, true"); chunkusestexturestage[texturestage][chunkx, chunky] = true; } } } } maxtexels = RendererSdl.GetInstance().MaxTexelUnits; int totaltexturestagesneeded = 0; foreach (MapTextureStage maptexturestage in maptexturestages) { totaltexturestagesneeded += maptexturestage.NumTextureStagesRequired; } multipass = false; if (totaltexturestagesneeded > maxtexels) { multipass = true; } rendererpasses = new List <RendererPass>(); //maxtexels = 2; //int currenttexel = 0; multipass = true; // force multipass for now for simplicity if (multipass) { for (int i = 0; i < maptexturestages.Count; i++) { MapTextureStage maptexturestage = maptexturestages[i]; int numtexturestagesrequired = maptexturestage.NumTextureStagesRequired; if (numtexturestagesrequired > 0) // exclude Nops { RendererPass rendererpass = new RendererPass(maxtexels); for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++) { rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, width, height)); } rendererpasses.Add(rendererpass); } } } }