3D模拟自然——山体
2016-05-11 23:31
429 查看
算法上使用分形插值算法。渲染上,效率和扩展性中最理想的是用shader,但为了方便也可以用封装好的pixmap或shapeRenderer。这里用pixmap来绘制3d山。值得一提,1.6.1API:Color.toIntBits(int r,int g,int b,int a)是错的,参数位置前后倒了,导致山体一片红,所以顺着对的修改完毕。可以重置,修改blend模式以及精细程度。
以下是代码和效果图。
(可以看到n值为2倍后内存消耗增加不止1倍,渲染算法上是需要改进的)
以下是代码和效果图。
(可以看到n值为2倍后内存消耗增加不止1倍,渲染算法上是需要改进的)
package indi.dawn.ff.work; import java.util.StringTokenizer; import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Blending; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.utils.Disposable; class MountainC extends Actor implements Disposable{ ShapeRenderer jj; int n = 32, n1, h,w,h2,w2, mx0,my0, xPol[],yPol[], iCol[][][]; double rnd, fiX = .2, fiY = .3, dfi = .01, scale = .8, m20,m21,m22; double vert[][][], vert1[][][], Norm[][][][], Norm1z[][][], M[]; Color col[][]; boolean painted; Texture buffImage;Pixmap buffGraphics; InputListener ip; public MountainC(){ ip=new InputListener(){ @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { // TODO Auto-generated method stub mx0 = (int) x; my0 = (int) y; if ( Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) ){ setup(); // repaint(); } if ( Gdx.input.isKeyPressed(Input.Keys.ALT_LEFT) ){ if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) ){ n /= 2; if (n < 1) n = 1;} else n *= 2; setup(); // repaint(); } if(Gdx.app.getType()==ApplicationType.Android){ if (pointer==1){ n *= 2; setup(); // repaint(); } if (pointer==2 ) { n /= 2; if (n < 1) n = 1;} } return true; } @Override public void touchDragged(InputEvent event, float x, float y, int pointer) { // TODO Auto-generated method stub int x1 = (int) x; int y1 = (int) y; if ( Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) ) scale *= Math.exp(-(y1 - my0)/(double)w); else fiX += dfi*(y1 - my0); fiY += dfi*(x1 - mx0); mx0 = x1; my0 = y1; rotate(); // repaint(); } }; init(); /*for(int i=0;i<4;i++){ for(Color c:col[i]){ System.out.println(c.toIntBits()); } }*/ } private Color calCol(int r,int g,int b){ return new Color(Color.toIntBits(255, b, g, r)); }; int getN(){ return 32; } Color getCol(){ return Color.WHITE; } Color bgColor; int pmWidth=600,pmHeight=800; public void init(){ // w=(int) getWidth();h=(int) getHeight(); w = pmWidth; h = pmHeight; w2 = w/2; h2 = h/2; // n=getN(); xPol = new int[3]; yPol = new int[3]; buffGraphics=new Pixmap(w, h, Pixmap.Format.RGB888); // buffGraphics.setBlending(Blending.SourceOver); buffImage= new Texture(buffGraphics); col = new Color[4][256]; for (int i = 0; i < 256; i++){ col[0][i] = calCol(0, 0, i); col[1][i] = calCol(0, (i*220)/256, 0); col[2][i] = calCol((i*150)/256, (i*150)/256, (i*50)/256); col[3][i] = calCol(i, i, i);} for(int i=0;i<4;i++){ for(Color c:col[i]){ System.out.println(c); } } bgColor=getCol(); if(bgColor==null) bgColor=Color.WHITE; addListener(ip); setup(); } public double R(){ return rnd*(Math.random()-.5);} public void setup(){ rnd = 1; n1 = n+1; iterate(); vert = new double[n1][n1][3]; vert1 = new double[n1][n1][2]; double dx = w/(double)n; int t = 0; for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){ vert[i][j][0] = dx*i - w2; vert[i][j][2] = dx*j - w2; double mi = M[t++]; if (mi < 0) mi = .01*Math.random(); vert[i][j][1] = w*mi - w2/2;} Norm = new double[n1][n1][2][3]; Norm1z = new double[n1][n1][2]; iCol = new int [2]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++){ double s = ((vert[i][j][1] + vert[i+1][j][1] + vert[i+1][j+1][1])/3 + w2/2)/w; if (s < .01) iCol[i][j][0] = 0; else if (s+.1*Math.random() > .35) iCol[i][j][0] = 3; else if (s+.1*Math.random() > .15) iCol[i][j][0] = 2; else iCol[i][j][0] = 1; s = ((vert[i][j][1] + vert[i][j+1][1] + vert[i+1][j+1][1])/3 + w2/2)/w; if (s < .01) iCol[i][j][1] = 0; else if (s+.1*Math.random() > .35) iCol[i][j][1] = 3; else if (s+.1*Math.random() > .15) iCol[i][j][1] = 2; else iCol[i][j][1] = 1; Norm[i][j][0][0] = vert[i][j][1] - vert[i+1][j][1]; Norm[i][j][0][1] = dx; Norm[i][j][0][2] = vert[i+1][j][1] - vert[i+1][j+1][1]; double mod = Math.sqrt(Norm[i][j][0][0]*Norm[i][j][0][0] + Norm[i][j][0][1]* Norm[i][j][0][1] + Norm[i][j][0][2]*Norm[i][j][0][2]) / 255.5; Norm[i][j][0][0] /= mod; Norm[i][j][0][1] /= mod; Norm[i][j][0][2] /= mod; Norm[i][j][1][0] = vert[i][j+1][1] - vert[i+1][j+1][1]; Norm[i][j][1][1] = dx; Norm[i][j][1][2] = vert[i][j][1] - vert[i][j+1][1]; mod = Math.sqrt(Norm[i][j][1][0]*Norm[i][j][1][0] + Norm[i][j][1][1]* Norm[i][j][1][1] + Norm[i][j][1][2]*Norm[i][j][1][2]) / 255.5; Norm[i][j][1][0] /= mod; Norm[i][j][1][1] /= mod; Norm[i][j][1][2] /= mod;} rotate(); } public void iterate(){ int nc=n, Max=n1*n1, ncn1; double Min=-1; M = new double[Max]; for (int i=n+2; i < n*n1-1; i++) M[i] = Min; for (int i=2*n1; i < n*n1; i += n1) M[i] = M[i-1] = 0; while ( (nc /= 2) >= 1){ ncn1 = nc*n1; for (int j=ncn1; j < Max; j += ncn1+ncn1){ for (int i= nc; i < n; i += nc+nc){ if (M[i+j]==Min) M[i+j] = (M[i+j+nc-ncn1] + M[i+j-nc+ncn1])/2.+R(); if (M[i+j+nc]==Min) M[i+j+nc] = (M[i+j+nc+ncn1] + M[i+j+nc-ncn1])/2.+R(); if (M[i+j+ncn1]==Min) M[i+j+ncn1] = (M[i+j-nc+ncn1] + M[i+j+nc+ncn1])/2.+R(); }} rnd /= 2.;} } public void rotate(){ double ct = Math.cos(fiX), cf = Math.cos(fiY), st = Math.sin(fiX), sf = Math.sin(fiY), m00 = scale*cf, m02 = scale*sf, m10 = scale*st*sf, m11 = scale*ct, m12 = -scale*st*cf; m20 = -ct*sf; m21 = st; m22 = ct*cf; for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){ vert1[i][j][0] = m00*vert[i][j][0] + m02*vert[i][j][2]; vert1[i][j][1] = m10*vert[i][j][0] + m11*vert[i][j][1] + m12*vert[i][j][2];} for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (int k = 0; k < 2; k++) Norm1z[i][j][k] = m20*Norm[i][j][k][0] + m21*Norm[i][j][k][1] + m22*Norm[i][j][k][2]; painted = false; } @Override public void draw(Batch batch, float parentAlpha) { // TODO Auto-generated method stub if ( !painted ){ if(buffImage!=null){ buffImage.dispose(); buffImage=null; /* buffGraphics.dispose(); buffGraphics=new Pixmap(w, h, Format.RGB888);*/ } // buffGraphics.dispose(); // Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); buffGraphics.setColor(Color.WHITE); buffGraphics.fill(); int ib=0, ie=n, sti=1, jb=0, je=n, stj=1; if (m20 < 0){ ib = n; ie = -1; sti = -1;} if (m22 < 0){ jb = n; je = -1; stj = -1;} for (int i = ib; i != ie; i += sti) for (int j = jb; j != je; j += stj){ if (Norm1z[i][j][0] > 0){ xPol[0] = w2 + (int)vert1[i][j][0]; xPol[1] = w2 + (int)vert1[i+1][j][0]; xPol[2] = w2 + (int)vert1[i+1][j+1][0]; yPol[0] = h2 - (int)vert1[i][j][1]; yPol[1] = h2 - (int)vert1[i+1][j][1]; yPol[2] = h2 - (int)vert1[i+1][j+1][1]; System.out.println(iCol[i][j][0]+"?"+(int)(Norm1z[i][j][0])); System.out.println(col[iCol[i][j][0]][(int)(Norm1z[i][j][0])].toString()); buffGraphics.setColor(col[iCol[i][j][0]][(int)(Norm1z[i][j][0])]); buffGraphics.fillTriangle(xPol[0], yPol[0], xPol[1], yPol[1], xPol[2], yPol[2]); // buffGraphics.fillPolygon(xPol,yPol, 3); } if (Norm1z[i][j][1] > 0){ xPol[0] = w2 + (int)vert1[i][j][0]; xPol[1] = w2 + (int)vert1[i][j+1][0]; xPol[2] = w2 + (int)vert1[i+1][j+1][0]; yPol[0] = h2 - (int)vert1[i][j][1]; yPol[1] = h2 - (int)vert1[i][j+1][1]; yPol[2] = h2 - (int)vert1[i+1][j+1][1]; buffGraphics.setColor(col[iCol[i][j][1]][(int)(Norm1z[i][j][1])]); buffGraphics.fillTriangle(xPol[0], yPol[0], xPol[1], yPol[1], xPol[2], yPol[2]);} } painted = true; buffImage=new Texture(buffGraphics, true); } // Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.draw(buffImage, getX(), getY()); /*if(!painted){ buffGraphics.setColor(col(255, 0, 0)); buffGraphics.fill(); buffImage=new Texture(buffGraphics); painted = true; }batch.draw(buffImage, getX(), getY());*/ // g.drawImage(buffImage, 0, 0, this); } @Override public void dispose() { // TODO Auto-generated method stub buffGraphics.dispose(); buffImage.dispose(); } /***************************************************/ /*public void init2(){ w = getSize().width; h = getSize().height; w2 = w/2; h2 = h/2; String s=getParameter("N"); if (s != null) n = Integer.parseInt(s); xPol = new int[3]; yPol = new int[3]; buffImage = createImage(w, h); buffGraphics = buffImage.getGraphics(); col = new Color[4][256]; for (int i = 0; i < 256; i++){ col[0][i] = new Color(0, 0, i); col[1][i] = new Color(0, (i*220)/256, 0); col[2][i] = new Color((i*150)/256, (i*150)/256, (i*50)/256); col[3][i] = new Color(i, i, i);} s = getParameter("bgColor"); if (s != null){ StringTokenizer st = new StringTokenizer(s); int red = Integer.parseInt(st.nextToken()); int green = Integer.parseInt(st.nextToken()); int blue = Integer.parseInt(st.nextToken()); setBackground( new Color(red, green, blue));} else setBackground(new Color(255,255,255)); addMouseListener(this); addMouseMotionListener(this); setup(); for(int i=0;i<4;i++){ for(Color c:col[i]){ int a=c.getRed(); int b=c.getGreen(); int g=c.getBlue(); int r= c.getAlpha(); int m=(a << 24) | (b << 16) | (g << 8) | r; System.out.println(m); } } }*/ public void rotate2(){ double ct = Math.cos(fiX), cf = Math.cos(fiY), st = Math.sin(fiX), sf = Math.sin(fiY), m00 = scale*cf, m02 = scale*sf, m10 = scale*st*sf, m11 = scale*ct, m12 = -scale*st*cf; m20 = -ct*sf; m21 = st; m22 = ct*cf; for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){ vert1[i][j][0] = m00*vert[i][j][0] + m02*vert[i][j][2]; vert1[i][j][1] = m10*vert[i][j][0] + m11*vert[i][j][1] + m12*vert[i][j][2];} for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (int k = 0; k < 2; k++) Norm1z[i][j][k] = m20*Norm[i][j][k][0] + m21*Norm[i][j][k][1] + m22*Norm[i][j][k][2]; painted = false; } public void iterate2(){ int nc=n, Max=n1*n1, ncn1; double Min=-1; M = new double[Max]; for (int i=n+2; i < n*n1-1; i++) M[i] = Min; for (int i=2*n1; i < n*n1; i += n1) M[i] = M[i-1] = 0; while ( (nc /= 2) >= 1){ ncn1 = nc*n1; for (int j=ncn1; j < Max; j += ncn1+ncn1){ for (int i= nc; i < n; i += nc+nc){ if (M[i+j]==Min) M[i+j] = (M[i+j+nc-ncn1] + M[i+j-nc+ncn1])/2.+R(); if (M[i+j+nc]==Min) M[i+j+nc] = (M[i+j+nc+ncn1] + M[i+j+nc-ncn1])/2.+R(); if (M[i+j+ncn1]==Min) M[i+j+ncn1] = (M[i+j-nc+ncn1] + M[i+j+nc+ncn1])/2.+R(); }} rnd /= 2.;} } public void setup2(){ rnd = 1; n1 = n+1; iterate(); vert = new double[n1][n1][3]; vert1 = new double[n1][n1][2]; double dx = w/(double)n; int t = 0; for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){ vert[i][j][0] = dx*i - w2; vert[i][j][2] = dx*j - w2; double mi = M[t++]; if (mi < 0) mi = .01*Math.random(); vert[i][j][1] = w*mi - w2/2;} Norm = new double[n1][n1][2][3]; Norm1z = new double[n1][n1][2]; iCol = new int [2]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++){ double s = ((vert[i][j][1] + vert[i+1][j][1] + vert[i+1][j+1][1])/3 + w2/2)/w; if (s < .01) iCol[i][j][0] = 0; else if (s+.1*Math.random() > .35) iCol[i][j][0] = 3; else if (s+.1*Math.random() > .15) iCol[i][j][0] = 2; else iCol[i][j][0] = 1; s = ((vert[i][j][1] + vert[i][j+1][1] + vert[i+1][j+1][1])/3 + w2/2)/w; if (s < .01) iCol[i][j][1] = 0; else if (s+.1*Math.random() > .35) iCol[i][j][1] = 3; else if (s+.1*Math.random() > .15) iCol[i][j][1] = 2; else iCol[i][j][1] = 1; Norm[i][j][0][0] = vert[i][j][1] - vert[i+1][j][1]; Norm[i][j][0][1] = dx; Norm[i][j][0][2] = vert[i+1][j][1] - vert[i+1][j+1][1]; double mod = Math.sqrt(Norm[i][j][0][0]*Norm[i][j][0][0] + Norm[i][j][0][1]* Norm[i][j][0][1] + Norm[i][j][0][2]*Norm[i][j][0][2]) / 255.5; Norm[i][j][0][0] /= mod; Norm[i][j][0][1] /= mod; Norm[i][j][0][2] /= mod; Norm[i][j][1][0] = vert[i][j+1][1] - vert[i+1][j+1][1]; Norm[i][j][1][1] = dx; Norm[i][j][1][2] = vert[i][j][1] - vert[i][j+1][1]; mod = Math.sqrt(Norm[i][j][1][0]*Norm[i][j][1][0] + Norm[i][j][1][1]* Norm[i][j][1][1] + Norm[i][j][1][2]*Norm[i][j][1][2]) / 255.5; Norm[i][j][1][0] /= mod; Norm[i][j][1][1] /= mod; Norm[i][j][1][2] /= mod;} rotate(); } }
相关文章推荐
- Android开发笔记之简易音乐播放器
- jenkins的svn路径中文问题
- java数据类型值的注意的地方
- Python学习---day 1
- Linux-常用命令
- SpringMVC处理Form表单
- Lightoj 1248 概率dp
- 网址
- OpenCV学习笔记大集锦
- 切换文字颜色
- 国际化java.util.MissingResourceException: Can't find bundle for base name message报错
- 链队列的C/C++实现
- Maven简单了解
- hibernateTemplate.delete(t);删除不了语句,没有生成sql语句
- 配置redis外网可访问
- jquery mobile(jm)关于数据的动态交互问题-提交数据关闭ajax
- 第五次c++作业——代码篇
- bzoj 4403 序列统计 卢卡斯定理
- 101_自定义FastJsonRequest
- bzoj4518【SDOI2016】征途