In my scene, I have ambient light with values:
GLfloat global_ambient[] = {0.4, 0.4, 0.4};
And in my initGL I am enableing it:
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
I want when I press "s" key to toggle the light on and off. I know how to toggle the light, my question is is there a method such as glEnagle and glDisable for the ambient light?
Figured it myself. In my KeyResponder method when the user presses the 's' key this is what I am doing:
if (key == 's'){
if (isAmbientOn){
//if it is true turn the ambient off by setting the R,G,B values to 0
global_ambient[0] = 0;
global_ambient[1] = 0;
global_ambient[2] = 0;
isAmbientOn = false;
}
else{
//if it is false tuen the ambient on by setting it to a value - 0.4
global_ambient[0] = 0.4;
global_ambient[1] = 0.4;
global_ambient[2] = 0.4;
isAmbientOn = true;
}
}
And in my DrawScene method:
void CDrawModel::myDrawGLScene(GLvoid) // Here's Where We Do All The Drawing{
//set up the ambient light in myDrawGLScene so we can switch it on and off on 's' key press...
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
{
Related
i wanna make a small app that allow me to move the triangle to top/bottm left/right.
and when i press w -> rotate above and move above , s => rotate bottom and move bottom ,, d -> rotate right and moves right , a -> rotate left and move left ..
here is my code :
#include <GL/glut.h> // (or others, depending on the system in use)
float xpoint1 = 0.0f;
float xpoint2 = 50.0f;
float xpoint3 = 25.0f;
float ypoint1 = 0.0f, ypoint2 = 0.0f, ypoint3 = 20.0f;
double direction = 0.0;
void Keys(unsigned char key, int x, int y) {
if (key == 'a') {
if (xpoint1 != 0) {
xpoint1 -= 1.0f;
xpoint2 -= 1.0f;
xpoint3 -= 1.0f;
direction = 90.0;
}
}
else if (key == 'd') {
if (xpoint2 != 200) {
xpoint1 += 1.0f;
xpoint2 += 1.0f;
xpoint3 += 1.0f;
direction = 270.0;
}
}
else if (key == 'w') {
if (ypoint3 != 150) {
ypoint1 += 1.0f;
ypoint2 += 1.0f;
ypoint3 += 1.0f;
direction = 0.0;
}
}
else if (key == 's') {
if (ypoint3 != 0) {
ypoint1 -= 1.0f;
ypoint2 -= 1.0f;
ypoint3 -= 1.0f;
direction = 180.0;
}
}
glutPostRedisplay();
}
void resizeChange(int w, int h) {
glClearColor(1.0, 1.0, 1.0, 0.0); // Set display-window color to white.
glMatrixMode(GL_PROJECTION); // Set projection parameters.
glLoadIdentity();
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
}
void lineSegment(void)
{
glClear(GL_COLOR_BUFFER_BIT); // Clear display window.
glColor3f(0.0, 0.4, 0.2); // Set line segment color to green.
//gluLookAt(0.0, 0.0, 5.0,
// 0.0, 0.0,0.0,
// 0.0, 1.0, 0.0
//);
glLoadIdentity();
glRotated(direction, 0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(xpoint1, ypoint1);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(xpoint2, ypoint2);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(xpoint3, ypoint3);
glEnd();
//degree += 1.0;
glFlush(); // Process all OpenGL routines as quickly as possible.
//glutSwapBuffers();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv); // Initialize GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // Set display mode.
glutInitWindowPosition(50, 100); // Set top-left display-window position.
glutInitWindowSize(600, 600); // Set display-window width and height.
glutCreateWindow("An Example OpenGL Program"); // Create display window.
glutDisplayFunc(lineSegment); // Send graphics to display window.
glutReshapeFunc(resizeChange);
//glutIdleFunc(lineSegment);
glutKeyboardFunc(Keys);
glutMainLoop(); // Display everything and wait.
}
the problem is when i try to change direction of the triangle it disappered ?! , whats the problem ?!
glRotated rotates around (0, 0). Actually rotate the triangle out of sight. You have to rotate the triangle first and then move it to its place in the world.
Do not change the vertex coordinates but add a translation matrix with glTranslate:
double tx = 0.0, ty = 0.0;
double direction = 0.0;
void Keys(unsigned char key, int x, int y)
{
if (key == 'a') {
tx -= 1.0;
direction = 90.0;
}
else if (key == 'd') {
tx += 1.0;
direction = 270.0;
}
else if (key == 'w') {
ty += 1.0;
direction = 0.0;
}
else if (key == 's') {
ty -= 1.0;
direction = 180.0;
}
glutPostRedisplay();
}
void lineSegment(void)
{
// [...]
glTranslated(tx, ty, 0.0);
glRotated(direction, 0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(-25.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex2f(25.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(0.0, 20.0);
glEnd();
// [...]
}
I'm trying to get a model working which has 8 different light sources. I would like to make it so that a surface reaches its "maximum" value when near one light source, but the way the code works now if multiple lights are near a surface, it just keeps increasing in how lit up it is until it is almost pure-white.
For surfaces, I use:
float white[] = {1,1,1,1};
float black[] = {0,0,0,1};
float medium[] = {.5,.5,.5,.5};
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white);
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,black);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,medium);
And for the eight lights:
int glLightConstant = GL_LIGHT0 + i;
float Diffuse[] = {(float)0.01*50 ,(float)0.01*50 ,(float)0.01*50 ,1.0f};
float Specular[] = {(float)0.01*0,(float)0.01*0,(float)0.01*0,1.0f};
float Position[] = {(float)positions[i].x,(float)positions[i].y,(float)positions[i].z,(float)1.0};
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,0.0);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(glLightConstant);
if(i == 0) {
float Ambient[] = {(float)0.01*0 ,(float)0.01*0 ,(float)0.01*0 ,1.0f};
glLightfv(glLightConstant,GL_AMBIENT ,Ambient);
}
glLightfv(glLightConstant,GL_DIFFUSE ,Diffuse);
glLightfv(glLightConstant,GL_SPECULAR,Specular);
glLightfv(glLightConstant,GL_POSITION,Position);
I realize that the ambient light is 0, I might change it later.
I'm trying to run the "Cacti in the Desert" Billboard example from Chapter 15 of the OpenGL Game Programming book (Book source code available here). I'm having difficulty getting the desert terrain to be visible on my screen. I'm using GLFW for my window and the example code created it's own window, could this be the issue?
Or, could the issue be with the DisplayScene() function below. In this function, do I have to somehow set the following matrices from my camera class?
ViewMatrix = camera[currentCamera]->GetViewMatrix();
ProjectionMatrix = camera[currentCamera]->GetViewProjectionMatrix();
Here's the DisplayScene() function from the Cacti demo:
BOOL DisplayScene()
{
// used to track the orientation of the viewer
static GLfloat s_eye[] = { MAP_X * MAP_SCALE * 0.5, 8.0, -MAP_Z * MAP_SCALE * 0.5};
static GLfloat s_at[] = { 0.0, 0.0, 0.0 };
static GLfloat s_angle = -90.0;
float speed = 0.3f;
// check for rotation
if (g_keys[VK_LEFT])
{
s_angle -= 2.0;
}
if (g_keys[VK_RIGHT])
{
s_angle += 2.0;
}
// run if the shift key is pressed
if (KEY_DOWN(VK_SHIFT))
speed = speed * 2;
float rad = float(PI*s_angle/180.0f);
// check for forward and backward motion
if (g_keys[VK_UP])
{
s_eye[2] += (float)sin(rad) * speed;
s_eye[0] += (float)cos(rad) * speed;
}
if (g_keys[VK_DOWN])
{
s_eye[2] -= (float)sin(rad) * speed;
s_eye[0] -= (float)cos(rad) * speed;
}
// do bound's checking to make sure they don't leave the map
if (s_eye[0] < MAP_SCALE)
s_eye[0] = MAP_SCALE;
if (s_eye[0] > (MAP_X - 2) * MAP_SCALE)
s_eye[0] = (MAP_X - 2) * MAP_SCALE;
if (s_eye[2] < -(MAP_Z - 2) * MAP_SCALE)
s_eye[2] = -(MAP_Z - 2) * MAP_SCALE;
if (s_eye[2] > - MAP_SCALE)
s_eye[2] = -MAP_SCALE;
// set the eye position in relation to the ground
s_eye[1] = GetHeight(s_eye[0], s_eye[2]) + 2.0f;
//set the look at point to be at eye level in the direction the viewer is headed
s_at[0] = float(s_eye[0] + 100*cos(rad));
s_at[2] = float(s_eye[2] + 100*sin(rad));
s_at[1] = s_eye[1];
// set up the modelview matrix according to this viewer orientation
glLoadIdentity();
gluLookAt(s_eye[0], s_eye[1], s_eye[2],
s_at[0], s_at[1], s_at[2],
0.0, 1.0, 0.0
);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawSand();
DrawCacti();
return TRUE;
} // end DisplayScene()
Here is the DrawSand() function to draw the terrain:
void DrawSand()
{
// select the sand texture
glBindTexture(GL_TEXTURE_2D, g_sand);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// loop through all the triangle strips
for (int z = 0; z < MAP_Z-1; z++)
{
// draw the triangles in this strip
glDrawElements(GL_TRIANGLE_STRIP, MAP_X * 2, GL_UNSIGNED_INT, &g_indexArray[z * MAP_X * 2]);
}
} // end DrawSand()
I m new to OpenGL. I have a viewer for a point cloud.
When I rotate the point cloud around x-axis or z-axis , it gets flipped or inverted after 180 degrees and flips back again at 0 degrees.
From 0-180 degrees it works fine and from 180-360 degrees it flips.
The following is a code snippet for the paint event
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_center[0] = (m_minX+m_maxX)/2.0f;
m_center[1] = (m_minY+m_maxY)/2.0f;
m_center[2] = (m_minZ+m_maxZ)/2.0f;
m_radius = static_cast<float>(std::sqrt((m_maxX-m_center[0])*(m_maxX-m_center[0])
+(m_maxY-m_center[1])*(m_maxY-m_center[1])+(m_maxZ-m_center[2])*(m_maxZ-m_center[2])));
m_fDistance = m_radius/0.57735f; //where 0.57735f is tan(30 degrees)
m_dNear = m_fDistance - 3*m_radius;
m_dFar = m_fDistance + 3*m_radius;
glLoadIdentity();
glPushMatrix();
// glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-m_zoomFactor*2*m_radius, +m_zoomFactor*2*m_radius, -m_zoomFactor*2*m_radius, +m_zoomFactor*2*m_radius, m_dNear, m_dFar);
glMatrixMode(GL_MODELVIEW);
glRotatef(m_modelRotation.x/16.0, 1.0, 0.0, 0.0);
glRotatef(m_modelRotation.y/16.0, 0.0, 1.0, 0.0);
glRotatef(m_modelRotation.z/16.0, 0.0, 0.0, 1.0);
glScalef(m_modelScale.x,m_modelScale.y,m_modelScale.z);
switch(m_shapeMode)
{
case eShapePointCloud:
drawPoints();
break;
case eShapeSolid:
drawQuads();
break;
default:
qDebug()<<"No shape is specified, so use the points shape.";
drawPoints();
break;
}
glPopMatrix();
Here is the code for the mouse move event
void OglWidget::mouseMoveEvent(QMouseEvent *event)
{
GLfloat dx = GLfloat(event->x() - m_lastPos.x()) ;/// width();
GLfloat dy = GLfloat(event->y() - m_lastPos.y()) ;/// height();
if (event->buttons() & Qt::LeftButton)
{
setXRotation(m_modelRotation.x + 8*dy);
setZRotation(m_modelRotation.z + 8*dx);
this->setPropertyValue(1,m_modelRotation);
}
m_lastPos = event->pos();
}
reference
http://www.chai3d.org/doc/classc_light.html
code
light2->setPos(cVector3d( 0, 0,0.0)); // position the light source
light2->m_ambient.set(0.8, 0.8, 0.8);
light2->m_diffuse.set(0.8, 0.8, 0.8);
light2->m_specular.set(0.8, 0.8, 0.8);
light2->setDirectionalLight(false);//make a positional light
the rendering code which uses opengl is
void cLight::renderLightSource()
{
// check if light source enabled
if (m_enabled == false)
{
// disable OpenGL light source
glDisable(m_glLightNumber);
return;
}
computeGlobalCurrentObjectOnly();
// enable this light in OpenGL
glEnable(m_glLightNumber);
// set lighting components
glLightfv(m_glLightNumber, GL_AMBIENT, m_ambient.pColor());
glLightfv(m_glLightNumber, GL_DIFFUSE, m_diffuse.pColor() );
glLightfv(m_glLightNumber, GL_SPECULAR, m_specular.pColor());
// position the light source in (global) space (because we're not
// _rendered_ as part of the scene graph)
float position[4];
position[0] = (float)m_globalPos.x;
position[1] = (float)m_globalPos.y;
position[2] = (float)m_globalPos.z;
//position[0] = (float)m_localPos.x;
//position[1] = (float)m_localPos.y;
//position[2] = (float)m_localPos.z;
// Directional light source...
if (m_directionalLight) position[3] = 0.0f;
// Positional light source...
else position[3] = 1.0f;
glLightfv(m_glLightNumber, GL_POSITION, (const float *)&position);
// set cutoff angle
glLightf(m_glLightNumber, GL_SPOT_CUTOFF, m_cutOffAngle);
// set the direction of my light beam, if I'm a _positional_ spotlight
if (m_directionalLight == false)
{
cVector3d dir = m_globalRot.getCol0();
float direction[4];
direction[0] = (float)dir.x;
direction[1] = (float)dir.y;
direction[2] = (float)dir.z;
direction[3] = 0.0f;
glLightfv(m_glLightNumber, GL_SPOT_DIRECTION, (const float *)&direction);
}
// set attenuation factors
glLightf(m_glLightNumber, GL_CONSTANT_ATTENUATION, m_attConstant);
glLightf(m_glLightNumber, GL_LINEAR_ATTENUATION, m_attLinear);
glLightf(m_glLightNumber, GL_QUADRATIC_ATTENUATION, m_attQuadratic);
// set exponent factor
glLightf(m_glLightNumber, GL_SPOT_EXPONENT, m_spotExponent);
}
why do I get my whole environment uniformly lighted?
how do I get a concetrated light around the origin 0,0,0, which fades away after 1 or 2 unit distance? My origin is the middle cube in the grid.
caveat emptor: This is "from the top of my head" from way-back-when i used to fumble with OpenGL.
I think the OpenGL concept of a "directional light" is sort of like a point-lightsource at infinity, meaning the light-vector is invariant across the entire scene.
In order to do the spotlight effect, you need to form the dot-product of the light-direction and the light-vector (vector from vertex to light) and attenuate the light exponentially as the angle increases.
I remember reading a tutorial about this once, will search...
Right, its described here
Scroll down to the description of "spotlights".
In the code you've listed, I believe you need to ensure that m_spotExponent is greater-than zero to get a "cone" effect. Higher values yield a "sharper" transition from "lit" to "dark" parts of the cone (I think).
Hope that helps