Rotating around the origin in 3d space using GLUT - c

I am stuck trying to get this code to work in Visual Studio 2012 using glut. It renders a 10/10 3D grid but it will not respond to my input from the keyboard. I am trying to get the camera to rotate around the origin when i hit the left arrow key.
// This example shows how to create a camera for 3D graphics.
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int g_winWidth = 1024;
int g_winHeight = 512;
bool keyStatus[256];
float angle = 0.0f; //angle for rotating camera
float beginning_angle = 0.0f;
float cx = 10.0, cy = 10.0, cz = -10.0;
void initialGL()
{
glEnable(GL_DEPTH_TEST);
glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
//initialize the keyboard keys
void initialization()
{
for(int i =0; i<256; i++)
keyStatus[i] = false;
}
//function to draw the colored x,y, and z axis
void drawCS()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(10.0f, 10.0f, 10.0f);
glLineWidth(2.5f);
glBegin(GL_LINES);
//axis x
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.3f, 0.0f, 0.0f);
//text x
glVertex3f(0.4f, 0.05f, 0.0f);
glVertex3f(0.5f, -0.05f, 0.0f);
glVertex3f(0.4f, -0.05f, 0.0f);
glVertex3f(0.5f, 0.05f, 0.0f);
//axis y
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.3f, 0.0f);
//text y
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.0f, 0.4f, 0.0f);
glVertex3f(-0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
//axis z
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.3f);
//text z
glVertex3f(-0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(0.025f, -0.025f, 0.4f);
glEnd();
glLineWidth(1.0f);
glPopMatrix();
}
//function to draw the grid
void drawGrid()
{
int size = 10; // determining the grid size and the numbers of cells
if(size%2 != 0) ++size;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glScalef(30.0f, 30.0f, 30.0f);
glBegin(GL_LINES);
for (int i =0; i<size+1; i++) {
if((float)i == size/2.0f) {
glColor3f(0.0f, 0.0f, 0.0f);
} else {
glColor3f(0.8f, 0.8f, 0.8f);
}
glVertex3f(-size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(-size/2.0f+i, 0.0f, -size/2.0f);
glVertex3f(-size/2.0f+i, 0.0f, size/2.0f);
}
glEnd();
glPopMatrix();
}
//function to display everything that is happening in window
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawGrid();// call to function to draw the grid
drawCS();//call to function to draw the x,y,z axis
glutSwapBuffers();
}
void reshape(int w, int h)
{
g_winWidth = w;
g_winHeight = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//this function sets the initial position of the camera in 3D space
/*
Need to find a way to rotate around the origin from left to right
*/
gluLookAt( cx, cy, cz, //camera position
0.0f, 0.0f, 0.0f, //what camera looks at
0.0f, 1.0f, 0.0f); //
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, g_winWidth/g_winHeight, 0.1, 100);//specifies the view for the scene
glViewport(0, 0, w, h);
//angle += 0.1f;
}
//keyboard function for the exit key
void keyboard(unsigned char key, int x, int y)
{
keyStatus[key] = true;
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
//sets the keyboard callback to the current window
void keyboardUp(unsigned char key, int x, int y)
{
keyStatus[key] = false;
}
//function for arrow keys output
void processSpecialKeys(int key, int xx, int yy) {
switch(key) {
case GLUT_KEY_LEFT :
//What the left arrow key does
angle -= 0.01f;
cx = sin(angle);
cz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
//What the right arrow key does
break;
case GLUT_KEY_UP :
//What the up arrow key does
break;
case GLUT_KEY_DOWN :
//What the down arrow key does
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(g_winWidth, g_winHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Camera");
initialGL();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(processSpecialKeys);
glEnable(GL_DEPTH_TEST);
initialization();
glutMainLoop();
return 1;//changed from EXIT_SUCCESS
}

Related

Not able to to move two objects in opposite directions simultaneously in openGl

I am trying to make a project where we can move one tank in one direction ,other in the opposite direction by using translatef function I am able to move tank 1 ,when I try moving tank2 both the tanks start moving in the same direction along with the background .
Here is the image:-
Here when i click "Move Russian tank".It is moving .When i click Ukrainian tank i want it to move in opposite direction. I am not able to move Ukranian tank in opposite direction .Can u help with this ?.
Here is my code snipet:-
float th = 0.0;
float trX = 0.0, trY = 0.0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
if (rFlag == 1) //Rotate Around origin
{
trX += 0.5;
trY += 0.0;
}
background();
tank2();
glTranslatef(trX, trY, 0.0);
if (rFlag == 2) {
trX = 0.0;
}
tank1();
glutPostRedisplay();
glutSwapBuffers();
}
void rotateMenu(int option)
{
if (option == 1)
rFlag = 1;
if (option == 2)
rFlag = 2;
if (option == 3)
rFlag = 3;
}
void tank1()
{
glColor3f(0.0f, 0.1f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(-479, -429);
glVertex2f(-479, -359);
glVertex2f(-399, -359);
glVertex2f(-399, -429);
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(-459, -389);
glVertex2f(-459, -379);
glVertex2f(-419, -379);
glVertex2f(-419, -389);
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(-459, -399);
glVertex2f(-459, -389);
glVertex2f(-419, -389);
glVertex2f(-419, -399);
glEnd();
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(-459, -409);
glVertex2f(-459, -399);
glVertex2f(-419, -399);
glVertex2f(-419, -409);
glEnd();
glColor3f(0.0f, 0.1f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(-459, -359);
glVertex2f(-459, -329);
glVertex2f(-419, -329);
glVertex2f(-419, -359);
glEnd();
glBegin(GL_QUADS);
glVertex2f(-439, -329);
glVertex2f(-419, -289);
glVertex2f(-414, -289);
glVertex2f(-434, -329);
glEnd();
}
void tank2()
{
glColor3f(0.0f, 0.1f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(391, -309);
glVertex2f(391, -239);
glVertex2f(471, -239);
glVertex2f(471, -309);
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(411, -279);
glVertex2f(411, -264);
glVertex2f(451, -264);
glVertex2f(451, -279);
glEnd();
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(411, -279);
glVertex2f(411, -294);
glVertex2f(451, -294);
glVertex2f(451, -279);
glEnd();
glColor3f(0.0f, 0.1f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(411, -239);
glVertex2f(411, -209);
glVertex2f(451, -209);
glVertex2f(451, -239);
glEnd();
glBegin(GL_QUADS);
glVertex2f(431, -209);
glVertex2f(451, -169);
glVertex2f(456, -169);
glVertex2f(436, -209);
glEnd();
}
int background()
{
glColor3f(0.0f, 1.0f, 0.0f);//Green
glBegin(GL_QUADS);
glVertex2f(-600, -800);
glVertex2f(-600, -100);
glVertex2f(800, -100);
glVertex2f(800, -800);
glEnd();
}
You need to have separate positions for both tanks and a separate mechanism for updating their position. Let us apply a smattering of OO:
struct Tank {
float x = 0, y = 0;
float dx = 0, dy = 0;
std::function<void()> drawFunc;
void update() {
x += dx;
y += dy;
}
void startMoving(float dx_, float dy_) {
dx = dx_;
dy = dy_;
}
void stopMoving() {
dx = dy = 0;
}
void draw() {
glLoadIdentity();
glTranslatef(dx, dy, 0);
drawFunc();
}
};
That means we can now declare the following somewhere global:
Tank tank1{0, 0, 0, 0, &draw_tank1};
Tank tank2{0, 0, 0, 0, &draw_tank2};
Your display function is now simply:
tank1.update(); tank1.draw();
tank2.update(); tank2.draw();
And you need to call startMoving or stopMoving on the correct tank in response to inputs, of course.
As a first improvement you should make the x and y positions match the positions of the tanks on screen and rewrite the draw_tank functions to draw around (0,0).

Vulkan - Debugging A Camera Matrix Problem

The problem I'm having is that I'm exporting a scene from Blender and my scene is rotated 90 about the Y axis. It's clearly a matrix issue and I'm having problems visualizing the solution. Blender is configured to export with 'up' = (0, 1, 0) and 'forward' = (0, 0, 1).
I'm using row major matrices as indicated by the following.
mat4x4 cons_mat4x4_perspective(float fovy, float aspect_ratio, float near, float far)
{
mat4x4 result = cons_mat4x4_zero();
float half_tan_fovy = tan(fovy / 2.0f); /* in radians */
result.as_rows[0] = cons_vec4(1.0f / (aspect_ratio * half_tan_fovy), 0.0f, 0.0f, 0.0f);
result.as_rows[1] = cons_vec4(0.0f, 1.0f / half_tan_fovy, 0.0f, 0.0f);
result.as_rows[2] = cons_vec4(0.0f, 0.0f, -(far + near) / (far - near), -1.0f);
result.as_rows[3] = cons_vec4(0.0f, 0.0f, -(2.0f * far * near) / (far - near), 0.0f);
return result;
}
// Vulkan clip matrix
clip = cons_mat4x4_floats(1.0f, 0.0f, 0.0f, 0.0f,
0.0f,-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f, 1.0f);
mat4x4 cons_mat4x4_lookat(vec3 eye, vec3 center, vec3 up)
{
mat4x4 result = cons_mat4x4_identity();
vec3 f = normalize(vec3_sub(center, eye));
vec3 s = normalize(cross(f, up));
vec3 u = cross(s, f);
result.as_rows[0] = cons_vec4(s.x, u.x, -f.x, 0.0f);
result.as_rows[1] = cons_vec4(s.y, u.y, -f.y, 0.0f);
result.as_rows[2] = cons_vec4(s.z, u.z, -f.z, 0.0f);
result.as_rows[3] = cons_vec4(-vec3_dot(s, eye),
vec3_dot(u, eye),
vec3_dot(f, eye),
1.0f);
return result;
}
My model matrix is the identity matrix and I'm creating a lookat matrix with the following parameters:
vec3 _camera = cons_vec3(0.0f, 5.0f, 0.0f);
vec3 _at = cons_vec3(0.0f, 0.0f, 0.0f);
cons_mat4x4_lookat(_camera, _at, cons_vec3(0.0f, 1.0f, 0.0f));

OpenGL: How to make light stationary when moving the camera around?

I'm trying to render a simple (10x3x10 in size) room using OpenGL and GLUT, written in C.
I'd like to create a simple statinary spotlight, while i can move around in the room.
(The ultimate goal is to make a spotlight coming from a lamp at the ceiling)
The problem is the light changes when i move the camera around.
I'm calling the following function from main():
void init() {
glEnable(GL_TEXTURE_2D);
loadTexture(); // loading some textures using SOIL
loadModels(); // loading some OBJ models
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glClearDepth(1);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glClearColor(0, 0, 0, 1);
}
The function i pass to glutDisplayFunc():
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
initLight();
gluLookAt(x, 1.5f, z, x + vX, 1.5f, z + vZ, 0.0f, 1.5f, 0.0f);
// ...
// drawing the ground, ceiling and the walls
// no matrix transformations here, just simple glVertex () calls
// ...
glPushMatrix();
// drawing a table
glTranslatef(5, 0.842843, 5);
glBindTexture(GL_TEXTURE_2D, texture[1]);
draw_model(&modelTable);
// drawing some chairs
glTranslatef(0, -0.312053, chair1Position);
glBindTexture(GL_TEXTURE_2D, texture[2]);
draw_model(&modelChair1);
glTranslatef(0, 0, chair2Position);
draw_model(&modelChair2);
glPopMatrix();
glutSwapBuffers();
}
And the initLight() function:
void initLight() {
// i would like the light to originate from an upper corner
// directed to the opposing lower corner (across the room basically)
GLfloat lightPosition[] = { 10, 3, 0, 1 };
GLfloat lightDirection[] = { 0, 0, 10, 0 };
GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1 };
GLfloat diffuseLight[] = { 1, 1, 1, 1 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 64);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);
}
I was told this problem could be solved by the proper positioning of the glPushMatrix() and glPopMatrix() calls.
Wherever i put them, the light either keeps changing when i'm moving the camera or i got no light at all. I just cannot figure it out.
What would be a proper solution here?
Thanks in advance.
EDIT:
I've moved the initLight() call to after the gluLookAt() call as #derhass suggested below.
The light is still changing when i'm moving around.
There are two screenshots below.
On the first one the light is not even visible. When i turn slightly to the right, it appears.
EDIT2:
The full (stripped down) source code:
#include <GL/glut.h>
#include <SOIL/SOIL.h>
#include <math.h>
GLfloat lightPosition[] = { 10, 3, 0, 1 };
GLfloat lightDirection[] = { 0, 0, 10, 0 };
GLfloat diffuseLight[] = { 0, 1, 0, 1 };
GLfloat ambientLight[] = { 0.2, 0.2, 0.2, 1 };
float x = 1.0f, z = 5.0f;
float vX = 1.0f, vZ = 0.0f;
float angle = 1.5f;
int windowWidth = 1024;
int windowHeight = 768;
char* textureFiles[13] = { "floortexture.png", "tabletexture.png",
"chairtexture.png", "orange.png", "helptexture.png",
"fridgetexture.png", "oven.png", "yellow.png", "dishwasher.png",
"metallic.png", "cabinet.png", "wood.png", "cabinet2.png" };
GLuint texture[13];
void loadTexture() {
for (int i = 0; i < 13; i++) {
texture[i] = SOIL_load_OGL_texture(textureFiles[i], SOIL_LOAD_RGBA,
SOIL_CREATE_NEW_ID, 0);
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
}
void init() {
glEnable(GL_TEXTURE_2D);
loadTexture();
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glClearDepth(1);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glClearColor(0, 0, 0, 1);
}
void processSpecialKeys(int key, int xx, int yy) {
float moveFraction = 0.2f;
float angleFraction = 0.1f;
switch (key) {
case GLUT_KEY_LEFT:
angle -= angleFraction;
vX = sin(angle);
vZ = -cos(angle);
break;
case GLUT_KEY_RIGHT:
angle += angleFraction;
vX = sin(angle);
vZ = -cos(angle);
break;
case GLUT_KEY_UP:
x += vX * moveFraction;
z += vZ * moveFraction;
if (x < 1) {
x = 1;
}
if (z < 1) {
z = 1;
}
if (x > 9) {
x = 9;
}
if (z > 9) {
z = 9;
}
break;
case GLUT_KEY_DOWN:
x -= vX * moveFraction;
z -= vZ * moveFraction;
if (x < 1) {
x = 1;
}
if (z < 1) {
z = 1;
}
if (x > 9) {
x = 9;
}
if (z > 9) {
z = 9;
}
break;
}
}
void initLight() {
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 128);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);
}
void renderWalls() {
// floor
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(0, 8);
glVertex3f(0.0f, 0.0f, 10.0f);
glTexCoord2f(8, 8);
glVertex3f(10.0f, 0.0f, 10.0f);
glTexCoord2f(8, 0);
glVertex3f(10.0f, 0.0f, 0.0f);
glEnd();
// walls
glBindTexture(GL_TEXTURE_2D, texture[3]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// first wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(0, 1);
glVertex3f(0.0f, 3.0f, 0.0f);
glTexCoord2f(1, 1);
glVertex3f(10.0f, 3.0f, 0.0f);
glTexCoord2f(1, 0);
glVertex3f(10.0f, 0.0f, 0.0f);
glEnd();
// second wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(10.0f, 0.0f, 0.0f);
glTexCoord2f(0, 1);
glVertex3f(10.0f, 3.0f, 0.0f);
glTexCoord2f(1, 1);
glVertex3f(10.0f, 3.0f, 10.0f);
glTexCoord2f(1, 0);
glVertex3f(10.0f, 0.0f, 10.0f);
glEnd();
// third wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(10.0f, 0.0f, 10.0f);
glTexCoord2f(0, 1);
glVertex3f(10.0f, 3.0f, 10.0f);
glTexCoord2f(1, 1);
glVertex3f(0.0f, 3.0f, 10.0f);
glTexCoord2f(1, 0);
glVertex3f(0.0f, 0.0f, 10.0f);
glEnd();
// fourth wall
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(0, 1);
glVertex3f(0.0f, 3.0f, 0.0f);
glTexCoord2f(1, 1);
glVertex3f(0.0f, 3.0f, 10.0f);
glTexCoord2f(1, 0);
glVertex3f(0.0f, 0.0f, 10.0f);
glEnd();
// ceiling
glBindTexture(GL_TEXTURE_2D, texture[7]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0.0f, 3.0f, 0.0f);
glTexCoord2f(0, 1);
glVertex3f(10.0f, 3.0f, 0.0f);
glTexCoord2f(1, 1);
glVertex3f(10.0f, 3.0f, 10.0f);
glTexCoord2f(1, 0);
glVertex3f(0.0f, 3.0f, 10.0f);
glEnd();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(x, 1.5f, z, x + vX, 1.5f, z + vZ, 0.0f, 1.5f, 0.0f);
initLight();
renderWalls();
glutSwapBuffers();
}
void changeWindowSize(int width, int height) {
if (height == 0) {
height = 1;
}
float ratio = 1.0 * width / height;
windowWidth = width;
windowHeight = height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
gluPerspective(45.0f, ratio, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(0, 0);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("Kitchen");
init();
glutDisplayFunc(display);
glutReshapeFunc(changeWindowSize);
glutIdleFunc(display);
glutSpecialFunc(processSpecialKeys);
glutMainLoop();
return 0;
}
Your light is stationary - but to the camera.
Fixed-function OpenGL does all the lighting calculations in eye space. At the moment you specify the GL_POSITION of a light, it is transformed according to the current modelView matrix at the time of the call, to get the eye space position. Since modelView is set to identity, it will always set the light to the given eye-space location - no matter where you later place the camera.
To fix this, just move initLight() after the gluLookAt.
However. You should not be doing this at all. You are using deprecated OpenGL features which you shouldn't use since a decade now. In modern GL, that functionality is completely removed. So if you are learning OpenGL in 2016, do yourself a favour and forget about that old cruft, and just learn shaders directly.

I can't render a cube in OpenGL, in Windows, using MinGW

I tried rendering a cube using OpenGL, in Windows. But the display window is black. I enabled the Z-Buffer, I clear the depth bit in the glClear function, etc. But no luck. And the problem is that every example or documentation I follow, is incomplete, or omit some information, and I'm very, very confused right now. I don't know what am I doing right and what am I doing wrong.
All I want is to display a cube, to know that the renderer is ready for 3D graphics (I can display 2D graphics with no problems). Nothing else.
This is the code of my main program:
#include "demo.h"
#include "renderfunc.c"
HDC hDC;
HGLRC hRC;
void enableGL(HWND hWnd)
{
hDC = GetDC(hWnd);
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0 };
if(!hDC)
{
MessageBox(hWnd,L"Can't Create A GL Device Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if(!nPixelFormat)
{
MessageBox(hWnd,L"Can't find a proper Pixel Format.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
SetPixelFormat(hDC, nPixelFormat, &pfd);
/* Those lines has to be here*/
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* UNCOMMENT THIS SECTION FOR 3D */
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL); //In some examples this is GL_LESS
glDepthMask(GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Accurate perspective calculations
return;
}
GLvoid ChangeSize(GLsizei width, GLsizei height)
{
if(height==0)
height=1;
glViewport(0,0,width,height);
//glLoadIdentity();
/* THIS SECTION IS FOR 3D GRAPHICS */
/* Comment glLoadIdentity above, and uncomment this section */
/* If you enable Z-buffer */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
enableGL(hWnd);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
ReleaseDC(hWnd,hDC);
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
case WM_PAINT:
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* GL ANIMATION GOES HERE */
//Change this for whatever you want to render
renderCubeTest();
/* -------------------- */
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
return 0;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
return 0;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
//String with the name of the class of our window
LPCTSTR classname = L"OpenGL";
//String with the title of our window
LPCTSTR windowtitle = L"Cubes Demo By Ninjihaku Software";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
wc.hIcon = NULL;
wc.hCursor = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(RegisterClass(&wc) == 0)
return false;
//hWnd = CreateWindow(classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 640, 480, NULL, NULL, hInstance, NULL);
hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 640, 480, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
return FALSE;
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
return (int) msg.wParam;
}
Then the renderCubeTest() function included in renderfunc.c:
void renderCubeTest()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glFlush();
glPopMatrix();
return;
}
I hope someone can help me and tell me what's wrong with this.
glDepthFunc(GL_EQUAL);
I suspect this is the problem - what it basically does is tell OpenGL that pixels should only be rendered to the screen if the new pixel's depth value is equal to the current pixel's depth value. This is most certainly not what you want.
Instead, you should use either GL_LEQUAL (note the "L" before "EQUAL") or GL_LESS, as these are the normal comparison functions.

OpenGL sphere camera: cube rendering incorrectly

I implement a simple sphere camera by using OpenGL and I render a cube for observasion. But the cube is not displayed correctly. Like this:
Some surfaces of the cube are invisible, some are not. Can someone solve the problem? Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gl/glut.h>
#define MAX_EPSILON_ERROR 10.0f
#define THRESHOLD 0.30f
#define REFRESH_DELAY 10 //ms
////////////////////////////////////////////////////////////////////////////////
// constants
const unsigned int window_width = 512;
const unsigned int window_height = 512;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0, rotate_y = 0.0;
float translate_z = -3.0;
// Auto-Verification Code
int fpsCount = 0; // FPS count for averaging
int fpsLimit = 1; // FPS limit for sampling
int g_Index = 0;
float avgFPS = 0.0f;
unsigned int frameCount = 0;
unsigned int g_TotalErrors = 0;
bool g_bQAReadback = false;
int *pArgc = NULL;
char **pArgv = NULL;
#define MAX(a,b) ((a > b) ? a : b)
////////////////////////////////////////////////////////////////////////////////
// declaration, forward
void cleanup();
// GL functionality
bool initGL(int *argc, char **argv);
// rendering callbacks
void display();
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void timerEvent(int value);
////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
// First initialize OpenGL context
if (false == initGL(&argc, argv))
{
return false;
}
// register callbacks
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
// start rendering mainloop
glutMainLoop();
atexit(cleanup);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//! Initialize GL
////////////////////////////////////////////////////////////////////////////////
bool initGL(int *argc, char **argv)
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("Cuda GL Interop (VBO)");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutTimerFunc(REFRESH_DELAY, timerEvent,0);
//// initialize necessary OpenGL extensions
//glewInit();
//if (! glewIsSupported("GL_VERSION_2_0 "))
//{
// fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");
// fflush(stderr);
// return false;
//}
// default initialization
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
// viewport
glViewport(0, 0, window_width, window_height);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 2, 10.0);
// SDK_CHECK_ERROR_GL();
return true;
}
////////////////////////////////////////////////////////////////////////////////
//! Display callback
////////////////////////////////////////////////////////////////////////////////
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, translate_z);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f); // 颜色改成绿色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)
glEnd();
glutSwapBuffers();
}
void timerEvent(int value)
{
glutPostRedisplay();
glutTimerFunc(REFRESH_DELAY, timerEvent,0);
}
void cleanup()
{
//sdkDeleteTimer(&timer);
}
////////////////////////////////////////////////////////////////////////////////
//! Keyboard events handler
////////////////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
switch (key)
{
case (27) :
exit(EXIT_SUCCESS);
break;
}
}
////////////////////////////////////////////////////////////////////////////////
//! Mouse event handlers
////////////////////////////////////////////////////////////////////////////////
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
Left click for rotation, and right click to change the radius.
Request a depth buffer:
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE);
^^^^^^^^^^
And enable depth testing:
glEnable(GL_DEPTH_TEST);

Resources