I'm having a problem in OpenGL, when I press W, A, S, D everything works normal, but when I press space or shift it happens:
The cube disappears before the end of the screen. Depending on the value of xrot and yrot another axis gets this problem.
I'm a beginner in openGL 3D and I don't know why that happens.
code:
float xrot = 100.0f;
float yrot = -100.0f;
float tra_x = 0.0f;
float tra_y = 0.0f;
float tra_z = 0.0f;
GLFWwindow* window;
void drawBox()
{
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glEnable(3553);
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
// FRONT
glVertex3f(-0.5f, -0.5f, 0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
// BACK
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
// LEFT
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
// RIGHT
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
// TOP
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glColor3f(1.0f, 0.0f, 0.0f);
// BOTTOM
glVertex3f(-0.5f, -0.5f, 0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
}
void display(void)
{
glDisable(GL_BLEND);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(yrot, -1.0f, 0.0f, 0.0f);
glRotatef(xrot, 0.0f, 1.0f, 0.0f);
glTranslatef(-tra_x, tra_y, -tra_z);
drawBox();
glFlush();
glfwSwapBuffers(window);
}
void framebuffer_resize_callback(GLFWwindow* window, int fbW, int fbH)
{
glViewport(0, 0, fbW, fbH);
}
int main(void)
{
if (!glfwInit())
return -1;
glfwWindowHint(GLFW_SAMPLES, 2);
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_resize_callback);
glfwMakeContextCurrent(window);
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0f);
while (!glfwWindowShouldClose(window))
{
display();
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
tra_x += 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
tra_x -= 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
tra_z -= 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
tra_z += 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
tra_y += 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
tra_y -= 0.1f;
}
glfwPollEvents();
}
}
The object is clipped by the fare plane of the Orthographic projection. The projection matrix defines the volume (clip space) which is projected on to 2 dimensional viewport. Actually you don't set a projection matrix, thus the projection is the Identity matrix. Hence, view space, clip space and normalized device space are the same and the viewing volume is a unique cube, with the left, bottom, near of (-1, -1, -1) and the right, top, far of (1, 1, 1). Hence the near plane is at -1 and the far plane is at 1. All the geometry which is out of this space is clipped.
Use glOrtho to define a clip space with a larger scale. For instance:
void display(void)
{
// [...]
# set projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, -1, -10, 10); // near = -10, far = 10
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// [...]
Alternatively you can use Perspective projection. At perspective projection the viewing volume is a [Frustum](https://en.wikipedia.org/wiki/Viewing_frustum. Hence you have to shift the object along the negative z axis in between the near and far plane.
Create a perspective projection by gluPerspective and move the object in between then near and far plane by gluLookAt:
void display(void)
{
// [...]
# set projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glOrtho(-1, 1, -1, -1, -10, 10); // near = -10, far = 10
gluPerspective(90.0, 480.0/640.0, 0.1, 20.0)
// set view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 5.0, 0, 0, 0, 0, 1.0, 0);
// [...]
What exactly are eye space coordinates?
Related
I read similar suggested questions and their solutions, but could not find an answer.
I'm trying to draw a scene with an isometric view in OpenGL.
Draw func:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
glPopMatrix();
In the end, I get this result. The camera does have an isometric projection, but for some reason polygons are clipped.
If I add glTranslatef(-0.8f, 0, -0.8f) before drawing the quad, the result is as follows:
The problem is that I don't apply any optimization to OpenGL render. But why do polygons have to be cut off?
The polygons are clipped by the near or far plane of the viewing volume.
When you do not set a projection matrix, then view space, clip space and normalized device space are the same. The normalized device space is a unique cube with the left, bottom, near of (-1, -1, -1) and right, top, far of (1, 1, 1). All the geometry which is not inside this cube is clipped.
Actually you draw a quad with a side length of 1. One vertex of the quad is at the origin of the view (0, 0, 0). The quad is rotated around the origin by glRotate. Since the length of the diagonal of the quad is sqrt(2.0), one vertex of the rotated quad is clipped by either the near plane or the far plane.
If you construct and rotate a quad whose center is (0, 0 ,0), it will not be clipped, because the length form the center to each vertex is sqrt(2.0)/2.0. That is less than 1 (distance to near and far plane form the center of the viewing volume)
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f, 0.5f);
glVertex3f(-0.5f, 0.0f, 0.5f);
glEnd();
respectively
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glTranslate(-0.5f, 0.0f, -0.5f);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
Alternatively you can set an Orthographic projection, which enlarges the viewing volume by glOrtho:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
I am working on making a tower defense game in C++ using OpenGL. When trying to utilize the "sleep" function from Windows.H it causes my OpenGL window to open the total time of whatever value I put into Sleep and then opens the window. Any suggestions?
#include <GLFW/glfw3.h>
#include <iostream>
#include <Windows.h>
void enemy(int num) //Written By Ryan
{
switch (num)
{
case 1: glBegin(GL_TRIANGLES); //Position 3
glColor3ub(255, 0, 0);
glVertex2f(0.25, 0.9);
glVertex2f(0.1, 0.6);
glVertex2f(0.4, 0.6);
glEnd();
break;
case 2: glBegin(GL_TRIANGLES); //Position 6
glColor3ub(255, 0, 0);
glVertex2f(0.25, 0.4);
glVertex2f(0.1, 0.1);
glVertex2f(0.4, 0.1);
glEnd();
break;
case 3: glBegin(GL_TRIANGLES); //Position 7
glColor3ub(255, 0, 0);
glVertex2f(-0.25, 0.4);
glVertex2f(-0.4, 0.1);
glVertex2f(-0.1, 0.1);
glEnd();
break;
case 4: glBegin(GL_TRIANGLES); //Position 10
glColor3ub(255, 0, 0);
glVertex2f(-0.25, -0.1);
glVertex2f(-0.4, -0.4);
glVertex2f(-0.1, -0.4);
glEnd();
break;
case 5: glBegin(GL_TRIANGLES); //Position 14
glColor3ub(255, 0, 0);
glVertex2f(-0.25, -0.6);
glVertex2f(-0.4, -0.9);
glVertex2f(-0.1, -0.9);
glEnd();
break;
}
}
void map()
{
glColor3ub(0, 128, 0); // set color green
//Position 1
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f); //top left
glVertex3f(-1.0f, 0.5f, 0.0f);//bottom left
glVertex3f(-0.5f, 0.5f, 0.0f); //bottom right
glVertex3f(-0.5f, 1.0f, 0.0f); //top right
glEnd();
//Position 2
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f); //top left
glVertex3f(-0.5f, 0.5f, 0.0f);//bottom left
glVertex3f(0.0f, 0.5f, 0.0f); //bottom right
glVertex3f(0.0f, 1.0f, 0.0f); //top right
glEnd();
//Position 3
glColor3ub(139, 69, 19); // set color brown
glBegin(GL_QUADS);
glVertex3f(0.0f, 1.0f, 0.0f); //top left
glVertex3f(0.0f, 0.5f, 0.0f);//bottom left
glVertex3f(0.5f, 0.5f, 0.0f); //bottom right
glVertex3f(0.5f, 1.0f, 0.0f); //top right
glEnd();
//Position 4
glColor3ub(0, 128, 0); // set color green
glBegin(GL_QUADS);
glVertex3f(0.5f, 1.0f, 0.0f); //top left
glVertex3f(0.5f, 0.5f, 0.0f);//bottom left
glVertex3f(1.0f, 0.5f, 0.0f); //bottom right
glVertex3f(1.0f, 1.0f, 0.0f); //top right
glEnd();
//Position 5
glBegin(GL_QUADS);
glVertex3f(-1.0f, .5f, 0.0f); //top left
glVertex3f(-1.0f, 0.0f, 0.0f);//bottom left
glVertex3f(-0.5f, 0.0f, 0.0f); //bottom right
glVertex3f(-0.5f, 0.5f, 0.0f); //top right
glEnd();
//Position 6
glColor3ub(139, 69, 19); // set color brown
glBegin(GL_QUADS);
glVertex3f(-0.5f, 0.5f, 0.0f); //top left
glVertex3f(-0.5f, 0.0f, 0.0f);//bottom left
glVertex3f(0.0f, 0.0f, 0.0f); //bottom right
glVertex3f(0.0f, 0.5f, 0.0f); //top right
glEnd();
//Position 7
glBegin(GL_QUADS);
glVertex3f(0.0f, 0.5f, 0.0f); //top left
glVertex3f(0.0f, 0.0f, 0.0f);//bottom left
glVertex3f(0.5f, 0.0f, 0.0f); //bottom right
glVertex3f(0.5f, 0.5f, 0.0f); //top right
glEnd();
//Position 8
glColor3ub(0, 128, 0); // set color green
glBegin(GL_QUADS);
glVertex3f(0.5f, 0.5f, 0.0f); //top left
glVertex3f(0.5f, 0.0f, 0.0f);//bottom left
glVertex3f(1.0f, 0.0f, 0.0f); //bottom right
glVertex3f(1.0f, 0.5f, 0.0f); //top right
glEnd();
//Position 9
glBegin(GL_QUADS);
glVertex3f(-1.0f, 0.0f, 0.0f); //top left
glVertex3f(-1.0f, -0.5f, 0.0f);//bottom left
glVertex3f(-0.5f, -0.5f, 0.0f); //bottom right
glVertex3f(-0.5f, 0.0f, 0.0f); //top right
glEnd();
//Position 10
glColor3ub(139, 69, 19); // set color brown
glBegin(GL_QUADS);
glVertex3f(-0.5f, 0.0f, 0.0f); //top left
glVertex3f(-0.5f, -0.5f, 0.0f);//bottom left
glVertex3f(0.0f, -0.5f, 0.0f); //bottom right
glVertex3f(0.0f, 0.0f, 0.0f); //top right
glEnd();
//Position 11
glColor3ub(0, 128, 0); // set color green
glBegin(GL_QUADS);
glVertex3f(0.0f, 0.0f, 0.0f); //top left
glVertex3f(0.0f, -0.5f, 0.0f);//bottom left
glVertex3f(0.5f, -0.5f, 0.0f); //bottom right
glVertex3f(0.5f, 0.0f, 0.0f); //top right
glEnd();
//Position 12
glBegin(GL_QUADS);
glVertex3f(0.5f, 0.0f, 0.0f); //top left
glVertex3f(0.5f, -0.5f, 0.0f);//bottom left
glVertex3f(1.0f, -0.5f, 0.0f); //bottom right
glVertex3f(1.0f, 0.0f, 0.0f); //top right
glEnd();
//Position 13
glBegin(GL_QUADS);
glVertex3f(-1.0f, -0.5f, 0.0f); //top left
glVertex3f(-1.0f, -1.0f, 0.0f);//bottom left
glVertex3f(-0.5f, -1.0f, 0.0f); //bottom right
glVertex3f(-0.5f, -0.5f, 0.0f); //top right
glEnd();
//Position 14
glColor3ub(139, 69, 19); // set color brown
glBegin(GL_QUADS);
glVertex3f(-0.5f, -0.5f, 0.0f); //top left
glVertex3f(-0.5f, -1.0f, 0.0f);//bottom left
glVertex3f(-0.0f, -1.0f, 0.0f); //bottom right
glVertex3f(-0.0f, -0.5f, 0.0f); //top right
glEnd();
//Position 15
glColor3ub(0, 128, 0); // set color green
glBegin(GL_QUADS);
glVertex3f(0.0f, -0.5f, 0.0f); //top left
glVertex3f(0.0f, -1.0f, 0.0f);//bottom left
glVertex3f(0.5f, -1.0f, 0.0f); //bottom right
glVertex3f(0.5f, -0.5f, 0.0f); //top right
glEnd();
//Position 16
glBegin(GL_QUADS);
glVertex3f(0.5f, -0.5f, 0.0f); //top left
glVertex3f(0.5f, -1.0f, 0.0f);//bottom left
glVertex3f(1.0f, -1.0f, 0.0f); //bottom right
glVertex3f(1.0f, -0.5f, 0.0f); //top right
glEnd();
}
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(1000, 1000, "Aloha Tower Defence", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
std::cout << glGetString(GL_VERSION) << std::endl;
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
//'The' Loop
for (int x = 0; x <= 5; x++)
{
// glClear(GL_COLOR_BUFFER_BIT);
map();
enemy(x);
Sleep(100);
}
// glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
map();
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
So above causes the window to sit and do nothing for 100 miliseconds (*5 because of the loop value) and then it opens the window and displays Enemy at x value 5. I want to see the enemy "move" down the board from x values 1-5
You have to use the application loop. Add a variable x and increment the variable in the loop:
int x = 0;
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
//'The' Loop
glClear(GL_COLOR_BUFFER_BIT);
map();
enemy(x);
if (x < 5)
x += 1;
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
Sleep(100);
}
Instead of Sleep you can use glfwGetTime, which retrieves the time in seconds, since glfw was initialized:
int x = 0;
double startTime = glfwGetTime();
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
double currentTime = glfwGetTime();
/* Render here */
//'The' Loop
glClear(GL_COLOR_BUFFER_BIT);
map();
enemy(x);
if (x < 5 && (currentTime - startTime) > x * 0.1)
x += 1;
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
I am currently rendering a solar system of planets in my 3d space but every single planet is black even when light hits the sphere. The spheres are rendered last in my render function. Had the colors working when the spheres were being rendered on their own but now i've added my sky box and other quads all the spheres refuse to be colored.
#include "Scene.h"
float rotation;
float rotation2;
int direction;
int speed;
Scene::Scene(Input *in)
{
// Initialise variables
rotation = 20;
rotation2 = 0;
direction = 1;
speed = 5;
myTexture = 0;
skyBox = 0;
// Store pointer for input class
input = in;
// OpenGL settings
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.39f, 0.58f, 93.0f, 1.0f); // Cornflour Blue Background
glClearDepth(1.0f); // Depth Buffer Setup
glClearStencil(0); // Clear stencil buffer
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable(GL_LIGHTING); // Enables Lighting
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
// Other OpenGL / render setting should be applied here.
myTexture = SOIL_load_OGL_texture
(
"gfx/neongrid.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
skyBox = SOIL_load_OGL_texture
(
"gfx/starField.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
camera = new Camera();
}
void Scene::update(float dt)
{
// Update camera position
camera->update(input, dt);
// Handle user input
if (input->isKeyDown(43))
{
direction = 1;
input->SetKeyUp(43);
}
else if (input->isKeyDown(45))
{
direction = -1;
input->SetKeyUp(45);
}
// Update scene related variables
rotation += speed * dt;
rotation2 += (speed *2) * dt;
if (input->isKeyDown('p') && WF == false)
{
WF = true;
input->SetKeyUp('p');
glPolygonMode(GL_FRONT, GL_LINE);
}
if (input->isKeyDown('p') && WF == true)
{
WF = false;
input->SetKeyUp('p');
glPolygonMode(GL_FRONT, GL_FILL);
}
// Calculate FPS for output
calculateFPS();
}
void Scene::render() {
// Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z,
camera->getLookAt().x, camera->getLookAt().y, camera->getLookAt().z,
camera->getUp().x, camera->getUp().y, camera->getUp().z);
glutWarpPointer(400, 300);
glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR);
// Lighting
GLfloat Light_Ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat Light_Diffuse[] = { 9.0f, 9.0f, 9.0f, 1.0f };
GLfloat Light_Position[] = { 2.0f, 2.0f, 2.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, Light_Ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Light_Diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, Light_Position);
glEnable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
#pragma region skybox
glPushMatrix();
glTranslatef(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z);
glBindTexture(GL_TEXTURE_2D, skyBox);
glBegin(GL_QUADS);
//Back
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
//Right
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
//front
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
//left
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
//top
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
//bottom
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
#pragma endregion
glEnable(GL_DEPTH_TEST);
glPopMatrix();
glPushMatrix();
#pragma region wall
glBindTexture(GL_TEXTURE_2D, myTexture);
glTranslatef(0.0, 0.0, 0.0);
glScalef(5.0f, 5.0f, 5.0f);
glBegin(GL_QUADS);
// first face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// second face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
// third face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
// fourth face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
glPopMatrix();
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, myTexture);
glScalef(5.0f, 5.0f, 5.0f);
glBegin(GL_QUADS);
// first face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
// second face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
// third face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 0.0f, -1.0f);
// fourth face
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, -1.0f);
glEnd();
#pragma endregion
glPopMatrix();
glPushMatrix();
// Render sun
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, NULL);
glTranslatef(0.5, 0.5, -0.5);
glColor3f(1.0f, 0.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPushMatrix(); // Push for default matrix
// Render Planet 1
glRotatef(rotation, 0.5, 0.5, 0);
glTranslatef(0, 0, 1);
glScalef(1, 1, 1);
glColor3f(0.0f, 2.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 10, 10);
glPopMatrix(); // Pop off stack back to sun matrix
glPushMatrix(); // Push for default matrix
// Render Planet 2
glRotatef(rotation2, 0, 1, 0);
glTranslatef(2, 0, 0);
glScalef(0.5, 0.5, 0.5);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 5, 5);
glPushMatrix(); // Pop back to sun
// Render a moon around Planet 2
glRotatef((rotation*2.0), 0, 1, 0);
glTranslatef(1.5, 0, 0);
glScalef(0.3, 0.3, 0.3);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPopMatrix(); // Pop to planet 2
glPushMatrix(); // Push for default matrix
// Render a SECOND moon around Planet 2
glRotatef((rotation * 2), 0, 0, 1);
glTranslatef(1.5, 0, 0);
glScalef(0.3, 0.3, 0.3);
glColor3f(0.0f, 0.0f, 1.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPopMatrix();
//glPopMatrix();
glPopMatrix(); // Go back to sun!
glPushMatrix();
glTranslatef(2, 2, 2);
glColor3f(1, 0, 0);
gluSphere(gluNewQuadric(), 0.5, 20, 20);
glPopMatrix();
// End render geometry --------------------------------------
// Render text, should be last object rendered.
renderTextOutput();
// Swap buffers, after all objects are rendered.
glutSwapBuffers();
}
// Handles the resize of the window. If the window changes size the perspective matrix requires re-calculation to match new window size.
void Scene::resize(int w, int h)
{
width = w;
height = h;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if (h == 0)
h = 1;
float ratio = (float)w / (float)h;
fov = 45.0f;
nearPlane = 0.1f;
farPlane = 100.0f;
// Use the Projection Matrix
glMatrixMode(GL_PROJECTION);
// Reset Matrix
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(fov, ratio, nearPlane, farPlane);
// Get Back to the Modelview
glMatrixMode(GL_MODELVIEW);
}
// Calculates FPS
void Scene::calculateFPS()
{
frame++;
time = glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000) {
sprintf_s(fps, "FPS: %4.2f", frame*1000.0 / (time - timebase));
timebase = time;
frame = 0;
}
}
// Compiles standard output text including FPS and current mouse position.
void Scene::renderTextOutput()
{
// Render current mouse position and frames per second.
sprintf_s(mouseText, "Mouse: %i, %i", input->getMouseX(), input->getMouseY());
displayText(-1.f, 0.96f, 1.f, 0.f, 0.f, mouseText);
displayText(-1.f, 0.90f, 1.f, 0.f, 0.f, fps);
}
// Renders text to screen. Must be called last in render function (before swap buffers)
void Scene::displayText(float x, float y, float r, float g, float b, char* string) {
// Get Lenth of string
int j = strlen(string);
// Swap to 2D rendering
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, 5, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Orthographic lookAt (along the z-axis).
gluLookAt(0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// Set text colour and position.
glColor3f(r, g, b);
glRasterPos2f(x, y);
// Render text.
for (int i = 0; i < j; i++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]);
}
// Reset colour to white.
glColor3f(1.f, 1.f, 1.f);
// Swap back to 3D rendering.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, ((float)width/(float)height), nearPlane, farPlane);
glMatrixMode(GL_MODELVIEW);
}
Updated sun code :
// Render sun
glTranslatef(0.5, 0.5, -0.5);
glColor3f(1.0f, 0.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 20, 20);
glPushMatrix(); // Push for default matrix
// Render Planet 1
glRotatef(rotation, 0.5, 0.5, 0);
glTranslatef(0, 0, 1);
glScalef(1, 1, 1);
glColor3f(0.0f, 2.0f, 0.0f);
gluSphere(gluNewQuadric(), 0.20, 10, 10);
glPopMatrix(); // Pop off stack back to sun matrix
glPushMatrix(); // Push for default matrix
Found out i was missing a OpenGL setting
glEnable(GL_COLOR_MATERIAL);
Inserted at the start of Scene
Try to end glEnable(GL_TEXTURE_2D); with glDisable(GL_TEXTURE_2D); after you render sun.
If problem appeared after you added skybox. Check if vertices are in right order.
I'm pretty sure this is due to my lack of understanding of how the GL_MODELVIEW matrix works. Here is a screen recording of what's happening: http://youtu.be/3F7FLkVI7kA
As you can see, the bottom-most triangle is the first triangle being drawn, and moves as I expect the other 2 triangles to move. The second triangle is moved and rotated relative to the first, and the third is moved and rotated relative to that combination.
What I want is for all three triangles to be stationary in 3D space, but spinning (like the first triangle).
Source:
// Main loop
do {
// Clear Screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update camera
glfwGetCursorPos(window, &cursorX, &cursorY);
cam.update(0.001f, (int)cursorX, (int)cursorY);
// Reset Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move camera
glRotatef(cam.rotation.x, 1.0f, 0.0f, 0.0f);
glRotatef(cam.rotation.y, 0.0f, 1.0f, 0.0f);
// translate modelview matrix to position of the camera - everything should now draw relative to camera position
glTranslatef(-cam.position.x, cam.position.y, -cam.position.z);
// Draw ground
drawGroundGrid(-25.0f);
drawSpinningTriangle(0.0f, 0.0f, -5.0f);
drawSpinningTriangle(3.14f, 3.0f, -6.0f);
drawSpinningTriangle(-6.0f, 12.0f, -5.0f);
// Swap buffers - back buffer is now front buffer to be rendered to next frame
glfwSwapBuffers(window);
glfwPollEvents();
calcFPS();
} while (!glfwGetKey(window, GLFW_KEY_ESCAPE) && !glfwWindowShouldClose(window));// Main Loop End
[...]
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
}
First using the matrix stack is deprecated. It's much better to manage your own matrices
Second you should pushMatrix and popMatrix before the transformations and after drawing:
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
glPopMatrix();
}
This will save and restore the top most matrix so any changes between the 2 calls are removed.
HI I am starting to learn openGl for C++.but at stating point I stucked.
I have 2 question that is the coordinates for drawing some objects? I mean where is X, Y and Z?
Second one I am making tutorial from some sites. and I am trying to animate my triangle.In tutorial it works but on my computer not.I Also downloaded source codes but It doesnt move. And there is no compiler error.
Edit:I solved problem. With restarting computer.I think it is poblem about my computer.
Here sample codes. I thougt that problem is glutTimerFunc().
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include<OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <gl/glut.h>
#endif
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 30.0f;
float _cameraAngle = 0.0f;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the camera
glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
glPushMatrix(); //Save the transformations performed thus far
glTranslatef(0.0f, -1.0f, 0.0f); //Move to the center of the trapezoid
glRotatef(_angle, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
glBegin(GL_QUADS);
//Trapezoid
glVertex3f(-0.7f, -0.5f, 0.0f);
glVertex3f(0.7f, -0.5f, 0.0f);
glVertex3f(0.4f, 0.5f, 0.0f);
glVertex3f(-0.4f, 0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the trapezoid
glPushMatrix(); //Save the current state of transformations
glTranslatef(1.0f, 1.0f, 0.0f); //Move to the center of the pentagon
glRotatef(_angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
glScalef(0.7f, 0.7f, 0.7f); //Scale by 0.7 in the x, y, and z directions
glBegin(GL_TRIANGLES);
//Pentagon
glVertex3f(-0.5f, -0.5f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the pentagon
glPushMatrix(); //Save the current state of transformations
glTranslatef(-1.0f, 1.0f, 0.0f); //Move to the center of the triangle
glRotatef(_angle, 1.0f, 2.0f, 3.0f); //Rotate about the the vector (1, 2, 3)
glBegin(GL_TRIANGLES);
//Triangle
glVertex3f(0.5f, -0.5f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glEnd();
glPopMatrix(); //Undo the move to the center of the triangle
glutSwapBuffers();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 260;
}
glutPostRedisplay(); //Tell GLUT that the display has changed
//Tell GLUT to call update again in 25 milliseconds
glutTimerFunc(25, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("Transformations and Timers - videotutorialsrock.com");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(24, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Regarding your first question, you can use gluProject() to apply your transform matrices (via GL_MODELVIEW_MATRIX and GL_PROJECTION_MATRIX) to arbitrary vertexes.