Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » Learn OpenGL

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
Learn OpenGL
Chris Katko
Member #1,881
January 2002
avatar

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

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

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
Member #8,592
May 2007
avatar

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?

Neil Roy
Member #2,229
April 2002
avatar

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
Member #8,592
May 2007
avatar

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.

Neil Roy
Member #2,229
April 2002
avatar

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
Member #8,592
May 2007
avatar

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
Member #1,881
January 2002
avatar

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

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Edgar Reynaldo
Member #8,592
May 2007
avatar

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.

Neil Roy
Member #2,229
April 2002
avatar

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
Member #1,881
January 2002
avatar

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.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

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
Member #8,592
May 2007
avatar

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
Member #1,881
January 2002
avatar

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.)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

<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
Member #8,592
May 2007
avatar

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
Member #1,881
January 2002
avatar

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).

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Edgar Reynaldo
Member #8,592
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

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
Member #1,881
January 2002
avatar

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.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

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
Member #1,881
January 2002
avatar

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/

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Neil Roy
Member #2,229
April 2002
avatar

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
Member #8,592
May 2007
avatar

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.

Neil Roy
Member #2,229
April 2002
avatar

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

 1   2   3 


Go to: