Learn OpenGL
NiteHackr

I just found the best OpenGL tutorials I have seen on the net in years!

https://learnopengl.com/

...it teaches modern OpenGL, the basics and advanced topics in a really nice way. I managed to achieve a lot and he teaches how to do it properly! No immediate mode garbage, but properly coded shaders etc... it's been a lot of fun following this and I just had to share it here.

He used GLFW for this, but the way he teaches it, you could easily pick your library to use it, just swap the various GLFW functions to whatever. Probably Allegro, or SDL etc... wouldn't be difficult.

{"name":"611195","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/5\/c56411813895b429c3e52ce278753562.jpg","w":791,"h":594,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/5\/c56411813895b429c3e52ce278753562"}611195

Samuel Henderson

Yeah these tutorials are very well done and certainly the best I've been seen at explaining a lot of the 3D concepts (transformations, matrices, etc).

I wanted to re-do his 'In Practice: 2D Breakout Game' with Allegro 5 but alas, I haven't had the time.

Arvidsson

Very nice! Even goes through PBR! I'm tempted to do some C++ again hehe.

NiteHackr

Yeah, it's been pretty kewl to learn the right way to do things for a change.

He uses GLFW, but there's no reason why someone couldn't use Allegro, SDL2 or whatever you prefer.

I was used to using GLEW in the past, but I he uses something called GLAD and I love it as it is a header file only which I like. No precompiled needed etc... his image loader is the same. I have been doing it his way, but I may rewrite some of what I have learned using Code::Blocks and something else, Allegro or SDL2.

Samuel Henderson
Neil Roy said:

I was used to using GLEW in the past, but I he uses something called GLAD and I love it as it is a header file only which I like. No precompiled needed etc... his image loader is the same.

Yeah. When I was looking at his stuff a couple of years ago he was using SOIL (Simple Opengl Image Library)... I had to jump through all sorts of hoops to get that library working in Windows, Linux and macOS. At some point he switched to stb_image ... which makes things SO MUCH SIMPLER. Just add stb_image.h to your project and call stbi_load(...) and bam: here's an unsigned char * to the image data.

Also, Neil Roy, is this you?:
https://youtu.be/ZxMx2NUT5sw?t=112

bamccaig

and bam: here's an unsigned char * to the image data.

You lied, where is my unsigned char * to this mystery image data? ??? ;)

I started these when Neil posted them a week or so ago on another thread (or maybe here, I don't know). It's still hard to find the energy to learn this stuff after work, but it's nice to dabble in it at least.

Chris Katko

A long time ago I was trying to get into OpenGL and I was making a "space" version of Minecraft where you could build ships and fly them around.

{"name":"O8DGS9c.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/5\/4566f393bc13fff1dae8ab95cce0d64e.jpg","w":812,"h":638,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/5\/4566f393bc13fff1dae8ab95cce0d64e"}O8DGS9c.jpg

Years later, Space Engineers came out. They totally ripped me off. ;)

Samuel Henderson
bamccaig said:

I started these when Neil posted them a week or so ago on another thread (or maybe here, I don't know). It's still hard to find the energy to learn this stuff after work, but it's nice to dabble in it at least.

I used to dabble with these tutorials too. Then my employer decided to pay me to do a bunch of OpenGL Core profile work. That tremendously accelerates the learning process ... being able to focus on learning and using OpenGL for 8+ hours a day.

Ariesnl

@ Chris Katko
Finish it anyway !
You might be able to make it better 8-)

NiteHackr

Also, Neil Roy, is this you?:

Yeah, kewl, I didn't know he mentioned my little program. Thanks for letting me know.

Years later, Space Engineers came out. They totally ripped me off. ;)

I agree, you should continue it. You started with your own idea, keep going your own way, you may end up with something far superior.

I want to convert all his examples to SDL2 + C, no C++, no classes. Could be fun as I feel much more at ease with pure C.

Rodolfo Lam

I think I have somewhere around a wrapper I made at least for the initial tutorials that used Allegro instead of GLFW, I recall it almost mapped 1:1 with ease. Bumping this to see if I find it and post it on GitHub or something.

NiteHackr

I just read through the advanced tutorial on instancing, wow, that one will be REALLY valuable! He renders 100,000 asteroids on screen without much of a performance hit. I could have used this in my old terrain program I wrote years ago. Using immediate mode OpenGL (fixed pipeline), and with my tree numbers maxxed out, I got 1 FPS! LMAO With instancing I shouldn't see much of a hit at all which is uber kewl.

{"name":"611208","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d60249d72a7cd912fe7b359e69db05df.jpg","w":1280,"h":720,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d60249d72a7cd912fe7b359e69db05df"}611208

He also had some great tips on skybox's, which I already understood (screenshot above used one I created back then). One of his tips should help increase efficiency with them too, and that was to render the skybox LAST, which I would never do normally, but with the right settings, it would be more efficient as the fragments of the skybox that are not visible would simply not be drawn at all using a depth buffer trick he mentioned. Each fragment would be checked against the depth buffer and would not be drawn if it wasn't visible due to something else already being there.

Contrast that with how you normally do it. Turn depth testing off, draw the skybox first, then the objects closer, then turn depth testing on. The result is you draw the entire visible skybox whether it is blocked or not, where as using his trick, only the parts not blocked by closer objects are seen = more efficient.

I think I have somewhere around a wrapper I made at least for the initial tutorials that used Allegro instead of GLFW, I recall it almost mapped 1:1 with ease. Bumping this to see if I find it and post it on GitHub or something.

That would be interesting! I would love to see some high quality 3D stuff done with Allegro.

Arvidsson

Hmm I can't make glad work with allegro for some reason.

al_set_new_display_flags(ALLEGRO_OPENGL_3_0);
al_set_new_display_option(ALLEGRO_OPENGL_MAJOR_VERSION, 3, ALLEGRO_REQUIRE);
al_set_new_display_option(ALLEGRO_OPENGL_MINOR_VERSION, 3, ALLEGRO_REQUIRE);
display = al_create_display(width, height);
if (!display) return -1;
al_set_current_opengl_context(display);

if (!gladLoadGLLoader((GLADloadproc)al_get_opengl_proc_address)) return -2;

I tried the above but the call to gladLoadGLLoader fails. Any idea what might be wrong?

NiteHackr

Wish I could help, never used Allegro with anything 3D before. :/ You could try using GLEW instead, see if that works. It shouldn't matter which one you use to be honest.

bamccaig

My only guess would be that the glad that you have doesn't match the OpenGL that Allegro is using? Try to regenerate GLAD to match I guess?

Arvidsson

Good idea. I tried it out and something is not right. I get the version 0 from al_get_opengl_version. I printed it out as hex and it was 0.

I link against opengl32.lib.

This is the code:

#SelectExpand
1#include <glad/glad.h> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_opengl.h> 4#include <iostream> 5 6int main(int argc, char **argv) 7{ 8 al_init(); 9 al_set_new_display_flags(ALLEGRO_OPENGL_3_0); 10 al_set_new_display_option(ALLEGRO_OPENGL_MAJOR_VERSION, 3, ALLEGRO_REQUIRE); 11 al_set_new_display_option(ALLEGRO_OPENGL_MINOR_VERSION, 3, ALLEGRO_REQUIRE); 12 ALLEGRO_DISPLAY *display = al_create_display(800, 600); 13 if (!display) { 14 std::cout << "Failed to create display"; 15 return -1; 16 } 17 al_set_current_opengl_context(display); 18 std::cout << "OpenGL Version: " << std::hex << al_get_opengl_version() << std::endl; 19 20 ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60); 21 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); 22 al_register_event_source(event_queue, al_get_display_event_source(display)); 23 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 24 25 if (!gladLoadGLLoader((GLADloadproc)al_get_opengl_proc_address)) { 26 std::cout << "Failed to load opengl"; 27 return -1; 28 } 29 30 al_clear_to_color(al_map_rgb(0, 0, 0)); 31 al_flip_display(); 32 al_start_timer(timer); 33 bool redraw = true; 34 35 while (1) { 36 ALLEGRO_EVENT ev; 37 al_wait_for_event(event_queue, &ev); 38 39 if (ev.type == ALLEGRO_EVENT_TIMER) { 40 redraw = true; 41 } 42 else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 43 break; 44 } 45 46 if (redraw && al_event_queue_is_empty(event_queue)) { 47 redraw = false; 48 glClearColor(1.0f, 0.3f, 0.3f, 1.0f); 49 glClear(GL_COLOR_BUFFER_BIT); 50 al_flip_display(); 51 } 52 } 53 54 al_destroy_timer(timer); 55 al_destroy_display(display); 56 al_destroy_event_queue(event_queue); 57 58 return 0; 59}

Any idea what else might be wrong here?

Edgar Reynaldo

Are you drivers up to date? Also, you might try adding in ALLEGRO_OPENGL to your al_set_new_display_flags call.

Chris Katko

I've had tons of problems with mismatched libraries that were compiled at different times, or from ever-so-slightly different sub-versions between include files and binaries.

They may even not break ALL functions! Sometimes they only break SOME! :o :o :o Until you realize what's going on, it will give you a headache for why only one function will blow up ("how can 'half a library' break!?")

Edgar Reynaldo

I can has questions.

How do you handle the poles with a skybox?

How do you render a quad in modern OpenGL?

NiteHackr

Somehow I doubt you don't know this stuff Edgar, but...

How do you handle the poles with a skybox?

I'm not sure what you mean? You talking about rotations?

Quote:

How do you render a quad in modern OpenGL?

You create two triangles...

{"name":"611214","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/f\/af696c4f2afee676b9b97743c2b3f98e.jpg","w":500,"h":500,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/f\/af696c4f2afee676b9b97743c2b3f98e"}611214

The first triangle would be something like vertices 0, 2 and 1, and the second would be 1, 2, 3. Or you could create a triangle strip with 0, 2, 1, 3. OR you could just specify GL_QUADS, but that may or may not work as they have been depreciated, though personally, I doubt very much that they will disappear anytime soon as that would wreck backwards compatibility, and who wants to sell a card that does that, especially with the growing nostalgia for older games these days.

Personally, I stick with triangles for everything as you can easily store lists of vertices and lists of indexes for polygons (triangles) and you don't have to worry about the different types etc. Plus you want them all triangles anyhow so you can do the various occlusion tests, collision tests, lighting etc.

In other news, I done some of the Advanced OpenGL - Instancing part of the tutorials and I am blown away at what that can do!!! In this screenshot I am rendering 10000 asteroids which all have 570+ polygons each plus the planet which has over 4000 and getting 91FPS (bottom right corner) without any culling or other optimizations! This is really kewl stuff.

{"name":"611215","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/6\/965fbb75d6b8fac26aba174b69d7b5fa.jpg","w":1280,"h":720,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/6\/965fbb75d6b8fac26aba174b69d7b5fa"}611215

Chris Katko
Neil Roy said:

n other news, I done some of the Advanced OpenGL - Instancing part of the tutorials and I am blown away at what that can do!!! In this screenshot I am rendering 10000 asteroids which all have 570+ polygons each plus the planet which has over 4000 and getting 91FPS (bottom right corner) without any culling or other optimizations! This is really kewl stuff.

Hell yeah! That's what I was saying in one of my previous posts. Modern cards (even 7-10 year old cards!) are unfathomably faster than you think and if they're slow, it's 99% of the time you doing something wrong.

NiteHackr

Yeah, my system is actually starting to get a little dated. My CPU is only a triple core CPU (AMD) and my video is an NVidia GTX650, which isn't too bad, but also getting dated.

Still, runs well! I had 100,000 asteroids being rendered and it did it, was choppy though, around 9-10 FPS, but considering the polygons that were being pushed, something like 57million, that wasn't too shabby. With optimizations like proper culling etc... the frame rate could go up pretty dramatically.

I'm taking the asteroids program and adding on a space skybox with some lighting etc... I want to see what I can make with it. ;)

Edit: I also created a simple, cube based 3D City program using older OpenGL programming (immediate or fixed pipeline mode) and I managed to get around 600FPS with culling with it so I have high hopes for this modern stuff.

Edit2: I have a dropbox link for the older City3D program if you're curious.
https://www.dropbox.com/s/mfcyhj5q0rdjfd9/City3D.zip?dl=0

Edgar Reynaldo

How do you handle looking up and down with a skybox?

There's an open game dev exchange question open for you to answer, Neil :

https://gamedev.stackexchange.com/questions/138173/creating-a-skybox-in-allegro-5

Chris Katko

How do you handle looking up and down with a skybox?

It's just a box with textures on the inside...

Edgar Reynaldo

Okay, so what happens when you look at the corners???

Chris Katko

It looks like crap! :P ;)

IIRC, you convert the bitmaps to polar coordinates, and then still use a cube.

http://www.mbsoftworks.sk/index.php?page=tutorials&series=1&tutorial=13

http://antongerdelan.net/opengl/cubemaps.html

video

NiteHackr

How do you handle looking up and down with a skybox?

You rotate the skybox in the opposite direction than you're looking. If you look down, so your pitch goes down, the skybox should rotate up. Note: You do not translate the skybox, it moves with you.

Okay, so what happens when you look at the corners???

You don't see corners on a skybox. When you render a skybox, you turn off lighting, you also clamp the edges of the skybox textures so there is no gap or lines where the sides meet (like any model really).

My City3D program I linked before this uses a simple skybox I made with old opengl code. Just a textured cube. Only I reverse the winding. OpenGL uses counter clockwise winding for it's polygons, so for a skybox I switch it to clockwise winding so the front face is on the inside of each side (using the old method of OpenGL anyhow). Then I disable lighting so there are no shadows on the skybox textures and render it. I have a function I use I can probably post here that I used in the past (though there are newer ways to do them now, I haven't studied it yet).

Important, this uses older, depreciated OpenGL, but it still works. At the very least, it gives an idea on how to do it which can be converted to modern OpenGL, something I plan to do. Also, in this function, it uses a global variable which contains the IDs for the various skybox textures that are loaded elsewhere.

#SelectExpand
1void skybox(void) 2{ 3 float m_SkyBoxSize = (float)(drawmax * 12); // 200.0f 4 float ymin, ymax; 5 6 ymin = -m_SkyBoxSize / 2.0f; 7 ymax = 1.0f + m_SkyBoxSize / 2.0f; 8 9 // Set winding to clock-wise 10 glFrontFace(GL_CW); 11 12 // Front Face 13 glBindTexture(GL_TEXTURE_2D, texture[SKY0]); 14 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 15 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 16 glBegin(GL_QUADS); 17 glTexCoord2f(1.0f, 0.0f); 18 glVertex3f(m_SkyBoxSize, ymin, m_SkyBoxSize); // Bottom Right Of The Texture and Quad 19 glTexCoord2f(1.0f, 1.0f); 20 glVertex3f(m_SkyBoxSize, ymax, m_SkyBoxSize); // Top Right Of The Texture and Quad 21 glTexCoord2f(0.0f, 1.0f); 22 glVertex3f(-m_SkyBoxSize, ymax, m_SkyBoxSize); // Top Left Of The Texture and Quad 23 glTexCoord2f(0.0f, 0.0f); 24 glVertex3f(-m_SkyBoxSize, ymin, m_SkyBoxSize); // Bottom Left Of The Texture and Quad 25 glEnd(); 26 27 // Right face 28 glBindTexture(GL_TEXTURE_2D, texture[SKY1]); 29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 31 glBegin(GL_QUADS); 32 glTexCoord2f(1.0f, 0.0f); 33 glVertex3f(m_SkyBoxSize, ymin, -m_SkyBoxSize); // Bottom Right Of The Texture and Quad 34 glTexCoord2f(1.0f, 1.0f); 35 glVertex3f(m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Right Of The Texture and Quad 36 glTexCoord2f(0.0f, 1.0f); 37 glVertex3f(m_SkyBoxSize, ymax, m_SkyBoxSize); // Top Left Of The Texture and Quad 38 glTexCoord2f(0.0f, 0.0f); 39 glVertex3f(m_SkyBoxSize, ymin, m_SkyBoxSize); // Bottom Left Of The Texture and Quad 40 glEnd(); 41 42 43 // Back Face 44 glBindTexture(GL_TEXTURE_2D, texture[SKY2]); 45 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 46 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 47 glBegin(GL_QUADS); 48 glTexCoord2f(1.0f, 0.0f); 49 glVertex3f(-m_SkyBoxSize, ymin, -m_SkyBoxSize); // Bottom Right Of The Texture and Quad 50 glTexCoord2f(1.0f, 1.0f); 51 glVertex3f(-m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Right Of The Texture and Quad 52 glTexCoord2f(0.0f, 1.0f); 53 glVertex3f(m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Left Of The Texture and Quad 54 glTexCoord2f(0.0f, 0.0f); 55 glVertex3f(m_SkyBoxSize, ymin, -m_SkyBoxSize); // Bottom Left Of The Texture and Quad 56 glEnd(); 57 58 // Left Face 59 glBindTexture(GL_TEXTURE_2D, texture[SKY3]); 60 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 62 glBegin(GL_QUADS); 63 glTexCoord2f(1.0f, 0.0f); 64 glVertex3f(-m_SkyBoxSize, ymin, m_SkyBoxSize); // Bottom Right Of The Texture and Quad 65 glTexCoord2f(1.0f, 1.0f); 66 glVertex3f(-m_SkyBoxSize, ymax, m_SkyBoxSize); // Top Right Of The Texture and Quad 67 glTexCoord2f(0.0f, 1.0f); 68 glVertex3f(-m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Left Of The Texture and Quad 69 glTexCoord2f(0.0f, 0.0f); 70 glVertex3f(-m_SkyBoxSize, ymin, -m_SkyBoxSize); // Bottom Left Of The Texture and Quad 71 glEnd(); 72 73 // Top Face 74 glBindTexture(GL_TEXTURE_2D, texture[SKY4]); 75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 77 glBegin(GL_QUADS); 78 glTexCoord2f(1.0f, 0.0f); 79 glVertex3f(m_SkyBoxSize, ymax, m_SkyBoxSize); // Bottom Right Of The Texture and Quad 80 glTexCoord2f(1.0f, 1.0f); 81 glVertex3f(m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Right Of The Texture and Quad 82 glTexCoord2f(0.0f, 1.0f); 83 glVertex3f(-m_SkyBoxSize, ymax, -m_SkyBoxSize); // Top Left Of The Texture and Quad 84 glTexCoord2f(0.0f, 0.0f); 85 glVertex3f(-m_SkyBoxSize, ymax, m_SkyBoxSize); // Bottom Left Of The Texture and Quad 86 glEnd(); 87 88 89 // Bottom Face 90 glBindTexture(GL_TEXTURE_2D, texture[SKY5]); 91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 93 glBegin(GL_QUADS); 94 glTexCoord2f(0.0f, 1.0f); 95 glVertex3f(-m_SkyBoxSize, ymin, m_SkyBoxSize); 96 glTexCoord2f(0.0f, 0.0f); 97 glVertex3f(-m_SkyBoxSize, ymin, -m_SkyBoxSize); 98 glTexCoord2f(1.0f, 0.0f); 99 glVertex3f(m_SkyBoxSize, ymin, -m_SkyBoxSize); 100 glTexCoord2f(1.0f, 1.0f); 101 glVertex3f(m_SkyBoxSize, ymin, m_SkyBoxSize); 102 glEnd(); 103 104 // Set winding to counter clock-wise 105 glFrontFace(GL_CCW); 106 107}

Edit: And this is some code I use to draw and rotate the skybox in my City3D program...

#SelectExpand
1// Draw Skybox 2 if(sky_enabled) { 3 glPushMatrix(); 4 glDisable(GL_LIGHTING); // disable lighting 5 glDisable(GL_DEPTH_TEST); // disables Depth Testing 6 glColor3f(1.0f, 1.0f, 1.0f); // white lighting 7 glDisable(GL_FOG); // no fog 8 glRotatef(xrot, 1.0f, 0.0f, 0.0f); // rotate around the x axis 9 glRotatef(yrot, 0.0f, 1.0f, 0.0f); // rotate around the y axis 10 glRotatef(zrot, 0.0f, 0.0f, 1.0f); // rotate around the z axis 11 skybox(); // render the skybox 12 if(fog_enabled) glEnable(GL_FOG); // turn fog back on 13 else glDisable(GL_FOG); 14 glEnable(GL_LIGHTING); // turn lighting back on 15 glEnable(GL_DEPTH_TEST); // Enables Depth Testing 16 glPopMatrix(); 17 }

Edit2: Oh, and each side of the skybox should be a 90 degree FOV texture for it to work properly. 90x4 sides = 360 degrees, plus the top and bottom sides.

Edit3: All this talk about skyboxes, made me add a modern OpenGL Skybox to my space scene, this is what I have now. :)

{"name":"611216","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/4\/54a1053d5d16fcc5fcabc282328a5827.jpg","w":1280,"h":720,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/4\/54a1053d5d16fcc5fcabc282328a5827"}611216

I want to add in proper lighting and a new planet texture next. I also thought it would be kewl to add in a couple, random, derilect ships floating around from Star Trek, Star Wars, Apollo etc. :D

Edit4: Created a short video clip of my project so far with music. :)

video

Edgar Reynaldo

That's pretty sweet, Neil.

Where did you get your asteroid model?

I still don't understand what happens when you look at the corners of the skybox. Shouldn't the textures be totally distorted?

Neil, could you show me where you setup your projection matrices for the skybox?

NiteHackr

Where did you get your asteroid model?

I was following the Learn OpenGL tutorials and got the model and information on how to do modern Skyboxes from him. Though I understood how they work, I just didn't understand modern techniques, which have improved. Also see his section on instancing which is where I learned this. He has a link to this asteroid model, though you can use any model you wish once you get the model loading code down pat. A direct link to it is here (from his website)...

https://learnopengl.com/Advanced-OpenGL/data/models/rock.rar

Quote:

I still don't understand what happens when you look at the corners of the skybox. Shouldn't the textures be totally distorted?

If you had a normal field of view, they absolutely would be distorted. But when you create a skybox, you render each view with a 90 degree field of view (as opposed to your normal 45-60 degree FOV most games use). You have four sides plus the top and bottom. In order to get a perfect 360 degree panaramic view, you need to have each of the four sides (plus top and bottom) be 360/4=90 degrees. So once you combine them all, you get what appears to be a panaramic, perfect 360 view you can look around and no corners. The 90 degree FOV textures actually look a little distorted until you put them on the inside of a cube for the skybox.

Now if you JUST make a cube with the 90 degree FOV textures, you will see the corners. You need to turn off lighting which will shade the sides and show shadows in the corners and just light the entire texture evenly by setting a colour as I did as pure white to light up the entire texture. You also turn off things like fog etc when you render the skybox. You clamp the edges (see my previous older code which contains code for clamping that is still valid), what that does is it ensure the texture goes all the way to the edge so no seams are visible between textures.

What you see when you see a corner is shadowing, lighting etc... plus if your textures are views which are less than 90 degree FOV, than you notice it. Think about it, if you try and fit a 45 degree FOV image onto a side which is a 90 degree FOV, you will get distortion unless the view was 90 degrees ahead of time.

Also, check out the Java tutorial Chris posted above, it explains modern skyboxes very nicely. Even though it is Java, it translates over to C/C++ easily. But the concepts are the same.

Quote:

Neil, could you show me where you setup your projection matrices for the skybox?

Learn OpenGL does a great job explaining this and even provides code if you get stuck. This is the modern method which is more involved, but well worth it.

https://learnopengl.com/Advanced-OpenGL/Cubemaps

If you followed along with these tutorials, I basically just needed to insert this code (though I had to alter some of it as he had errors in it, easy fix)...

#SelectExpand
1Shader skyboxShader("6.1.skybox.vs", "6.1.skybox.fs"); 2 3 float skyboxVertices[] = { 4 // positions 5 -1.0f, 1.0f, -1.0f, 6 -1.0f, -1.0f, -1.0f, 7 1.0f, -1.0f, -1.0f, 8 1.0f, -1.0f, -1.0f, 9 1.0f, 1.0f, -1.0f, 10 -1.0f, 1.0f, -1.0f, 11 12 -1.0f, -1.0f, 1.0f, 13 -1.0f, -1.0f, -1.0f, 14 -1.0f, 1.0f, -1.0f, 15 -1.0f, 1.0f, -1.0f, 16 -1.0f, 1.0f, 1.0f, 17 -1.0f, -1.0f, 1.0f, 18 19 1.0f, -1.0f, -1.0f, 20 1.0f, -1.0f, 1.0f, 21 1.0f, 1.0f, 1.0f, 22 1.0f, 1.0f, 1.0f, 23 1.0f, 1.0f, -1.0f, 24 1.0f, -1.0f, -1.0f, 25 26 -1.0f, -1.0f, 1.0f, 27 -1.0f, 1.0f, 1.0f, 28 1.0f, 1.0f, 1.0f, 29 1.0f, 1.0f, 1.0f, 30 1.0f, -1.0f, 1.0f, 31 -1.0f, -1.0f, 1.0f, 32 33 -1.0f, 1.0f, -1.0f, 34 1.0f, 1.0f, -1.0f, 35 1.0f, 1.0f, 1.0f, 36 1.0f, 1.0f, 1.0f, 37 -1.0f, 1.0f, 1.0f, 38 -1.0f, 1.0f, -1.0f, 39 40 -1.0f, -1.0f, -1.0f, 41 -1.0f, -1.0f, 1.0f, 42 1.0f, -1.0f, -1.0f, 43 1.0f, -1.0f, -1.0f, 44 -1.0f, -1.0f, 1.0f, 45 1.0f, -1.0f, 1.0f 46 }; 47 48 // skybox VAO 49 unsigned int skyboxVAO, skyboxVBO; 50 glGenVertexArrays(1, &skyboxVAO); 51 glGenBuffers(1, &skyboxVBO); 52 glBindVertexArray(skyboxVAO); 53 glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO); 54 glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); 55 glEnableVertexAttribArray(0); 56 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 57 58 // Skybox Textures 59 vector<std::string> faces 60 { 61 "resources/textures/skybox/space_right.jpg", 62 "resources/textures/skybox/space_left.jpg", 63 "resources/textures/skybox/space_top.jpg", 64 "resources/textures/skybox/space_bottom.jpg", 65 "resources/textures/skybox/space_front.jpg", 66 "resources/textures/skybox/space_back.jpg" 67 }; 68 unsigned int cubemapTexture = loadCubemap(faces); 69 70 skyboxShader.use(); 71 skyboxShader.setInt("skybox", 0);

I of course created my own space skybox textures and re-organized their loading order as his was flawed. See his tutorials for other functions mentioned here.

Now for drawing the skybox, he had some great optimizations. Normally, using the old OPenGL (see my code again above) you would disable depth testing and draw the skybox first (back to front). But in this newer code, you actually leave depth testing on and draw the skybox last, which one might think would overwrite the foreground objects, but what you do is adjust settings for the depth testing so that it only draws the parts of the skybox that are visible without overwriting foreground objects. As a result, this makes it FASTER to render it as you can skip over entire fragments which are not visible. Kewl beans! ;)

// draw skybox as last
    glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
    skyboxShader.use();
    view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
    skyboxShader.setMat4("view", view);
    skyboxShader.setMat4("projection", projection);
    // skybox cube
    glBindVertexArray(skyboxVAO);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glDepthFunc(GL_LESS); // set depth function back to default

There are separate shader programs you use for the asteroids. The fragment shaders (which are loaded and compiled when you run the game then sent to the video card).

Fragment shader for asteroids...

#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D texture_diffuse1;

void main()
{
    FragColor = texture(texture_diffuse1, TexCoords);
}

Vertex shader for asteroids...

#SelectExpand
1#version 330 core 2layout (location = 0) in vec3 aPos; 3layout (location = 2) in vec2 aTexCoords; 4layout (location = 3) in mat4 aInstanceMatrix; 5 6out vec2 TexCoords; 7 8uniform mat4 projection; 9uniform mat4 view; 10 11void main() 12{ 13 TexCoords = aTexCoords; 14 gl_Position = projection * view * aInstanceMatrix * vec4(aPos, 1.0f); 15}

It really is well worth just following along those tutorials, in order and you will understand all of this. They're very well explained, probably the best on the net that I have seen.

Edgar Reynaldo

Would you be willing to zip an archive of the source and binaries you used for the asteroids and skybox? I want to play with it. Trying to learn what you did piece by piece isn't helping me wrap my head around this.

What I'm trying to get at here, is how do you avoid spherical distortion of the corners of the skybox when you look up and down? I need to see your skybox textures, or see how they were created in order to understand this better.

NiteHackr

Okay, I created a trimmed down version with just a skybox and nothing else, in part to make it easier to follow and also to cut down on the filesize. I also copied the needed libs and includes etc... into one folder and then adjusted the solution properties so it will compile right out of the folder it is all zipped in.

This just has a skybox, nothing else. But all the libs and includes that are needed to do most of the Learn OpenGL tutorials are included so all you would need to do in order to do more is just add in the appropriate code, shaders and resources, which are all easily available from those tutorials.

This may help anyhow. The skybox textures are the ones the tutorial author used (except he had the front and back textures mixed up), it should make it easier to understand which direction you're looking. It was created using Terragen, you can make your own, just set the field of view to 90 degrees for each compass direction as well as up and down.

This is a Visual Studio 2017 solution by the way, I don't know how it will compile with older versions.

https://www.dropbox.com/s/8apyjnph5nnqeue/Moden%20OpenGL%20-%20Skybox.7z?dl=0

Edgar Reynaldo

Neil, thanks for the download. How many gigabytes does it take to build an msvc project these days? 1.86GB to be precise. Really, you could have just shared the source code and the models plus textures. That would have been good enough.

I guess you can't really answer my question. You're using a cube map from the tutorial, and I guess I just don't understand what happens when you're looking at the poles without there being some sort of polar or spherical projection.

I thought maybe you were doing it with an orthographic transform.

I don't really want to mess around with glfw and glew and glut and glad and all that crap. If I can't do it with straight Allegro and OpenGL I don't really want to do it. You know, you can get an RGBA* from allegro and create a new texture from that. Or you can use the texture allegro is using.

Chris Katko

I posted more than enough tutorials to answer the question. ::)

Edgar Reynaldo

Katko, your links said the exact same thing Neil's do. Use a cubemap. No. I want to understand what is going on, and how to render it manually. I shouldn't need a freaking shader to render a background. That's stupid.

NiteHackr

Well, this post, which I started, is all about modern opengl. If you don't want to use shaders, than you won't be doing modern opengl. I felt the same as you at one time, but if you follow the tutorials you will learn that shaders are awesome and actually a lot simpler than I thought.

The project I shared, you just need to compile it up, you don't need to know anything about GLFW, it will compile up for you as I already got everything put together for it.

I don't plan to use GLFW either, I can't stand it to be honest, but it is what those tutorials use and is, in the end, not important at all as it is just the framework which creates the window and opengl context, which you can just as easily do with anything else. I haven't done it with Allegro myself, so you're barking up the wrong tree here. I'll probably end up switching my entire project to another framework besides GLFW and I'll switch all the code to C from C++, but the important thing here is to learn modern opengl, everything else is depreciated.

I already posted OLDer code as well which shows the older, non-shader way to do it and there isn't any other way to explain skyboxes. It's just a 360 field of view, with four sides, each side is a texture, an image that was photographed or rendered with 90 degree field of view for each side totaling 360. Forget all the rest of your terminology and projections etc... it's a lot simpler than that. It's exactly what I just said. Just take four 90 degree views and paste them on the inside of a cube, plus the top and bottom view. THAT'S IT!!!

If you want an older game that did it, check out Myst 3, it used a cube/skybox for ALL of it's stuff. When you looked around, you were rotating a cube around you, each side animated in that case, but the same thing. PLus Chris already posted an excellent video on it (I watched it, and more myself, great find Chris!). There's nothing more to understand.

Old OpenGL and non-opengl: create a cube, paste textures on each side that are all created with a 90 degree FOV and you're done.

New OpenGL: Use a cubemap, which is basically the same, except newer opengl treats all 6 textures for it like one large texture and then uses a direction vector from the center and your view to determine which fragment to render.

If you do not like shaders, than you will never use modern OpenGL. Period. That is what they are all about, it's all done via shaders now, you write simple programs for the video card and tell it where to find your variables. It sounds more complicated than it actually is. I was VERY resistant to learning it, but I am glad I did as it is not hard at all and you can do some amazing things with them with very little effort.

I suggest you follow the tutorials using the software they use JUST to learn the OpenGL stuff, then you can get a full understanding of it and be better equipped to apply it to Allegro, perhaps make your own tutorial series once you do for the Allegro community.

There's nothing else I can say. I sat here working on making a self contained project you could easily open and compile right out of the box without setup and you didn't appreciate it one bit.

Edit: as for the asteroid program, if you didn't like the simple skybox program I packaged up, what would you possibly get out of the rest of a more complex program? The rest is just loading the planet and asteroid models and displaying them using similar techniques and there is no way in hell I will even try to explain them if you don't understand skyboxes which are about as simple as one can get. Again, FOLLOW THE TUTORIALS. These tutorials are, quite frankly, the best I have ever seen on modern opengl. They could have used Allegro, or SDL2 or whatever... and it wouldn't make a lick of difference with regard to opengl, the opengl code is STILL the same, and the methods are STILL the same. If it was Allegro, you would STILL BE USING THE SAME CODE, and you would be using SHADERS unless you want to use older, depreciated opengl, which still works and is even simpler and I already shared that code above (minus anything Allegro, which honestly, doesn't matter).

Chris Katko
Neil Roy said:

If you don't want to use shaders, than you won't be doing modern opengl.

This. Shader's aren't that big a deal. They're just little, concise programs.

NiteHackr

This. Shader's aren't that big a deal. They're just little, concise programs.

Exactly, they're awesome. I thought they would be more complicated, and once I learned them I was like... this is amazing! You basically write simple code on how to treat each fragment it renders, but you can do amazing things with them.

Heck, most of the shaders look like this...

Skybox vertex shader:
(vertex shaders operate on each vertex sent to it, it is the first stage on the video card)

#version 330 core
layout (location = 0) in vec3 aPos;

out vec3 TexCoords;

uniform mat4 projection;
uniform mat4 view;

void main()
{
    TexCoords = aPos;
    vec4 pos = projection * view * vec4(aPos, 1.0);
    gl_Position = pos.xyww;
}

Skybox fragment shader:
The vertex shader passes information to the fragment shader on the video card to process "fragments" or potential pixels, you can do things to each "pixel" (though technically, they are not pixels but for simplicity) creating special effects, anti-aliasing, you name it, quite amazing...

#version 330 core
out vec4 FragColor;

in vec3 TexCoords;

uniform samplerCube skybox;

void main()
{    
    FragColor = texture(skybox, TexCoords);
}

All modern OpenGL programs REQUIRE at LEAST a vertex shader and a fragment shader. There are other shader types as well, but these two are required. So, either you learn to use shaders, or you use depreciated opengl, fixed pipeline code or stick to 2D. And if this annoys you, don't even think about looking into a modern replacement for OpenGL called Vulcan, it's even worse (I won't bother with it myself).

Edit: Let me go over the vertex shader above and maybe I can make it more clear so you are not intimidated by them so much...

#version 330 core
^^ This tells the shader which version of opengl we are making it for, in this case, version 3.3. If you wanted to program some opengl 4.0 stuff, it would be #version 400 perhaps.

layout (location = 0) in vec3 aPos;
This tells the shader that we will be receiving a position vector, a 3D vector stored in the variable aPos, it will have X, Y and Z co-ordinates.

out vec3 TexCoords;
This tells our shader it will be outputting a 3D vector called TexCoords to the fragment shader we will make later, you will notice it takes this as an input in the example I posted above.

uniform mat4 projection;
uniform mat4 view;
Uniforms are like Global variables for shaders. This tells us we have two of them, a 4D projection matrice and a 4D view matrice.

Like C/C++, all shaders require a main() function...

void main()
{
    TexCoords = aPos;
    vec4 pos = projection * view * vec4(aPos, 1.0);
    gl_Position = pos.xyww;
}

...in this case, this main is simple, it applies the position vector we inputted to the TexCoords output vector and sends it along to the fragment shader, doing nothing with it. Remember, a vertex shader is required, even if it does nothing to this. This also takes a 4D vector pos variable and calculates the position of the skybox and sets it using a shader variable.

There's nothing much to it honestly. The fragment shader is similar except it sets the colour of a fragment, and you can do things with it, per pixel, this is where some neat special effects are possible (a fragment is a "potential pixel", it will be converted into screen co-ordinates by your video card later on and become a pixel).

Edit: Note, this is the GLSL shader language. Microsoft has their own, similar called HLSL and no doubt Java probably has their own, I don't know. They're all fairly similar.

Edgar Reynaldo
Neil Roy said:

There's nothing else I can say. I sat here working on making a self contained project you could easily open and compile right out of the box without setup and you didn't appreciate it one bit.

I do appreciate you trying to help me with this, but I do not need 1.86GB of MSVC crap to understand it. I apologize if I wasted your time. I should have asked for less. Less is more sometimes.

If it was as simple as rendering a cube with textures, there wouldn't be a special CUBE MAP in OpenGL to do it for you. There must be something going on under the hood.

Let me try and help you understand my confusion.

Take for example this skybox texture that I got off the internet. If you look at the colored lines, those have to match exactly or else it will look completely wrong.

{"name":"611217","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/1\/d1758bcd784ad4f7989425268996385d.png","w":630,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/1\/d1758bcd784ad4f7989425268996385d"}611217

I'll see if I can come up with my own skybox using an orthographic transform and simple texturing.

Chris Katko

Yeah, but what's the problem you're trying to solve? They all look like that:

https://www.google.com/search?q=opengl+cube+map&rlz=1C1CHBD_enUS771US771&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiv3cODl-zYAhVFQ6wKHUBKDdIQ_AUICigB&biw=1000&bih=893

Are you trying to figure out how to GENERATE the cubemap texture itself, or RENDER it?

Quote:

Cube map texturing is a form of texture mapping that uses a 3D direction vector (a fancy phrase that means nothing more than a direction) to index into a texture that is six square 2D textures arranged like the faces of a cube.

http://www.nvidia.com/object/cube_map_ogl_tutorial.html

Quote:

[You mentioned the seam problem previously]Filtering does not usually take place across cubemap face boundaries. So a visible seam can appear between cubemap face boundaries regardless of the texture filtering modes. Though a setting can permit filtering between faces.

Quote:

Seamless cubemap
Seamless Cubemap Filtering
Core in version 4.6
Core since version 3.2
Core ARB extension ARB_seamless_cube_map
Under the standard filtering rules for cubemaps, filtering does not work across faces of the cubemap. This results in a seam across the faces of a cubemap. This was a hardware limitation in the past, but modern hardware is capable of interpolating across a cube face boundary.

To globally enable this, use glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS).

https://www.khronos.org/opengl/wiki/Cubemap_Texture

(Make sure you have recent drivers if you use that as some people mention failures/artifacts on older cards or very old drivers.)

NiteHackr

<sigh>

Well, it IS as simple as making a box with textures, how do I know? Because I have done it. I done it with the older fixed pipeline OpenGL (and posted code for it) and I done it with newer OpenGL with shaders, and I posted code for that too!

The image you posted is simply a collection of all the sides of a box put into one image. When I load in my images, I load them separately. You can load each side separately, or you can load in one huge image that you just shown which has all sides on it already, but it is larger because it contains whitespace. But it is fairly common way to have it all in one image, so it can be handy.

Download my City3D program and check the images I use for it for my skybox, they are all separate images for each side. There is nothing special with that huge image you showed, it is just all the sides put together like this...

{"name":"611218","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/5\/e58f3ee2a567439a9eb499f202a46e25.png","w":700,"h":525,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/5\/e58f3ee2a567439a9eb499f202a46e25"}611218

AGAIN, for the millionth time, each side is a 90 DEGREE FIELD OF VIEW. That's it!!! That's ALL THE MAGIC!!! I have done it! I know what the fuck I am talking about.

You can actually put them in any order you wish for a skybox/cubemap, so long as you render them properly etc....

{"name":"611219","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/8\/78a7eb36bb561f2c3bd39a72389848fc.png","w":534,"h":390,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/8\/78a7eb36bb561f2c3bd39a72389848fc"}611219

Edgar Reynaldo

I guess I just don't understand wtf a 90^ FOV is. Or why it looks so distorted. You can see how the corners of the images for the -X, +Z, +X, -Z directions along the middle of the image stretch up at the corners.

Take this image for example : 4 X 5 Panorama Negative

{"name":"4x5negative_panorama123_bc_small_jpeg70_by_nemonameless-d9m8n6c.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/4\/54b1826c266c95f8d6da0d9dda860ac6.jpg","w":6312,"h":2227,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/4\/54b1826c266c95f8d6da0d9dda860ac6"}4x5negative_panorama123_bc_small_jpeg70_by_nemonameless-d9m8n6c.jpg

It's only got like a 120^ wide FOV and its aspect is 3 to 1. I would have to cram another 150^ into the same image to get one of these skybox textures I've been seeing to match the same aspect ratio.

I understand the concept of a skybox and a cube map. They omit the seventh square (because it is really the same as the back texture rotated 180 degrees.
{"name":"611220","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/4\/04b5b2677530d54e338e03117a08bc44.png","w":800,"h":800,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/4\/04b5b2677530d54e338e03117a08bc44"}611220

But if you take a distorted texture, and map it onto a cube, it still looks distorted. Take this annotated image for example :
{"name":"611223","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a326f6fc7cedda7d5aefb3228409242b.png","w":800,"h":800,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a326f6fc7cedda7d5aefb3228409242b"}611223

Each individual image is terribly distorted spherically. Render that distortion onto a cube, and it will still look like crap.

Neil Roy said:

I done did it with the older fixed pipeline OpenGL (and posted code for it)

I don't remember this. Kindly provide a linky for me to clicky on quickly?

While cube maps are superior to the other approaches described, only state-of-the-art hardware supports cube map textures. The older sphere map and dual paraboloid methods for environment mapping may still be useful as a fallback when hardware cube map textures are not available. Cube map textures are more straightforward and efficient, but it good that techniques exist to support older hardware too.
...
As promised, source code for two sample programs that use the EXT_texture_cube_map extension can be found -here- (broken link).

The 4 x 5 camera I used must not have a very wide FOV. I can't remember what focal length the lens on it was either.

Chris Katko
Quote:

While cube maps are superior to the other approaches described, only state-of-the-art hardware supports cube map textures. The older sphere map and dual paraboloid methods for environment mapping may still be useful as a fallback when hardware cube map textures are not available. Cube map textures are more straightforward and efficient, but it good that techniques exist to support older hardware too.

That article describes an extension that came out... in 1999.

It's been in OpenGL core (not an extension) since 1.3.

https://www.khronos.org/opengl/wiki/Cubemap_Texture

Supporting 19 year old hardware would support... at least a few... of your current customers. But what can I say, I only support people who can afford bleeding-edge... 18 year old cards. ;D

So you'd need a monster GeForce3 with 64MB of RAM, circa 2001, to support cubemaps. And many cards support them as an extension pre-OpenGL 1.3. ;)

https://en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units#GeForce3_series

Fun fact: nVidia actually backported OpenGL 2 (shaders) into their older cards like the FX (5xxx) series that originally only supported OpenGL 1.5 (fixed pipeline).

Edgar Reynaldo

Thanks for pointing me to a 18 year out of date web page. ;)

You didn't answer any of my questions about the distortion though.

NiteHackr

Provide a link to the older code??? SCROLL UP 15 MESSAGES!!! The code is in the same message I posted my video clip in. Yeesh.

There is no distortion, if you do a 90 degree field of view on a square texture. You know what a FOV is, anyone who has played a video game knows what a FOV is.

If you use a texture that is not square (duh, it's a texture), and is not a 90 degree FOV, and you are not at the exact center of the cube (but where else would you be, it's a skybox), than you will get distortion, period.

Oh, and if you don't want to do modern OpenGL, than you need to check out 18 year old pages, because that is how long ago the older OpenGL was used and that is how far back you will need to go to get information on it. (maybe not 18 years, but damn close to it)

Most of the older tutorials are gradually disappearing or are getting 5+ years old now because everyone is starting to finally switch to modern opengl with shaders.

To insist on using older, fixed pipeline opengl, is no different than someone else insisting on sticking with Allegro 3 or 4.

I am though explaining skyboxes any further. If you can't wrap your head around them, than don't even bother with 3D as skyboxes are the simplest things to do other than a straight polygon or normal cube.

I am seriously starting to think you're just pulling my chain here.

As for support, if I can afford a GTX650, which was like $100CDN, so can anyone else. It supports DX11 and OpenGL 4.3 and they are dirt cheap. There's no excuse for not being able to do modern 3D on any computer.

Chris Katko

Side note: Intel HD can even do modern OpenGL and comes included in even the lowest of mobile chipsets.

My humble ~2013 chromebook with a Celeron and only 2 GB of RAM supports OpenGL 4.5. (Acer C720) And you can get the FOUR GB model for $89.

I think my last netbook with an old 1st gen Atom CPU still has OpenGL ~3.0.

NiteHackr

Yeah, my wife's computer was given to her for free (we got two given to us) and it has IntelHD.

Oh, and that "spherical distortion" Edgar mentions in that cubemap image, is because he is LOOKING AT A FLAT IMAGE! Of course it is distorted, it hasn't been mapped to the cube yet!

Anyhow, I am not buying that Edgar doesn't understand this. I think he's on weed or thinks he's a joker messing with people.

My humble ~2013 chromebook with a Celeron and only 2 GB of RAM supports OpenGL 4.5. (Acer C720) And you can get the FOUR GB model for $89.

My system is from like... 2011 or so? Losing track now. ;D Actually thinking about building a new system this year.

Edgar, this is why you are confused...

Wants to know modern OpenGL...

How do you render a quad in modern OpenGL?

Wants my MSVC source at 1.86G...

How many gigabytes does it take to build an msvc project these days? 1.86GB to be precise. Really, you could have just shared the source code and the models plus textures. That would have been good enough.


Doesn't want my 1.86 MSVC crap...

I do not need 1.86GB of MSVC crap to understand it

Doesn't want to learn modern OpenGL...

Katko, your links said the exact same thing Neil's do. Use a cubemap. No. I want to understand what is going on, and how to render it manually. I shouldn't need a freaking shader to render a background. That's stupid.

I don't really want to mess around with glfw and glew and glut and glad and all that crap. If I can't do it with straight Allegro and OpenGL I don't really want to do it.

Incidentally, you really do need GLEW or GLAD if you want to do modern OpenGL as they greatly simplify handling all the OpenGL extensions, which is all they are for. But then, you don't want to learn Modern OpenGL... or rather... you do... or... <confused>

:)

Chris Katko

The only other thing I can think is maybe Edgar's got the wrong texture WRAPPING/clamping mode set?

Ala example here, which should be enough code for him to use:

https://www.opengl.org/discussion_boards/showthread.php/170050-Cube-Mapping-Using-OpenGL

[edit] Well, maybe it's not the perfect example thread, but it shows the wrap calls.

[edit] WOW, I was poking around my OpenGL supported extensions and found this gem:

https://github.com/KhronosGroup/OpenGL-Registry/blob/master/extensions/INTEL/INTEL_performance_query.txt

Tons of hardware performance counters for debugging/profiling. I know their CPUs have tons of that stuff too. But it's neat to know you can get statistics on number of shader calls, etc--even if it's on a piece-of-crap integrated intel graphics card.

It may come in handy later to tweak my games for low end systems.

[edit] Okay, so nVidia (and AMD) also have Perf kits!

https://developer.nvidia.com/nvidia-perfkit

Of course it only runs on Windows... because nVidia is a bunch of @!#$!'s.

Meanwhile, AMD's does.

https://developer.amd.com/gpuperfapi/

And not only that, they're OPEN SOURCE:

https://gpuopen.com/gaming-product/gpuperfapi/

NiteHackr

The only other thing I can think is maybe Edgar's got the wrong texture WRAPPING/clamping mode set?

Nah, he's looking at the flat cube map and wondering about the distortions at the corners. Well, they're distorted for good reason, because he's looking at them all flattened out instead of from the inside of a cube with them on the sides. :) Once it is inside a cube, there are no distortions because... ah, forget it.

Quote:

Tons of hardware performance counters for debugging/profiling.

There's where things like GLEW (open GL Extension Wrangler) and GLAD help (both do the same thing, take your pick). They figure out which extensions your card can use and then set all that up for you so you don't have to worry about it. You just... use OpenGL. They're really quite handy and pretty much all tutorials on the subject of OpenGL will mention using one of them (usually GLEW as it has been around longer).

BUT, you don't NEED them, you can do OpenGL with Allegro without GLEW or GLAD or anything else. You'll just have to handle any extension issues yourself, and there were a lot of new functionality added to OpenGL and some different video cards use differently named functions, which is why GLEW and GLAD are so great, you don't have to worry about that, and if you're going to give out your program, you better make certain it can handle different commands on different cards. Have fun with that without something like GLEW or GLAD! :)

But just for straight, old opengl, you could do without it. Good for learning I guess.

Maybe I'll sit down and make a simple Skybox with OpenGL and Allegro, but I really don't want to do much with Allegro anymore. Edit: changed my mind, I'll pass on Allegro coding. I'll leave the OpenGL + Allegro stuff with Edgar (https://www.allegro.cc/forums/thread/617199). I want to switch to SDL2, but that's another subject. It really doesn't matter which you use as Allegro and SDL2 and GLFW are all just interfaces to set up a window and opengl context.

The tutorial I linked to at the start of this just happens to use GLFW, which I am using just so I can concentrate on learning the newer OpenGL instead of figuring out how to get it all working with Allegro or SDL2. I'm even doing C++ coding which I can't stand! But I plan to convert my personal 3D project to SDL2 & pure C. I also want to convert my projects to Code::Blocks/MinGW as I am not a fan of the convoluted crap that is MSVC! ;)

My City3D program is coded using Code::Blocks and NO other libs, not Allegro, not SDL2... just plain old Win32 stuff, OpenGL and pure C code.

Edgar Reynaldo

I'm in the middle of a long post and Windoze decides to pull it's forceful shutdown and update mode on me. It's been working for half an hour and it's only 25% done. Lame. ;P It's holding my computer hostage.

I'm coding a skybox from scratch with allegro and "old" OpenGL. If it's really as simple as rendering a cube, I'll shit myself.

May take me a while though. Sigh.

NiteHackr

Here, you may need this. ;D
{"name":"611227","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/3\/b3133f60c7391cbac02cd8c1ddc1a601.jpg","w":2200,"h":2017,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/3\/b3133f60c7391cbac02cd8c1ddc1a601"}611227

It really is just that simple. Let me try and explain again. The key things to remember is;

1) Make a square cube. Obviously.
2) Texture each side with an image that was rendered with a 90 degree field of view. If you ever played a video game, your FOV is usually 45 - 65 degrees, and you can often adjust it. at 90 degrees you see a much wider area and it seems distorted. When you look at a cube map, as you did, it looks distorted, but that is because you're looking at a flat image. Remember, those maps, usually a cross shaped map, is simple an unfolded cube. Once you fold it up back into a cube, those distorted corners will look normal and no longer distorted from inside the cube.
3) Make certain your point of view is in the exact center of it, or you will notice distortions.
4) Make certain you have NO lighting on the cube. Usually I just pick a colour, like pure white for the sides, it will lighten up the textures without applying any shadows to the corners etc.
5) Make sure you clamp the textures, but then you would do this normally for all 3D models and such so you don't see seams.
6) Turn off anything else that can effect the cube, like fog and depth testing.

In older opengl you draw the skybox first, depth testing disabled, then once it is drawn, you can turn it back on along with lighting and such.

The view from the inside of the cube will appear normal, no distortions etc. The total view around you is 360 degrees, each side is a 90 degree portion of that view. YOU won't be looking at the entire side though once you are viewing it, only part of it, depending on your own field of view you set, most people set it to 45, I like 60 degrees. So, no distortion. You rotate the cube around you, but do not translate it and it will work out fine.

I seen your Allegro OpenGL code and it looked great! You made a cube, just need to make it bigger maybe, and put yourself in the center of it with the textures.

Oh, and if you want to make your own skybox renders, try and hunt down an older copy of Teragen, it was free (version 0.9.43). It limits the size you can render to, unregistered (can't register it either, too old), but you can render 512x512 sized textures which are fine for skyboxes. Set the ZOOM factor to 1 even, that will be 90 degrees, then you create a landscape, set your heading to 0 etc.. all to zero so you are looking straight north and render, that will be your FRONT texture, then, while looking north (important) you set your pitch to -90 (straight up) and render again, that will be UP. Then set the pitch to +90, straight down, render again, DOWN view. Then set your pitch to zero and your heading to -90, that will be your left view, +90 heading is right view, +180 heading is back view. Presto, you're done.

For making them as photographs it is more difficult because you need that 90 degree FOV, but there are tutorials online that show you how, and probably the right camera. I just have never bothered, I can render what I need just fine, or find stuff via Google.

This is one I made last night just for fun... called Mars...
{"name":"611228","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/a\/7a572cd506f72b05c9cf2c2b7b63077d.png","w":2048,"h":1536,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/a\/7a572cd506f72b05c9cf2c2b7b63077d"}611228

Elias

Btw. Allegro comes with an example that displays a skybox: https://github.com/liballeg/allegro5/blob/master/examples/ex_camera.c

Edgar Reynaldo
Neil Roy said:

Here, you may need this.

I always knew you rolled your toilet paper upside down. Blasphemy!

Elias said:

an example that displays a skybox

{"name":"611229","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/e\/9e5bed09f24e3dc30de79ffc7a979c06.png","w":642,"h":401,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/e\/9e5bed09f24e3dc30de79ffc7a979c06"}611229
Nice corner. :/

Still working on my example. Will report back.

bamccaig

I always knew you rolled your toilet paper upside down. Blasphemy!

Here, here!

NiteHackr

I always knew you rolled your toilet paper upside down. Blasphemy!

Actually, mine is hung properly, only not on a normal roll, but I have a hanger I bent so that I can hang in from a towel rack and not have to become a contortionist to use it! 8-)

{"name":"611230","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/8\/888f58fb9b21db36c295f6fa228cc9ff.jpg","w":512,"h":695,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/8\/888f58fb9b21db36c295f6fa228cc9ff"}611230

Ariesnl

Some things are the same in every part of the world. ;D
I wonder what they use in the amazon forrest

Chris Katko

I imagine they use something involving The Cloud.

NiteHackr
Ariesnl said:

I wonder what they use in the amazon forrest

Probably small furry creatures. ;D

Edgar Reynaldo

My skybox is seriously messed up.

EDIT
{"name":"611235","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/170e1bca67919e58d6529e9187c92fa2.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/170e1bca67919e58d6529e9187c92fa2"}611235
{"name":"611236","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/c\/dc131e5187f62ae06b579cf24812e71a.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/c\/dc131e5187f62ae06b579cf24812e71a"}611236

Chris Katko

It's a feature!

You're just holding the monitor wrong.

Edgar Reynaldo

I tried to do it with just one texture but my tex coords must be off. I'm also drawing the cube with two triangle fans, because two opposing vertices touch all the other faces. Gonna take a look at your City3D program a little later for some hints. I still don't think it's going to look right.

NiteHackr

Looks like you're using an orthographic view instead of a perspective one.

Here's the complete source code with Code::Blocks project for my City3D. It's a project I have been messing around with since 2004. It includes a separate Allegro 4 project for the map editor (already compiled), it's just a 2D editor that saves to the same map name each time. If you're curious about other maps, just rename them to city.map and the program will load them.

The main program doesn't use Allegro, it doesn't use anything (except the freeimage library, though I have separate code to load uncompressed TGAs which can be used instead). This is a Windows (IE: WinMain()) project, no allegro, no sdl2, nothing. It was something I started in order to learn a little straight Windows coding. The OpenGL stuff is pretty straight forward, if you can handle my coding style and C only code.

Oh, and I changed my code to use all QUADS, no triangles, though they could be used, I tried to keep it as simple as possible to make learning OpenGL easier, which is why I also stuck to a grid layout and cubes at the time (before Minecraft! heh).

I added in keys (listed on the main screen when you run it) to show wireframe mode, so you can see what is drawn. TO enable/disable Vsync, to enable/disable fullscreen mode, disable the onscreen text (except the FPS) which can speed things up a tad. SHIFT key goes super fast, use E and Q to fly up in the air (better when zipping around the map). Frustum culling can be toggled, note, my frustum culling is simple, and only culls to the right and left, but doesn't take into account your angle looking up and down (because this was meant to be only driving, no flying and looking up and down). You can toggle the skybox on and off as well etc... the code may help. Maybe try converting this to use Allegro as the main framework? I plan to convert this to modern opengl, should be interesting to see the FPS difference.

https://www.dropbox.com/s/r4bea14ll60vcz9/City3D_source.7z?dl=0

Edgar Reynaldo

Been up all night and the coffee house network has banned Dropbox, so I'll get it a little later. Need some zzzzs.

bamccaig

Hah, I stayed up all night too. I feel like shit today though. :(

Append:

I guess this wasn't the O/T thread... Whoops.

Edgar Reynaldo

I don't know what I'm doing wrong. My cube coordinates look right, and so do my texture coordinates.

{"name":"611241","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d6d68a2224a1ecd4d3cb22580ea3a32b.png","w":1365,"h":847,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d6d68a2224a1ecd4d3cb22580ea3a32b"}611241

Elias

I think it would be nice adding an actual texture to the ex_camera skybox - maybe I'll do that tonight. The skybox code in there originally is from a textured version so I can just copy&paste it back in and I'll add a command-line paramater to specify a picture with the skybox.

Otherwise, from your screenshot it definitely looks like some of the UV coordinates are off. Also - are you sure your camera is inside of your box? It won't work if you look at it from the outside.

Edgar Reynaldo

That screenshot is with an orthographic projection, so I can see the cube, because for some reason it doesn't show up when I use a perspective projection. I'll put my code up on GitHub. https://github.com/EdgarReynaldo/Skybox

EDIT
I enabled GL_CULL_FACE, I set the front face to GL_CCW, and I set it to cull backfaces, but I see the outside of my skybox. What gives? I know I wound the vertices in CCW order.

EDIT2
My skybox and my cube are both inside out, but I don't know why.

EDIT3
I think it has something to do with the handedness of OpenGL. My vertices are wound perfectly counterclockwise, but when I print them out, they are wound in clockwise order? WTF?

NiteHackr

You're using Orthographic projection. That is not 3D and will never work.

Elias

Here is an updated ex_camera: https://github.com/liballeg/allegro5/compare/master...allefant:skybox

I called it like this: ./ex_camera /tmp/skybox.png

And it looks like this:

There is some white border around the top face but I think that's because of Neil's source picture, adding a few pixels where he has white there likely would fix it!

{"name":"611244","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/496cc9b40906b13bfa6cceed84e840f8.png","w":1140,"h":739,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/496cc9b40906b13bfa6cceed84e840f8"}611244

NiteHackr

I never did test that image. Is it edge clamped? I attached the original separate images in a 7z to this message if you want to work with them, to redo that.

Elias

Ha, no, I just used the picture you posted and set the U/V coordinates to 0.25/0.33 - so they simply include the white pixels. Only hacked it in in half an hour or so. Just wanted to confirm that indeed all you do is paste a texture on the inside of an unlit untranslated cube - and ex_camera already was doing everything (except apply a texture).

NiteHackr

Ah, okay. Yeah, it is much simpler than some realize. A sort of optical illusion. The concept is simple enough. If you want a 360 degree view all around you, and you have four sides all the same size, than you make each view 360/4 degrees, or a 90 degree field of view.

Terragen is handy for that, it's what I used. It doesn't have degrees (the old version anyhow), but the ZOOM factor when set to 1 even, equals 90 degree field of view. After that, just render each direction to a 512x512 texture and you're all set.

Anyhow, the original pics are in that zip if anyone wants them separate. I only done it in that single cross shape because that is the most common I find online.

Thread #617205. Printed from Allegro.cc