This question already has an answer here:
No spot of light on cube
(1 answer)
Closed 5 years ago.
I created a 3D scene where I added a light source and a 3D box, which should be illuminated by the light source. Both Ambient and Diffuse colors seem to work properly, but the specular color does not seem to be calculated correctly. When moving the camera in front of the side with the light source, no specular 'dot' can be seen. But when i move the camera towards the top of the cube and look at the origin (0, 0, 0), a faint specular 'dot' can be seen on the illuminated side of the cube.
My question is the following: what am I doing wrong?
Everything in the code below happens in the modelMatrix, and the _nav member manages the camera movement.
Here's the code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(_nav->getCamPosx(), _nav->getCamPosy(), _nav->getCamPosz(),
_nav->getCamViewx(), _nav->getCamViewy(), _nav->getCamViewz(),
_nav->getCamUpx(), _nav->getCamUpy(), _nav->getCamUpz());
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat qaAmbientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat qaDiffuseLight[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat qaSpecularLight[] = {1.0f, 0.0f, 0.0f, 1.0f}; //red for testing
glLightfv(GL_LIGHT0, GL_AMBIENT, qaAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, qaDiffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, qaSpecularLight);
// Set the light position
GLfloat qaLightPosition[] = {0.5f, 0.5f, 1.2f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, qaLightPosition);
GLfloat cyan[] = {0.f, .8f, .8f, 1.f};
GLfloat white[] = {0.8f, 0.8f, 0.8f, 1.0f};
//GLfloat dark[] = {0.0, 0.0, 0.0, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, cyan);
glMaterialfv(GL_FRONT, GL_DIFFUSE, cyan);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
GLfloat shininess[] = {80};
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
glBegin(GL_QUADS);
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(0.1f, 0.0f, 0.1f);
glVertex3f(1.0f, 0.0f, 0.1f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.1f, 0.0f, 1.0f);
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(0.1f, 0.0f, 0.1f);
glVertex3f(1.0f, 0.0f, 0.1f);
glVertex3f(1.0f, 1.0f, 0.1f);
glVertex3f(0.1f, 1.0f, 0.1f);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(0.1f, 0.0f, 0.1f);
glVertex3f(0.1f, 0.0f, 1.0f);
glVertex3f(0.1f, 1.0f, 1.0f);
glVertex3f(0.1f, 1.0f, 0.1f);
//face that gets illuminated
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.1f, 0.0f, 1.0f);
glVertex3f(0.1f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.1f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.1f);
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.1f, 1.0f, 0.1f);
glVertex3f(1.0f, 1.0f, 0.1f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.1f, 1.0f, 1.0f);
glEnd();
Facing cube side with light source:
Top view of the cube, the faint red is the specular 'dot':
In fixed function OpenGL illumination is calculated only at the vertices and the resulting colour then interpolated across the faces. For specular reflexes to show up then you need sufficiently many vertices so that there's actually enough spatial sampling.
Obviously it's not very efficient to subdivide meshes, just to provide enough sampling points for illumination purposes. So over the years a number of per-pixel-illumination techniques were developed. It's pretty straightforward to implement using shaders ( https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/lighting.php ).
Related
I have to rotate an object in front of a background. I have to light it with a spotlight and show the shadow on the object and on the background.
My problem is when I rotate the object the shadow doesn't change.
Here is my code:
#include "stdafx.h"
#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
GLfloat qaBlack[] = { 0.0, 0.0, 0.0, 1.0 }; //Black Color
GLfloat qaGreen[] = { 0.0, 1.0, 0.0, 1.0 }; //Green Color
GLfloat qaWhite[] = { 1.0, 1.0, 1.0, 1.0 }; //White Color
GLfloat qaRed[] = { 1.0, 0.0, 0.0, 1.0 }; //White Color
GLfloat angleShape = 0.0f;
void CreateShape()
{
// Set material properties
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, qaGreen);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, qaGreen);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, qaWhite);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20);
glBegin(GL_TRIANGLES); // Begin drawing the pyramid with 4 triangles
// Front
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
// Right
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
// Back
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// Left
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd(); // Done drawing the pyramid
}
void Spotlight()
{
glEnable(GL_LIGHTING);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 15.f);
glLightModelf(GL_LIGHT_MODEL_AMBIENT, 0.2f);
GLfloat light0Pos[] = { -3,-3,10,1 };
glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
GLfloat light0Diffuse[] = { 1,1,1 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diffuse);
GLfloat light0Specular[] = { 1,1,1 };
glLightfv(GL_LIGHT0, GL_SPECULAR, light0Specular);
glEnable(GL_LIGHT0);
//glDisable(GL_LIGHTING);
}
void display2()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Spotlight();
glTranslatef(-0.5f, 0.0f, -6.0f);
glRotatef(angleShape, 1.0f, 1.0f, 0.0f);
CreateShape();
angleShape -= 5.f;
glLoadIdentity();
glTranslatef(2.0f, 2.5f, -7.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 1.0f, 0.5f);
glVertex3f(0.5f, -3.0f, -5.0f);
glVertex3f(-7.0f, -6.0f, -5.0f);
glVertex3f(1.0f, -6.0f, -5.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-6.5f, -3.0f, -5.0f);
glVertex3f(0.5f, -3.0f, -5.0f);
glVertex3f(-7.0f, -6.0f, -5.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-6.5f, -3.0f, -5.0f);
glVertex3f(0.5f, -3.0f, -5.0f);
glVertex3f(0.5f, 2.0f, -5.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-6.5f, -3.0f, -5.0f);
glVertex3f(-6.5f, 2.0f, -5.0f);
glVertex3f(0.5f, 2.0f, -5.0f);
glEnd();
glutSwapBuffers();
}
void initGL() {
glClearColor(0.0, 0.7, 1.0, 1.0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void reshape(GLsizei width, GLsizei height) {
if (height == 0) height = 1;
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(50, 50);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL #1");
glutDisplayFunc(display2);
glutReshapeFunc(reshape);
initGL();
glutMainLoop();
return 0;
}
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 want to have 2 squares under each other centered in an openGL scene.
I want it like this: https://image.prntscr.com/image/776a14cd345047a1985072e0cf279ceb.png
How can I do this, with glVertex and glColor?
Thanks
Something like this:
void draw() {
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex2f(-1.0f, -1.0f);
glVertex2f( 1.0f, -1.0f);
glVertex2f( 1.0f, 1.0f);
glVertex2f(-1.0f, 1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(-0.5f, 0.8f);
glVertex2f( 0.8f, 0.8f);
glVertex2f( 0.8f, 0.0f);
glVertex2f(-0.5f, 0.0f);
glVertex2f(-0.3f, 0.0f);
glVertex2f( 0.6f, 0.0f);
glVertex2f( 0.6f,-0.6f);
glVertex2f(-0.3f,-0.6f);
glEnd();
}
It was one of my better eye-balling jobs. Output (left is mine, bottom-right is yours):
Note that I am drawing a full-screen black quad instead of what one would usually do (glClearColor(0.0f, 0.0f, 0.0f); then glClear(GL_COLOR_BUFFER_BIT);) since you asked specifically in terms of glColor and glVertex.
I have been attempting to use OpenGL with C++ lately and I have come a cross a problem when trying to render a cube with lighting, but it doesn't appear I believe this is due to some kinda of clipping error.
Here is my code. The initialization function:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING); //Enable lighting
glEnable(GL_LIGHT0); //Enable light #0
glEnable(GL_LIGHT1); //Enable light #1
glEnable(GL_NORMALIZE); //Automatically normalize normals
and here is the draw code
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0.0f, 0.0f, -8.0f);
//Add ambient light
GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f}; //Color (0.2, 0.2, 0.2)
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
//Add positioned light
GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color (0.5, 0.5, 0.5)
GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 1.0f}; //Positioned at (4, 0, 8)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
//Add directed light
GLfloat lightColor1[] = {0.5f, 0.2f, 0.2f, 1.0f}; //Color (0.5, 0.2, 0.2)
//Coming from the direction (-1, 0.5, 0.5)
GLfloat lightPos1[] = {-1.0f, 0.5f, 0.5f, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
glRotatef(Rotation, 0.0f, 1.0f, 0.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
//Front
glNormal3f(0.0f, 0.0f, 1.0f);
//glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, -1.0f, 1.5f);
//glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, -1.0f, 1.5f);
//glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, 1.0f, 1.5f);
//glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, 1.0f, 1.5f);
//Right
glNormal3f(1.0f, 0.0f, 0.0f);
//glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, -1.0f, -1.5f);
//glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, 1.0f, -1.5f);
//glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, 1.0f, 1.5f);
//glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, -1.0f, 1.5f);
//Back
glNormal3f(0.0f, 0.0f, -1.0f);
//glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, -1.0f, -1.5f);
//glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, 1.0f, -1.5f);
//glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, 1.0f, -1.5f);
//glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, -1.0f, -1.5f);
//Left
glNormal3f(-1.0f, 0.0f, 0.0f);
//glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, -1.0f, -1.5f);
//glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, -1.0f, 1.5f);
//glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, 1.0f, 1.5f);
//glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, 1.0f, -1.5f);
glEnd();
SwapBuffers(hDC);
Sleep (1);
after following the advice of Keith i attempted to use the gluLookAt like this:
void gluLookAt ( 10.0 , 10.0 , 10.0 , 1.5, -1.0, 1.5, 0.0, 0.0, 1.0 );
but I get an error
|74|error: variable or field `gluLookAt' declared void|
You may need to define the projection matrix.
This can be done with, for example, gluLookAt()
After your edit: gluLookAt is a function just like glVertex3f and such. Therefore invoke it by just calling:
gluLookAt(10.0 , 10.0 , 10.0 , 1.5, -1.0, 1.5, 0.0, 0.0, 1.0 );
Note that there is no void involved in this line of code!
What the compiler sees if there is a void in front of this line is a variable declaration named gluLookAt of type void initialized (constructed) with a bunch of doubles.
I want to set a light in my 3d world, positioned in a corner and when I move with my mouse I want it to stay there and just be.
When I use the function from glut: glutSolidSphere, everything looks okay.
But when I add a quad in my world and I move with my mouse, the lighting on the quad changes. Any idea how to solve this?
void World::paint(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
float no_mat[] = {0.0f, 0.0f, 0.0f, 1.0f};
float mat_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f};
float mat_ambient_color[] = {0.8f, 0.8f, 0.2f, 1.0f};
float mat_diffuse[] = {0.1f, 0.5f, 0.8f, 1.0f};
float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
float no_shininess = 0.0f;
float low_shininess = 5.0f;
float high_shininess = 100.0f;
float mat_emission[] = {0.3f, 0.2f, 0.2f, 0.0f};
camera->setup();
light->assignComponentsToGLLightX();
glEnable(GL_LIGHTING);
glMatrixMode( GL_MODELVIEW );
// WORKS
float temp[] = {0.7f, 0.0f, 0.0f, 1.0f};
glPushMatrix();
glTranslatef(3.75f, 3.0f, 0.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, temp);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glutSolidSphere( 3.0, 25, 25 );
glPopMatrix();
// Doesn't work
glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, low_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
glBegin(GL_QUADS);
//Front
//glNormal3f(0.0f, 0.0f, 1.0f);
glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, -1.0f, 1.5f);
glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, -1.0f, 1.5f);
glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, 1.0f, 1.5f);
glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, 1.0f, 1.5f);
//Right
//glNormal3f(1.0f, 0.0f, 0.0f);
glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, -1.0f, -1.5f);
glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, 1.0f, -1.5f);
glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, 1.0f, 1.5f);
glNormal3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.5f, -1.0f, 1.5f);
//Back
//glNormal3f(0.0f, 0.0f, -1.0f);
glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, -1.0f, -1.5f);
glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, 1.0f, -1.5f);
glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, 1.0f, -1.5f);
glNormal3f(1.0f, 0.0f, -1.0f);
glVertex3f(1.5f, -1.0f, -1.5f);
//Left
//glNormal3f(-1.0f, 0.0f, 0.0f);
glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, -1.0f, -1.5f);
glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, -1.0f, 1.5f);
glNormal3f(-1.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, 1.0f, 1.5f);
glNormal3f(-1.0f, 0.0f, -1.0f);
glVertex3f(-1.5f, 1.0f, -1.5f);
glEnd();
glPopMatrix();
void Camera::setup() const
{
glRotatef(_rotX, 1.0,0.0,0.0);
glRotatef(_rotY, 0.0,1.0,0.0);
glTranslated(-_moveX,-_moveY,-_moveZ);
gluLookAt(3.0 , 5.0 , 25.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0 );
}
void Light::assignComponentsToGLLightX() const
{
glLightfv(_light, GL_AMBIENT, _ambientLight);
glLightfv(_light, GL_DIFFUSE, _diffuseLight);
glLightfv(_light, GL_SPECULAR, _specularLight);
glLightfv(_light, GL_POSITION, _position);
}
So I setted the light call after the camera_setup()
But now the quad is still not working as I want it to. The light still changes and I am pretty sure that my normals are correct (checked them twice).
I was thinking, is this possible because I don't change my _camPosX, Y, Z values when I move/rotate?
Calling gluLookAt before glRotate / glTranslate should help...
Other thoughts :
call glMatrixMode and glLoadIdentity only once, in camera::setup.
don't call glRotate and glTranslate in camera::setup. This has nothing to do with the camera. This is your object's tranformation
Wrap glRotate and glTranslate inside glPushMatrix/glPopMatrix. This way, the next time you draw an object, transformations won't be cummulated.
glTranslatef(0.0f, 0.0f, 0.0f) is useless. It means : add a null displacement to the current matrix. In other words: don't do anything
wrapping pushmatrix/popmatrix around this is thus useless
As datenwolf said, I don't see where you actually indicate the light's position
You must set the lights' positions after moving the world / setting the camera i.e. add
glLightfv(GL_LIGHT0+n, GL_POSITION, light_position)
calls right after
camera->setup();