java - Applying map of the earth texture a Sphere -
i been trying implement 3d animation in opengl (using jogl) of solar system far have 5 planets of different sizes problem seem having cant add map of earth texture on sphere can me on how done?
this code have far in display method:
@override public void display(glautodrawable drawable) { gl2 gl = drawable.getgl().getgl2(); glu glu = new glu(); gl.glclear(gl.gl_color_buffer_bit); //make sure in model_view mode gl.glmatrixmode(gl2.gl_modelview); gl.glloadidentity(); glu.glulookat(10,20,20,0,3,0,0, 20, 0); //gl.glmatrixmode(gl2.gl_projection); //glu.gluperspective(45,1,1,25); //render ground plane gl.glpushmatrix(); gl.gltranslatef(-10.75f, 3.0f, -1.0f); gl.glcolor3f(0.3f, 0.5f, 1f); gluquadric earth = glu.glunewquadric(); glu.gluquadricdrawstyle(earth, glu.glu_fill); glu.gluquadricnormals(earth, glu.glu_flat); glu.gluquadricorientation(earth, glu.glu_outside); final float radius = 3.378f; final int slices = 89; final int stacks = 16; glu.glusphere(earth, radius, slices, stacks); glu.gludeletequadric(earth); texture earths; try { earths = textureio.newtexture(new file("earth.png"), true); } catch (ioexception e) { javax.swing.joptionpane.showmessagedialog(null, e); } gl.glpopmatrix(); //gl.glend(); gl.glpushmatrix(); gl.gltranslatef(2.75f, 3.0f, -0.0f); gl.glcolor3f(0.3f, 0.5f, 1f); gluquadric earth1 = glu.glunewquadric(); glu.gluquadricdrawstyle(earth1, glu.glu_fill); glu.gluquadricnormals(earth1, glu.glu_flat); glu.gluquadricorientation(earth1, glu.glu_outside); final float radius1 = 3.378f; final int slices1 = 90; final int stacks1 = 63; glu.glusphere(earth1, radius1, slices1, stacks1); glu.gludeletequadric(earth1); gl.glpopmatrix(); gl.glpushmatrix(); gl.gltranslatef(3.75f, 6.0f, -7.20f); gl.glcolor3f(0.3f, 0.5f, 1f); gluquadric earth3 = glu.glunewquadric(); glu.gluquadricdrawstyle(earth3, glu.glu_fill); glu.gluquadricnormals(earth3, glu.glu_flat); glu.gluquadricorientation(earth1, glu.glu_outside); final float radius3 = 1.878f; final int slices3 = 89; final int stacks3 = 16; glu.glusphere(earth3, radius3, slices3, stacks3); glu.gludeletequadric(earth3); gl.glpopmatrix(); gl.glpushmatrix(); gl.gltranslatef(12.75f, 2.0f, -7.20f); gl.glcolor3f(0.3f, 0.5f, 1f); gluquadric earth4 = glu.glunewquadric(); glu.gluquadricdrawstyle(earth4, glu.glu_fill); glu.gluquadricnormals(earth4, glu.glu_flat); glu.gluquadricorientation(earth4, glu.glu_outside); final float radius4 = 1.078f; final int slices4 = 89; final int stacks4 = 16; glu.glusphere(earth4, radius4, slices4, stacks4); glu.gludeletequadric(earth4); gl.glpopmatrix(); gl.glpushmatrix(); gl.gltranslatef(2.75f, -6.0f, -0.0f); gl.glcolor3f(0.3f, 0.5f, 1f); gluquadric earth5 = glu.glunewquadric(); glu.gluquadricdrawstyle(earth5, glu.glu_fill); glu.gluquadricnormals(earth5, glu.glu_flat); glu.gluquadricorientation(earth5, glu.glu_outside); final float radius5 = 3.778f; final int slices5 = 90; final int stacks5 = 63; glu.glusphere(earth5, radius5, slices5, stacks5); glu.gludeletequadric(earth5); gl.glpopmatrix(); }
create own sphere mesh
simple 2d loop through 2 angles (spherical coordinate system 2 cartesian). can add ellipsoid properties (earth not sphere) if want more precision. if not can use single sphere mesh planets , scale before use ...
let
alongitude ,blatitude loopa02*pi[rad] ,b-0.5*pi+0.5*pi[rad]pi=3.1415...pi (in c++ math.h calledm_pi). if math api uses degrees convert degreespi [rad] = 180.0 [deg]add necessary info per vertex
normals lighting
// unit sphere nx=cos(b)*cos(a); ny=cos(b)*sin(a); nz=sin(b);texture coordinate (assuming rectangle non distorted image)
// convert a,b <0,1> range tx=a/(2.0*pi) ty=(b/pi)+0.5;vertex position
// sphere(rx=ry=rz=r) or ellipsoid (rx=ry=equatorial , rz=polar radius) // can use rx*nx,ry*ny,rz*nz instead ... x=rx*cos(b)*cos(a); y=ry*cos(b)*sin(a); z=rz*sin(b);send of opengl
so above store in memory space (cpu or gpu) , send rendering. can use legacy
glbegin(quad_strip); ... glend();or displaylist/vbo/vao. bind right texture before each planet/body , not forget updatemodelviewmatrix too. how mine coordinate systems looks like:
also have @ these related q/as:
[edit1] c++ example
//--------------------------------------------------------------------------- const int nb=15; // slices const int na=nb<<1; // points per equator class planet { public: bool _init; // has been initiated ? glfloat x0,y0,z0; // center of planet [gcs] glfloat pos[na][nb][3]; // vertex glfloat nor[na][nb][3]; // normal glfloat txr[na][nb][2]; // texcoord gluint txrid; // texture id glfloat t; // dayly rotation angle [deg] planet() { _init=false; txrid=0; x0=0.0; y0=0.0; z0=0.0; t=0.0; } ~planet() { if (_init) gldeletetextures(1,&txrid); } void init(glfloat r,ansistring texture); // call after opengl working !!! void draw(); }; void planet::init(glfloat r,ansistring texture) { if (!_init) { _init=true; glgentextures(1,&txrid); } glfloat x,y,z,a,b,da,db; glfloat tx0,tdx,ty0,tdy;// correction if clamp_to_edge not available int ia,ib; // a,b texture coordinate system tx0=0.0; ty0=0.5; tdx=0.5/m_pi; tdy=1.0/m_pi; // load texture gpu memory if (texture!="") { byte q; unsigned int *pp; int xs,ys,x,y,adr,*txr; union { unsigned int c32; byte db[4]; } c; graphics::tbitmap *bmp=new graphics::tbitmap; // new bmp bmp->loadfromfile(texture); // load file bmp->handletype=bmdib; // allow direct access pixels bmp->pixelformat=pf32bit; // set pixel 32bit int same size pixel xs=bmp->width; // resolution should power of 2 ys=bmp->height; txr=new int[xs*ys]; for(adr=0,y=0;y<ys;y++) { pp=(unsigned int*)bmp->scanline[y]; for(x=0;x<xs;x++,adr++) { // rgb2bgr , copy bmp -> txr[] c.c32=pp[x]; q =c.db[2]; c.db[2]=c.db[0]; c.db[0]=q; txr[adr]=c.c32; } } glenable(gl_texture_2d); glbindtexture(gl_texture_2d,txrid); glpixelstorei(gl_unpack_alignment, 4); gltexparameteri(gl_texture_2d, gl_texture_wrap_s,gl_clamp); gltexparameteri(gl_texture_2d, gl_texture_wrap_t,gl_clamp); gltexparameteri(gl_texture_2d, gl_texture_mag_filter,gl_linear); gltexparameteri(gl_texture_2d, gl_texture_min_filter,gl_linear); gltexenvf(gl_texture_env, gl_texture_env_mode,gl_modulate); glteximage2d(gl_texture_2d, 0, gl_rgba, xs, ys, 0, gl_rgba, gl_unsigned_byte, txr); gldisable(gl_texture_2d); delete bmp; delete[] txr; // texture coordinates 1 pixel each edge (gl_clamp_to_edge) tx0+=1.0/glfloat(xs); ty0+=1.0/glfloat(ys); tdx*=glfloat(xs-2)/glfloat(xs); tdy*=glfloat(ys-2)/glfloat(ys); } // correct texture coordinate system (invert x) tx0=1.0-tx0; tdx=-tdx; da=(2.0*m_pi)/glfloat(na-1); db= m_pi /glfloat(nb-1); (ib=0,b=-0.5*m_pi;ib<nb;ib++,b+=db) (ia=0,a= 0.0 ;ia<na;ia++,a+=da) { x=cos(b)*cos(a); y=cos(b)*sin(a); z=sin(b); nor[ia][ib][0]=x; nor[ia][ib][1]=y; nor[ia][ib][2]=z; pos[ia][ib][0]=r*x; pos[ia][ib][1]=r*y; pos[ia][ib][2]=r*z; txr[ia][ib][0]=tx0+(a*tdx); txr[ia][ib][1]=ty0+(b*tdy); } } void planet::draw() { if (!_init) return; int ia,ib0,ib1; glmatrixmode(gl_modelview); glpushmatrix(); glloadidentity(); gltranslatef(x0,y0,z0); glrotatef(90.0,1.0,0.0,0.0); // rotate planets z axis (north) opengl y axis (up) glrotatef(-t,0.0,0.0,1.0); // rotate planets z axis (north) opengl y axis (up) glenable(gl_texture_2d); glbindtexture(gl_texture_2d,txrid); glcolor3f(1.0,1.0,1.0); (ib0=0,ib1=1;ib1<nb;ib0=ib1,ib1++) { glbegin(gl_quad_strip); (ia=0;ia<na;ia++) { glnormal3fv (nor[ia][ib0]); gltexcoord2fv(txr[ia][ib0]); glvertex3fv (pos[ia][ib0]); glnormal3fv (nor[ia][ib1]); gltexcoord2fv(txr[ia][ib1]); glvertex3fv (pos[ia][ib1]); } glend(); } gldisable(gl_texture_2d); glmatrixmode(gl_modelview); glpopmatrix(); } //--------------------------------------------------------------------------- usage:
// variable store planet (global) planet earth; // init after opengl initialisation earth.init(1.0,"earth.bmp"); // position update earth.x0= 0.0; earth.y0= 0.0; earth.z0=-20.0; // add render loop earth.draw(); // draws planet earth.t+=2.5; // rotate planet 2.5 deg each frame... i know ugly not use funny stuff legacy opengl , math.h (cos(),sin(),m_pi) , vcl bitmap loading. rewrite environment , fine. not forget each planet has own texture need have 1 txrid per planet either have each planet separate planet variable or rewrite ...



Comments
Post a Comment