LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: msacco on June 18, 2018, 14:30:14

Title: Texturing a sphere
Post by: msacco on June 18, 2018, 14:30:14
I'd like to get some help with texturing a 3d sphere, Im using the following code to draw a sphere:

public static void testing() {
final float PI = 3.141592f;
float x, y, z, alpha, beta; // Storage for coordinates and angles
float radius = 60f;
int gradation = 20;
for (alpha = 0.0f; alpha < PI; alpha += PI / gradation) {
glBegin(GL_TRIANGLE_STRIP);
for (beta = 0.0f; beta < 2.01 * PI; beta += PI / gradation) {
x = (float) (radius * Math.cos(beta) * Math.sin(alpha));
y = (float) (radius * Math.sin(beta) * Math.sin(alpha));
z = (float) (radius * Math.cos(alpha));
glVertex3f(x, y, z);
x = (float) (radius * Math.cos(beta) * Math.sin(alpha + PI / gradation));
y = (float) (radius * Math.sin(beta) * Math.sin(alpha + PI / gradation));
z = (float) (radius * Math.cos(alpha + PI / gradation));
glVertex3f(x, y, z);
}
glEnd();
}
}


The 3d sphere works just as it should, but I just don't really understand how to draw the texture on to it, I used slick utils to load the texture etc, and I manage to texture the sphere, but not really the way I need it to, how do I match/map the texture to the model? do I need to use glTexCoord2f go each glVertex3f? how does that work exactly? And how does the glVertex3f really works? Thanks.
Title: Re: Texturing a sphere
Post by: msacco on June 19, 2018, 11:05:15
Anyone? :\
Title: Re: Texturing a sphere
Post by: mudlee on June 19, 2018, 13:42:59
I would recommend you three resources:


When I learnt opengl, I used these resources mainly and the opengl red book: https://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0134495497/ref=sr_1_1?s=books&ie=UTF8&qid=1529415776&sr=1-1&keywords=opengl+programming+guide (https://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0134495497/ref=sr_1_1?s=books&ie=UTF8&qid=1529415776&sr=1-1&keywords=opengl+programming+guide)
Title: Re: Texturing a sphere
Post by: msacco on June 19, 2018, 14:36:56
Quote from: mudlee on June 19, 2018, 13:42:59
I would recommend you three resources:


  • https://learnopengl.com/Getting-started/Textures (https://learnopengl.com/Getting-started/Textures) - it's c++, but the opengl stuff is the same
  • https://ahbejarano.gitbook.io/lwjglgamedev/textures (https://ahbejarano.gitbook.io/lwjglgamedev/textures) - it's based on LWJGL 3, but again, the opengl part is the same
  • https://www.youtube.com/watch?v=SPt-aogu72A (https://www.youtube.com/watch?v=SPt-aogu72A) - same as above

When I learnt opengl, I used these resources mainly and the opengl red book: https://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0134495497/ref=sr_1_1?s=books&ie=UTF8&qid=1529415776&sr=1-1&keywords=opengl+programming+guide (https://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0134495497/ref=sr_1_1?s=books&ie=UTF8&qid=1529415776&sr=1-1&keywords=opengl+programming+guide)

I already tried those, but Im trying to texture a 3d sphere, which is like a lot of small triangles and Im trying to texture it with an earth or sun texture for example, but I don't know how to wrap it, because its not like a square where you just have to put the corner vertices..so I have no idea what to do :\
Title: Re: Texturing a sphere
Post by: mudlee on June 19, 2018, 17:46:04
I see, sorry. I would recommend to ask this on http://www.java-gaming.org/ (http://www.java-gaming.org/) as well.
Title: Re: Texturing a sphere
Post by: msacco on June 19, 2018, 17:46:32
Quote from: mudlee on June 19, 2018, 17:46:04
I see, sorry. I would recommend to ask this on http://www.java-gaming.org/ (http://www.java-gaming.org/) as well.

I will, thank you :)
Title: Re: Texturing a sphere
Post by: KaiHH on June 19, 2018, 18:53:47
First, you need a suitable projection of a spherical surface onto a 2D surface. Most people and also most textures you find use equirectangular projection (https://en.wikipedia.org/wiki/Equirectangular_projection). So there is that.

Next you need to know that texture coordinates in OpenGL are in the range ([0..1], [0..1]). So you need to map the texture coordinates in the range from zero to one in both dimensions u and v (also called 's' and 't') onto the sphere.

Equirectangular projection is suitable for you since it can simply use longitude/latitude angles, just like you are currently using to generate the 3D vertex positions in cartesian space.

So, try the following directly before the first glVertex3f call:

glTexCoord2f(beta / (2.0f * PI), alpha / PI);


And the following directly before the second glVertex3f call:

glTexCoord2f(beta / (2.0f * PI) + 0.5f / gradation, alpha / PI + 1.0f / gradation);
Title: Re: Texturing a sphere
Post by: msacco on June 19, 2018, 19:50:44
Quote from: KaiHH on June 19, 2018, 18:53:47
First, you need a suitable projection of a spherical surface onto a 2D surface. Most people and also most textures you find use equirectangular projection (https://en.wikipedia.org/wiki/Equirectangular_projection). So there is that.

Next you need to know that texture coordinates in OpenGL are in the range ([0..1], [0..1]). So you need to map the texture coordinates in the range from zero to one in both dimensions u and v (also called 's' and 't') onto the sphere.

Equirectangular projection is suitable for you since it can simply use longitude/latitude angles, just like you are currently using to generate the 3D vertex positions in cartesian space.

So, try the following directly before the first glVertex3f call:

glTexCoord2f(beta / (2.0f * PI), alpha / PI);


And the following directly before the second glVertex3f call:

glTexCoord2f(beta / (2.0f * PI) + 0.5f / gradation, alpha / PI + 1.0f / gradation);


Amazing! Thank you so much! I've been trying to work it out for a few days now with no success. It works perfectly with my sun texture, but there's a small problem with my earth texture, tho Im not sure if its something with the code or the actual earth texture, but I downloaded it from a very reliable source(aka: http://planetpixelemporium.com/earth.html).
Thats how it looks like with the earth texture:
https://imgur.com/s0pn0Oy

I think I managed to fix it by changing both of the lines to 2.07f * PI instead of 2.0f, and it seems to be working now, but I don't think thats how it should work, do you have any ideas why it happens?
One more thing, when looking close at the texture it looks like this:
https://imgur.com/lUpLg9K

Is that the way it supposed to be? or is there a way to make it smoother? It seems that when lowering the graduation the gaps appears to be bigger and bigger, thats with graduation of 20 for example:
https://imgur.com/yZIjYc8

I assume Im doing something wrong in the code, thanks a lot for the help anyway!!

Title: Re: Texturing a sphere
Post by: KaiHH on June 19, 2018, 20:06:03
Oh, sorry, by bad. The second call has to be:

glTexCoord2f(beta / (2.0f * PI), alpha / PI + 1.0f / gradation);
Title: Re: Texturing a sphere
Post by: msacco on June 19, 2018, 20:15:01
Quote from: KaiHH on June 19, 2018, 20:06:03
Oh, sorry, by bad. The second call has to be:

glTexCoord2f(beta / (2.0f * PI), alpha / PI + 1.0f / gradation);


Yep, it works like a charm! The code still needs to be (2.07f * PI) in both of them for the earth texture to work properly, but I assume its something to do with the texture itself. If you know why it might happen, that would be really nice to know, as making 2 different codes for 2 different textures is ok, but code duplication is never a good thing.
Title: Re: Texturing a sphere
Post by: KaiHH on June 20, 2018, 15:13:58
The problem is the inaccuracy of the floating point arithmetic of your loops. Normally, you would not loop over the actual float angles and increment them; but you would loop over your "gradation" as integer and compute the angle from the current step, like so:

float PI = (float) Math.PI;
float x, y, z;
float radius = 60f;
int gradation = 10;
for (int j = 0; j < gradation; j++) {
  float alpha1 = (float) j / gradation * PI;
  float alpha2 = (float) (j + 1) / gradation * PI;
  for (int i = 0; i <= gradation; i++) {
    float beta = (float) i / gradation * 2.0f * PI;
    x = (float) (radius * Math.cos(beta) * Math.sin(alpha1));
    y = (float) (radius * Math.sin(beta) * Math.sin(alpha1));
    z = (float) (radius * Math.cos(alpha1));
    glTexCoord2f(beta / (2.0f * PI), alpha1 / PI);
    glVertex3f(x, y, z);
    x = (float) (radius * Math.cos(beta) * Math.sin(alpha2));
    y = (float) (radius * Math.sin(beta) * Math.sin(alpha2));
    z = (float) (radius * Math.cos(alpha2));
    glTexCoord2f(beta / (2.0f * PI), alpha2 / PI);
    glVertex3f(x, y, z);
  }
}
Title: Re: Texturing a sphere
Post by: msacco on June 20, 2018, 15:43:27
Quote from: KaiHH on June 20, 2018, 15:13:58
The problem is the inaccuracy of the floating point arithmetic of your loops. Normally, you would not loop over the actual float angles and increment them; but you would loop over your "gradation" as integer and compute the angle from the current step, like so:

float PI = (float) Math.PI;
float x, y, z;
float radius = 60f;
int gradation = 10;
for (int j = 0; j < gradation; j++) {
  float alpha1 = (float) j / gradation * PI;
  float alpha2 = (float) (j + 1) / gradation * PI;
  for (int i = 0; i <= gradation; i++) {
    float beta = (float) i / gradation * 2.0f * PI;
    x = (float) (radius * Math.cos(beta) * Math.sin(alpha1));
    y = (float) (radius * Math.sin(beta) * Math.sin(alpha1));
    z = (float) (radius * Math.cos(alpha1));
    glTexCoord2f(beta / (2.0f * PI), alpha1 / PI);
    glVertex3f(x, y, z);
    x = (float) (radius * Math.cos(beta) * Math.sin(alpha2));
    y = (float) (radius * Math.sin(beta) * Math.sin(alpha2));
    z = (float) (radius * Math.cos(alpha2));
    glTexCoord2f(beta / (2.0f * PI), alpha2 / PI);
    glVertex3f(x, y, z);
  }
}


Well the code works as well, but when Im using the earth texture I still need to change it(to 2.05f now tho). So I think its pretty clear that its a problem with my texture, as the texture dimensions are 1000x500 and are not a power of 2(I assume, I can't see any other reason for that to happen besides that).

One more unrelated question, are there any good tutorials for opengl 4 for java? Many people told me that using old opengl versions is bad because of the gpu management. Do you know anything about it? I just can't find any tutorial..Thanks.

Edit - I have changed the earth texture to 1024x512, and it works just as it should now, so yeah, it was because of the texture and power of 2.
Title: Re: Texturing a sphere
Post by: KaiHH on June 20, 2018, 17:12:40
Quote from: msacco on June 20, 2018, 15:43:27
are there any good tutorials for opengl 4 for java?
You can have a look at https://www.amazon.com/Computer-Graphics-Programming-OpenGL-Java/dp/1683920279
It uses the most modern OpenGL version at the time it was written, is specifically for Java and uses JOGL as the Java/OpenGL binding. But you can very easily adapt to LWJGL it you like it better.
The second edition of this book is due to August this year, also featuring the "quasi de-facto" Java vector/matrix standard library JOML (https://github.com/JOML-CI/JOML), so that you do not have to use the legacy OpenGL matrix stack anymore.
Title: Re: Texturing a sphere
Post by: msacco on June 20, 2018, 18:03:54
Quote from: KaiHH on June 20, 2018, 17:12:40
Quote from: msacco on June 20, 2018, 15:43:27
are there any good tutorials for opengl 4 for java?
You can have a look at https://www.amazon.com/Computer-Graphics-Programming-OpenGL-Java/dp/1683920279
It uses the most modern OpenGL version at the time it was written, is specifically for Java and uses JOGL as the Java/OpenGL binding. But you can very easily adapt to LWJGL it you like it better.
The second edition of this book is due to August this year, also featuring the "quasi de-facto" Java vector/matrix library JOML (https://github.com/JOML-CI/JOML), so that you do not have to use the legacy OpenGL matrix stack anymore.

Im already using the jogl vectors etc, its really nice and good. The book looks really good, I'll surely check it out. Just out of curiosity, and only if you really want to, because you really don't have to at all, can you show me a version of the draw sphere code using opengl 4? Cause I don't quite understand the basics, as far as people told me, you shouldn't use any opengl 1-2 methods in opengl 4. Again, only if you feel like it, its kinda something big to ask for. Thanks.
Title: Re: Texturing a sphere
Post by: KaiHH on June 20, 2018, 19:39:32
No problem. Here is a demo using the somewhat latest reasonable version of OpenGL to render a rotating, textured sphere:
  https://github.com/LWJGL/lwjgl3-demos/commit/4304297afc6275f791d8b3e2850b740b6cfcdb4f
See the Java and shader files in that commit. It uses OpenGL 3.2 Core Profile functions. There hasn't been much improvement in later OpenGL versions for such simple things as rendering a textured sphere. It's still always:
- create a vertex and (optionally) index/element buffer
- create a shader program
- setup vertex specification with these buffers and the vertex attributes imported by the shader program
- enable/bind shader
- call draw functions
Title: Re: Texturing a sphere
Post by: msacco on June 21, 2018, 07:15:25
woops.~
Title: Re: Texturing a sphere
Post by: msacco on June 21, 2018, 07:26:00
Quote from: KaiHH on June 20, 2018, 19:39:32
No problem. Here is a demo using the somewhat latest reasonable version of OpenGL to render a rotating, textured sphere:
  https://github.com/LWJGL/lwjgl3-demos/commit/4304297afc6275f791d8b3e2850b740b6cfcdb4f
See the Java and shader files in that commit. It uses OpenGL 3.2 Core Profile functions. There hasn't been much improvement in later OpenGL versions for such simple things as rendering a textured sphere. It's still always:
- create a vertex and (optionally) index/element buffer
- create a shader program
- setup vertex specification with these buffers and the vertex attributes imported by the shader program
- enable/bind shader
- call draw functions

That seems much more complex than opengl 1-2 :D Do you have to use vao/vbos and shaders in opengl 3-4? And do you think this tutorial is good for learning new opengl? https://legacy.gitbook.com/download/pdf/book/lwjglgamedev/3d-game-development-with-lwjgl Thanks a lot for the example! (tho I can't really get it to work, but I can still read it)
Title: Re: Texturing a sphere
Post by: KaiHH on June 21, 2018, 09:11:53
Just import the repository as Maven project into your favorite IDE and everything will be settled for you automatically.
QuoteDo you have to use vao/vbos and shaders in opengl 3-4?
Yes.
Title: Re: Texturing a sphere
Post by: msacco on June 22, 2018, 08:58:11
Quote from: KaiHH on June 21, 2018, 09:11:53
Just import the repository as Maven project into your favorite IDE and everything will be settled for you automatically.
QuoteDo you have to use vao/vbos and shaders in opengl 3-4?
Yes.

The usage of lightning in new opengl is same as using lightning in old opengl? cause I wanna try to do some currently on my old oopengl code, but if its different than I guess there's no point in learning that.
Title: Re: Texturing a sphere
Post by: KaiHH on June 22, 2018, 12:07:11
You probably meant "lighting". And yes, it is TOTALLY different. There is no fixed-function API anymore to specify light parameters such as position, color, specularity, etc. You have to write GLSL shaders for that.
Title: Re: Texturing a sphere
Post by: msacco on June 22, 2018, 17:40:02
Quote from: KaiHH on June 22, 2018, 12:07:11
You probably meant "lighting". And yes, it is TOTALLY different. There is no fixed-function API anymore to specify light parameters such as position, color, specularity, etc. You have to write GLSL shaders for that.

Yep, I guess the "lightning" came as an habit ^_^ hmm, is it harder in new opengl or harder? Because from what I've heard, you should have more control of the lighting in opengl, you know if its meant for both new opengl or old opengl? I don't want something too complex, just make an object spread light to nearby objects in all directions.
Title: Re: Texturing a sphere
Post by: KaiHH on June 22, 2018, 17:51:19
Quote from: msacco on June 22, 2018, 17:40:02
is it harder in new opengl or harder?
Neither. It is harder. ;-)

Quote from: msacco on June 22, 2018, 17:40:02
Because from what I've heard, you should have more control of the lighting in opengl
You do have more control with shaders, obviously, since you can implement your own custom lighting and shading models with simple linear algebra and arithmetic while not having to rely on fixed-function pipeline flat and phong shading which you merely control parameters of.

But it sure has a learning curve attached to it. You know that you also do not have to use OpenGL >= 3. You can still perfectly use what you always used with OpenGL <= 2 and the fixed-function pipeline. It is not going to go away anytime soon. All drivers still perfectly support "legacy" OpenGL which might be absolutely sufficient for what you might want to do, if you do not want to invest into learning modern OpenGL and GLSL.
Title: Re: Texturing a sphere
Post by: msacco on June 22, 2018, 18:35:35
Quote from: KaiHH on June 22, 2018, 17:51:19
Quote from: msacco on June 22, 2018, 17:40:02
is it harder in new opengl or harder?
Neither. It is harder. ;-)

Quote from: msacco on June 22, 2018, 17:40:02
Because from what I've heard, you should have more control of the lighting in opengl
You do have more control with shaders, obviously, since you can implement your own custom lighting and shading models with simple linear algebra and arithmetic while not having to rely on fixed-function pipeline flat and phong shading which you merely control parameters of.

But it sure has a learning curve attached to it. You know that you also do not have to use OpenGL >= 3. You can still perfectly use what you always used with OpenGL <= 2 and the fixed-function pipeline. It is not going to go away anytime soon. All drivers still perfectly support "legacy" OpenGL which might be absolutely sufficient for what you might want to do, if you do not want to invest into learning modern OpenGL and GLSL.

Well Im doing it for my own fun atm, it would be amazing if I'll be able to work with it as a game developer or something similar in the future, but that's usually something you need tons of expeirence to do as far as I can see. I've just heard from many people that older opengl is not something that should still be used and that it is better to learn opengl, and it might make some sense as well, as if I learn something, might as well just learn the modern version than the older one. Im still very confused about all of this, so I really don't know, Some say that learning older gl first is bad, and some says the opposite.
Title: Re: Texturing a sphere
Post by: KaiHH on June 22, 2018, 19:47:52
Well, everyone can only express their own opinions based on their own experience and the path they chose.
If you really want to learn it and not achieve some immediate goal with finishing your planet rendering program, then my opinion is: start learning modern OpenGL.
I myself started learning the legacy/old fixed-function pipeline OpenGL in 2007 and transitioned to more "modern" OpenGL 2.0 (VBOs and shaders) two years later. This has been at the expense of many many maaaaaaaany hours of googling the web left and right and up and down for OpenGL-related resources, articles, papers, specifications, forum posts, blog articles, literally everything, building dozens of little test and demo programs and throwing them away after reading how that all can be done better. If you get hooked by the thrill of learning it, and the small moments when it makes "click" in your head, then there's no stopping you anymore. :)
The hardest thing but also the most fun is to get an accurate mental model of the object model, state management and the rendering pipeline in modern OpenGL.
In modern OpenGL you just have a few core concepts/objects that you use for everything (VAO, buffer objects, textures, samplers, shaders and framebuffer objects). Then there are the different shader stages doing different things. Sooo many things to explore.
So, start digging around and building your own mental model of modern OpenGL. :)
I guess, at the beginning literally every starting point is a good point.
Title: Re: Texturing a sphere
Post by: msacco on June 22, 2018, 21:00:43
Quote from: KaiHH on June 22, 2018, 19:47:52
Well, everyone can only express their own opinions based on their own experience and the path they chose.
If you really want to learn it and not achieve some immediate goal with finishing your planet rendering program, then my opinion is: start learning modern OpenGL.
I myself started learning the legacy/old fixed-function pipeline OpenGL in 2007 and transitioned to more "modern" OpenGL 2.0 (VBOs and shaders) two years later. This has been at the expense of many many maaaaaaaany hours of googling the web left and right and up and down for OpenGL-related resources, articles, papers, specifications, forum posts, blog articles, literally everything, building dozens of little test and demo programs and throwing them away after reading how that all can be done better. If you get hooked by the thrill of learning it, and the small moments when it makes "click" in your head, then there's no stopping you anymore. :)
The hardest thing but also the most fun is to get an accurate mental model of the object model, state management and the rendering pipeline in modern OpenGL.
In modern OpenGL you just have a few core concepts/objects that you use for everything (VAO, buffer objects, textures, samplers, shaders and framebuffer objects). Then there are the different shader stages doing different things. Sooo many things to explore.
So, start digging around and building your own mental model of modern OpenGL. :)
I guess, at the beginning literally every starting point is a good point.

I think I will try finishing what Im currently doing(almost finished except for lighting and correct scaling/3d camera movement) using old opengl, then I will learn and try to do the same, but in modern opengl, once thing that really bugs me, is that I know that in modern opengl you need to upload something only once to the gpu to render it, unlike now, where I want to do something that renders many any objects all at once, but it simply causes huge fps drops so I can't really do it. Obviously, there are tons of ways to go around it, but for someone like me, I don't really know how to do it yet, so thats where I kinda feel the limitations atm. Hopefully I will have enough time for that, as I start a degree soon and maybe a new job, so that might be a bit stressful :x
Anyway, I really appreciate all your answers and help, that was so helpful and you have no idea how much I've been tought through you.