Spherical Heightmap
in
Contributed Library Questions
•
2 years ago
Hi!
I'm trying to add a heightmap to a sphere with an GLModel since I need quite a lot of vertices to render a somewhat realistic model of Mars. (the one below has 250.000 vertices, although im planning to use 10.000 in the final version through the use of a normal map).
I started out using the TexturedSphere example from GLGraphics but quickly switched out the calcCoords() function for my own which uses cartesian coordinates. Except I get this, admittely funky looking, line drawing as of now.
Does anyone now how to get it right?
- import processing.opengl.*;
- import codeanticode.glgraphics.*;
- import javax.media.opengl.*;
- int globeDetail = 100;
- float rotationX = 0.0f,
- rotationY = 0.0f,
- velocityX = 0.0f,
- velocityY = 0.0f,
- globeRadius = 450.0f,
- distance = 20000.0f;
- String globeMapName = "mars_6k_color.jpg";
- PImage globeHeight;
- ArrayList vertices = new ArrayList(),
- texCoords = new ArrayList(),
- normals = new ArrayList();
- PFont font;
- GLModel mars;
- GLTexture tex;
- public void setup() {
- size(screen.width, screen.height, GLConstants.GLGRAPHICS);
- hint(ENABLE_OPENGL_4X_SMOOTH);
- font = loadFont("LucidaSansUnicode.vlw");
- globeHeight = loadImage("mars_6k_topo.jpg");
- setupSphere();
- mars = new GLModel(this, vertices.size(), TRIANGLE_STRIP, GLModel.STATIC);
- mars.updateVertices(vertices);
- tex = new GLTexture(this, globeMapName);
- mars.initTextures(1);
- mars.setTexture(0, tex);
- mars.updateTexCoords(0, texCoords);
- mars.initNormals();
- mars.updateNormals(normals);
- mars.initColors();
- mars.setColors(255);
- mars.setShininess(100);
- }
- public void draw() {
- background(0);
- GLGraphics renderer = (GLGraphics)g;
- renderer.beginGL();
- renderer.gl.glEnable(GL.GL_LIGHTING);
- renderer.gl.glEnable(GL.GL_LIGHT0);
- renderer.gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, new float[]{0.1,0.1,0.1,1}, 0);
- renderer.gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[]{0.9,0.9,0.9,1}, 0);
- renderer.gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] {1000, -600, 400, 0 }, 0);
- renderer.gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, new float[] { 1, 1, 1, 0.75 }, 1);
- translate(width/2, height/2, 0);
- pushMatrix();
- rotateX(radians(rotationX));
- rotateY(radians(270 - rotationY));
- renderer.model(mars);
- popMatrix();
- renderer.endGL();
- rotationX += velocityX;
- rotationY += velocityY;
- velocityX *= 0.95;
- velocityY *= 0.95;
- if (mousePressed) {
- velocityX += -(mouseY-pmouseY) * 0.01;
- velocityY -= (mouseX-pmouseX) * 0.01;
- }
- }
- public void setupSphere(){
- float[] grid = new float[globeDetail+1];
- for(int i = 0; i <= globeDetail; i++){
- grid[i]= i / (float) globeDetail;
- }
- for(int i = 0; i <= globeDetail; i++){
- for(int j = 0; j <= globeDetail; j++){
- calcPoint(grid[i], grid[j]);
- }
- }
- }
- void calcPoint(float x, float y){
- float phi = x*2*PI;
- float theta = PI - y*PI;
- int nx = (int) map(x, 0, 1, 0, globeHeight.width);
- int ny = (int) map(y, 0, 1, 0, globeHeight.height);
- int index = nx+ny*globeHeight.width;
- float h = 0;
- try {
- h = brightness(globeHeight.pixels[index])/10;
- } catch(ArrayIndexOutOfBoundsException e) {}
- float mx = (globeRadius+h)*sin(theta)*cos(phi);
- float my = (globeRadius+h)*sin(theta)*sin(phi);
- float mz = (globeRadius+h)*cos(theta);
- addVertex(mx, my, mz, x, y);
- }
- void addVertex(float x, float y, float z, float u, float v) {
- PVector vert = new PVector(x, y, z);
- PVector texCoord = new PVector(u, v);
- PVector vertNorm = PVector.div(vert, vert.mag());
- vertices.add(vert);
- texCoords.add(texCoord);
- normals.add(vertNorm);
- }
1