Separating Triangle Strips in Circular Annulus - c++

Given the problem description:
More specifically, the problem involves specifically the decorated annulus. The problem I am having is to separate the lightly shaded triangle from the dark shaded triangles.
I have produced code (based on a previous example) that produces a circular annulus. However, the triangles are together rather than separate, and produce the same color.
Here is the code that I have produced so far:
///////////////////////////////////////////////////////////////////////////////////////////
// circularAnnuluses.cpp
//
// This program draws three identical-looking circular annuluses in three different ways -
// see comments below.
//
// Interaction:
// Press the space bar to toggle between wirefrime and filled for the lower annulus.
//
// Sumanta Guha.
///////////////////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <cmath>
#include <iostream>
#ifdef __APPLE__
# include <GL/glew.h>
# include <GL/freeglut.h>
# include <OpenGL/glext.h>
#else
# include <GL/glew.h>
# include <GL/freeglut.h>
//# include <GL/glext.h>
#pragma comment(lib, "glew32.lib")
#endif
#define PI 3.14159265
#define N 6.0 // Number of vertices on the boundary of the disc.
using namespace std;
// Globals.
static int isWire = 0; // Is wireframe?
// Drawing routine.
void drawScene(void)
{
float angle;
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers including
// the depth buffer.
glPolygonMode(GL_FRONT, GL_FILL);
// Lower circular annulus: with a true hole.
if (isWire) glPolygonMode(GL_FRONT, GL_LINE); else glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i <= N; ++i)
{
angle = 2 * PI * i / N;
glColor3f(1.0, 0.0, 0.0);
glVertex3f(50 + cos(angle) * 10.0, 50 + sin(angle) * 10.0, 0.0);
glColor3f(0, 1, 0);
glVertex3f(50 + cos(angle) * 20.0, 50 + sin(angle) * 20.0, 0.0);
}
glEnd();
// Write labels.
glColor3f(0.0, 0.0, 0.0);
glFlush();
}
// Initialization routine.
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case ' ':
if (isWire == 0) isWire = 1;
else isWire = 0;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
cout << "Interaction:" << endl;
cout << "Press the space bar to toggle between wirefrime and filled for the lower annulus." << endl;
}
// Main routine.
int main(int argc, char** argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("DecoratedAnnulus.cpp");
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glewExperimental = GL_TRUE;
glewInit();
setup();
glutMainLoop();
}
The section of code where the problem lies is in the 'drawscene' function. I believe there should be two different for loops to separate the triangles from one another, but whenever I try to split the for loop it produces a monster of a shape.
I'm not exactly sure where to begin to complete this last problem.

As mentioned in the other answer, a possibility is to switch to flat shading mode by glShadeModel.
But note, you've also to offset the vertex coordinates of the outer circle:
glShadeModel( GL_FLAT );
glBegin(GL_TRIANGLE_STRIP);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * i / N;
angle2 = 2 * PI * (i+0.5) / N;
glColor3f(1.0, 0.0, 0.0);
glVertex3f(50 + cos(angle1) * 10.0, 50 + sin(angle1) * 10.0, 0.0);
glColor3f(0, 1, 0);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
}
glEnd();
The other possibility is to draw the inner and outer triangles with the primitive type GL_TRIANGLES in 2 separate loops:
glShadeModel( GL_SMOOTH );
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * i / N;
angle2 = 2 * PI * (i+0.5) / N;
angle3 = 2 * PI * (i+1) / N;
glVertex3f(50 + cos(angle1) * 10.0, 50 + sin(angle1) * 10.0, 0.0);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
glVertex3f(50 + cos(angle3) * 10.0, 50 + sin(angle3) * 10.0, 0.0);
}
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(0, 1, 0);
for (i = 0; i <= N; ++i)
{
angle1 = 2 * PI * (i-0.5) / N;
angle2 = 2 * PI * i / N;
angle3 = 2 * PI * (i+0.5) / N;
glVertex3f(50 + cos(angle1) * 20.0, 50 + sin(angle1) * 20.0, 0.0);
glVertex3f(50 + cos(angle2) * 10.0, 50 + sin(angle2) * 10.0, 0.0);
glVertex3f(50 + cos(angle3) * 20.0, 50 + sin(angle3) * 20.0, 0.0);
}
glEnd();
Both methods generate the following image:
If you want a more "circular" look, then you've to tessellate the segments along the inner or outer circle. Use the primitive type GL_TRIANGLE_FAN (see Triangle primitives) to draw a single segment:
int N2 = 10;
glShadeModel( GL_SMOOTH );
# draw the red segments
glColor3f(1.0, 0.0, 0.0);
for (int i = 0; i <= N; ++i)
{
float angle1 = 2 * PI * i / N;
float angle2 = 2 * PI * (i+0.5) / N;
float angle3 = 2 * PI * (i+1) / N;
# draw a single red segment
glBegin(GL_TRIANGLE_FAN);
glVertex3f(50 + cos(angle2) * 20.0, 50 + sin(angle2) * 20.0, 0.0);
for (int j = 0; j <= N2; ++j)
{
float a = angle1 + (angle3 - angle1) * (float)j / (float)N2;
glVertex3f(50 + cos(a) * 10.0, 50 + sin(a) * 10.0, 0.0);
}
glEnd();
}
# draw the green sgements
glColor3f(0, 1, 0);
for (int i = 0; i <= N; ++i)
{
float angle1 = 2 * PI * (i-0.5) / N;
float angle2 = 2 * PI * i / N;
float angle3 = 2 * PI * (i+0.5) / N;
# draw a single green segment
glBegin(GL_TRIANGLE_FAN);
glVertex3f(50 + cos(angle2) * 10.0, 50 + sin(angle2) * 10.0, 0.0);
for (int j = 0; j <= N2; ++j)
{
float a = angle1 + (angle3 - angle1) * (float)j / (float)N2;
glVertex3f(50 + cos(a) * 20.0, 50 + sin(a) * 20.0, 0.0);
}
glEnd();
}

Related

Creating multiple Bezier curves using GL_MAP1_VERTEX_3 function in OpenGL

So I am trying to create an arbitrary curved shape using OpenGL and currently my code is only able to produce one curve between the specified control points, below is my OpenGL code:
#include <GL/glut.h>
#include <stdlib.h>
GLfloat controlPoints[18][3] =
{
{0.0, 8.0, 0.0},
{ -1.5, 3.0, 0.0}, //2
{-5.5, 4.0, 0.0},
{-5.5, 4.0, 0.0},
{-2.5, 0.0, 0.0}, //4
{-6.0, -4.0, 0.0},
{-6.0, -4.0, 0.0},
{-1.5, -3.0, 0.0}, //6
{0.0, -8.0, 0.0},
{0.0, -8.0, 0.0},
{1.0, -3.0, 0.0}, //8
{6.0, -5.0, 0.0},
{6.0, -5.0, 0.0},
{3.0, 0.0, 0.0}, //10
{6.5, 4.5, 0.0},
{6.5, 4.5, 0.0},
{1.5, 3.0, 0.0}, //12
{0.0, 8.0, 0.0}
};
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
for (int i = 0; (i + 3) < 3; i += 3)
{
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &controlPoints[i][0]);
}
//glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &controlPoints2[0][0]);
glEnable(GL_MAP1_VERTEX_3);
// The evaluator with a stride of 3 and an order of 4
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
//draw(controlPoints);
//draw(controlPoints2);
glBegin(GL_LINE_STRIP);
{
for (int i = 0; i <= 18; i++)
{
glEvalCoord1f((GLfloat)i / 18.0);
}
}
glEnd();
glBegin(GL_LINE_STRIP);
{
for (i = 0; i < 18; i++)
{
glVertex3fv(&controlPoints[i][0]);
}
}
glEnd();
glPointSize(6.0);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_POINTS);
{
for (i = 0; i < 18; i++)
{
glVertex3fv(&controlPoints[i][0]);
}
}
glEnd();
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
{
glOrtho(-10.0, 10.0, -10.0 * (GLfloat)h / (GLfloat)w, 10.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
}
else
{
glOrtho(-10.0 * (GLfloat)h / (GLfloat)w, 10.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0, -10.0, 10.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
How do I modify my init portion of the code such that able to produce 6 curves between the three control points totaling up to 18? and if not possible is there a way I can do it using GL_LINE_STRIP?
Below is what my current output looks like:
My advice - avoid openGL evaluators completely!
Aside from some SGI machines back in the 90's, no GPU vendor has ever added hardware support for them, so it falls back to a fairly inefficient software implementation.
Anyhow, there are a few problems in your code...
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3,
4, ///< this says you want 4 control points per curve
&controlPoints[i][0]);
However, there is something wrong here in the control points:
GLfloat controlPoints[18][3] =
{
{0.0, 8.0, 0.0},
{ -1.5, 3.0, 0.0}, //2
{-5.5, 4.0, 0.0}, ///< I'm assuming this is the last control point you want?
{-5.5, 4.0, 0.0}, ///< however this is duplicated here?
It looks as though you want a quadratic curve? (i.e. 3 control points per curve?)
// enable evaluators
glEnable(GL_MAP1_VERTEX_3);
// step through each triplet of CV's
for(int cv = 0; cv < 18; cv += 3) {
// specify the control point array
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0,
3, ///< each vertex has 3 floats.
3, ///< I assume you want 3? (as in 3x CV per curve)
&controlPoints[cv][0]);
// render this curve segment
glBegin(GL_LINE_STRIP);
{
// choose how many divisions you want
int NUM_DIVISIONS = 32;
for (int i = 0; i <= NUM_DIVISIONS; i++)
{
glEvalCoord1f((GLfloat)i / (GLfloat) NUM_DIVISIONS);
}
}
glEnd();
}
glDisable(GL_MAP1_VERTEX_3);
However, as I said above, GL evaluators are terrible.
It's actually just a lot easier to simply write the code yourself.
One option would be to simply tessellate each curve, and then render (This would work with your current control point layout)
void render_quadratic_curves(
GLfloat controlPoints[][3],
int num_curves,
int num_divisions) {
int out_size_of_each_curve = (num_divisions + 1) * 3;
// allocate enough memory to store a curves
GLfloat* temp = new GLfloat[out_size_of_each_curve];
// re-render from the same vertex array.
glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, temp);
glEnableClientState(GL_VERTEX_ARRAY);
for(int curve = 0; curve < num_curves; ++curve) {
// pointers to the control points for this curve
const GLfloat* P0 = controlPoints[3 * curve + 0];
const GLfloat* P1 = controlPoints[3 * curve + 1];
const GLfloat* P2 = controlPoints[3 * curve + 2];
for(int division = 0; division <= num_divisions; ++division) {
GLfloat t = (GLfloat) division / (GLfloat) NUM_DIVISIONS;
GLfloat inv_t = (1.0f - t);
// compute bezier coefficients for quadratic curve
GLfloat B0 = inv_t * inv_t;
GLfloat B1 = 2.0f * inv_t * t;
GLfloat B2 = t * t;
// compute XYZ coordinates
GLfloat x = P0[0] * B0 +
P1[0] * B1 +
P2[0] * B2;
GLfloat y = P0[1] * B0 +
P1[1] * B1 +
P2[1] * B2;
GLfloat z = P0[2] * B0 +
P1[2] * B1 +
P2[2] * B2;
// insert into the buffer for rendering
temp[3 * division + 0] = x;
temp[3 * division + 1] = y;
temp[3 * division + 2] = z;
}
// render this curve in one go as a strip
glDrawArrays(GL_LINE_STRIP, 0, num_divisions + 1);
}
// cleanup
glDisableClientState(GL_VERTEX_ARRAY);
delete [] temp;
}
However, in your case above you effectively have a loop, so this can be done in one go instead with GL_LINE_LOOP instead (This approach would nicely fit into a VBO)
void render_quadratic_curves_as_loop(
GLfloat controlPoints[][3],
int num_curves,
int num_divisions) {
// curves are 1 vertex smaller in size than previously,
// since the start vertex of one curve, is shared with the
// last vertex of the previous curve
int out_size_of_each_curve = num_divisions * 3;
// allocate enough memory to store all of the curves
GLfloat* temp = new GLfloat[out_size_of_each_curve * num_curves];
for(int curve = 0; curve < num_curves; ++curve) {
GLfloat* this_curve = temp + curve * out_size_of_each_curve;
// pointers to the control points for this curve
const GLfloat* P0 = controlPoints[3 * curve + 0];
const GLfloat* P1 = controlPoints[3 * curve + 1];
const GLfloat* P2 = controlPoints[3 * curve + 2];
// note! I am using less than here!
// the last vertex of each curve is simply the first
// vertex of the next one...
for(int division = 0; division < num_divisions; ++division) {
GLfloat t = (GLfloat) division / (GLfloat) NUM_DIVISIONS;
GLfloat inv_t = (1.0f - t);
// compute bezier coefficients for quadratic curve
GLfloat B0 = inv_t * inv_t;
GLfloat B1 = 2.0f * inv_t * t;
GLfloat B2 = t * t;
// compute XYZ coordinates
GLfloat x = P0[0] * B0 +
P1[0] * B1 +
P2[0] * B2;
GLfloat y = P0[1] * B0 +
P1[1] * B1 +
P2[1] * B2;
GLfloat z = P0[2] * B0 +
P1[2] * B1 +
P2[2] * B2;
// insert into the buffer for rendering
this_curve[3 * division + 0] = x;
this_curve[3 * division + 1] = y;
this_curve[3 * division + 2] = z;
}
}
// re-render from the same vertex array.
// This *could* be replaced with a VBO.
glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, temp);
glEnableClientState(GL_VERTEX_ARRAY);
// render all of the curves in one go.
glDrawArrays(GL_LINE_LOOP, 0, out_size_of_each_curve * num_curves);
// cleanup
glDisableClientState(GL_VERTEX_ARRAY);
delete [] temp;
}
// You'll now need to remove the duplicate CV's from your array
GLfloat controlPoints[12][3] =
{
{0.0, 8.0, 0.0},
{ -1.5, 3.0, 0.0}, //2
{-5.5, 4.0, 0.0},
{-2.5, 0.0, 0.0}, //4
{-6.0, -4.0, 0.0},
{-1.5, -3.0, 0.0}, //6
{0.0, -8.0, 0.0},
{1.0, -3.0, 0.0}, //8
{6.0, -5.0, 0.0},
{3.0, 0.0, 0.0}, //10
{6.5, 4.5, 0.0},
{1.5, 3.0, 0.0}, //12
};
render_quadratic_curves_as_loop(controlPoints, 6, 32);
If you actually want 4 CV's per curve, then you can easily extend this into a cubic bezier.
// obviously each curve will now need an additional CV
void render_cubic_curves_as_loop(
GLfloat controlPoints[][3],
int num_curves,
int num_divisions) {
// curves are 1 vertex smaller in size than previously,
// since the start vertex of one curve, is shared with the
// last vertex of the previous curve
int out_size_of_each_curve = num_divisions * 3;
// allocate enough memory to store all of the curves
GLfloat* temp = new GLfloat[out_size_of_each_curve * num_curves];
for(int curve = 0; curve < num_curves; ++curve) {
GLfloat* this_curve = temp + curve * out_size_of_each_curve;
// pointers to the control points for this curve
const GLfloat* P0 = controlPoints[4 * curve + 0];
const GLfloat* P1 = controlPoints[4 * curve + 1];
const GLfloat* P2 = controlPoints[4 * curve + 2];
const GLfloat* P3 = controlPoints[4 * curve + 2];
// note! I am using less than here!
// the last vertex of each curve is simply the first
// vertex of the next one...
for(int division = 0; division < num_divisions; ++division) {
GLfloat t = (GLfloat) division / (GLfloat) NUM_DIVISIONS;
GLfloat inv_t = (1.0f - t);
// compute bezier coefficients for cubic curve
GLfloat B0 = inv_t * inv_t * inv_t;
GLfloat B1 = 3.0f * inv_t * inv_t * t;
GLfloat B2 = 3.0f * inv_t * t * t;
GLfloat B2 = t * t;
// compute XYZ coordinates
GLfloat x = P0[0] * B0 +
P1[0] * B1 +
P2[0] * B2 +
P3[0] * B3;
GLfloat y = P0[1] * B0 +
P1[1] * B1 +
P2[1] * B2 +
P3[1] * B3;
GLfloat z = P0[2] * B0 +
P1[2] * B1 +
P2[2] * B2 +
P3[2] * B3;
// insert into the buffer for rendering
this_curve[3 * division + 0] = x;
this_curve[3 * division + 1] = y;
this_curve[3 * division + 2] = z;
}
}
// re-render from the same vertex array.
// This *could* be replaced with a VBO.
glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, temp);
glEnableClientState(GL_VERTEX_ARRAY);
// render all of the curves in one go.
glDrawArrays(GL_LINE_LOOP, 0, out_size_of_each_curve * num_curves);
// cleanup
glDisableClientState(GL_VERTEX_ARRAY);
delete [] temp;
}
NOTE: on modern hardware, if you have tessellation shaders available, that's usually the best option. Failing that, if you have hardware instancing, you can specify the basis coefficients as a shared vertex buffer, and the control points can be specified per instance.
generate a VBO to store the blending coefficients, and set the VBO to have a vertex divisor of 0.
void populate_shared_vertex_data_for_VBO(float* out, int NUM_DIVISIONS) {
for(int i = 0; i <= NUM_DIVISIONS; ++i) {
GLfloat t = (GLfloat) division / (GLfloat) (NUM_DIVISIONS + 1);
GLfloat inv_t = (1.0f - t);
// compute bezier coefficients for cubic curve
GLfloat B0 = inv_t * inv_t * inv_t;
GLfloat B1 = 3.0f * inv_t * inv_t * t;
GLfloat B2 = 3.0f * inv_t * t * t;
GLfloat B2 = t * t;
out[0] = B0;
out[1] = B1;
out[2] = B2;
out[3] = B3;
out += 4;
}
}
Load the control points for all curves into a single BIG VBO, set up the 4 per-instance attributes (i.e. specify 4 varying shader inputs, one for each CV, set each stride to sizeof(Cubic_Curve_CVS), and set the divisor to 1).
struct Cubic_Curve_CVS {
float P0[3];
float P1[3];
float P2[3];
float P3[3];
};
Cubic_Curve_CVS VBO_DATA[NUM_CURVES]; ///< load this
The vertex shader ends up being pretty simple to implement:
#version 450
uniform mat4 vs_mvp;
// share this buffer between all indices,
// i.e. glVertexAttribDivisor(0, 0);
layout(location = 0) in vec4 vs_coeffs;
// make these per-instance attributes
// i.e. :
// glVertexAttribDivisor(1, 1);
// glVertexAttribDivisor(2, 1);
// glVertexAttribDivisor(3, 1);
// glVertexAttribDivisor(4, 1);
layout(location = 1) in vec4 vs_CV0;
layout(location = 2) in vec4 vs_CV1;
layout(location = 3) in vec4 vs_CV2;
layout(location = 4) in vec4 vs_CV3;
void main()
{
float B0 = vs_coeffs.x;
float B1 = vs_coeffs.y;
float B2 = vs_coeffs.z;
float B3 = vs_coeffs.w;
vec4 V = vs_CV0 * B0 +
vs_CV1 * B1 +
vs_CV2 * B2 +
vs_CV3 * B3;
gl_Position = vs_mvp * V;
}
and then just render the whole lot in one go with glDrawArraysInstanced.

Drawing 3d and 2d in the same window not working correctly openGl

I am trying to draw some 3d ( a sun) and 2d (ground, cloud, ...) shapes in the same window, it actually worked! But the problem is when I when I run the program, it does not show smooth screen, it shows one shape then the other (while the first disappears), then the next shape and so on...
here is the code, than you.
#include<windows.h>
#include<stdio.h>
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define CIRCLE_RADIUS 0.15f
# define PI 3.14159265358979323846
int eggs_caught = 0, missed_eggs = 0, level_count = 1, points = 0;
int egg_xc, egg_yc;
// for coordinates of egg
int basket_x, basket_y;
// for coordinates of basket
int a = 600, b = 650; // for default size of the screen
int s = 0;
// for menu option
int dropped_eggs = 0;
int speed_1 = 1, speed_2 = 1.5, speed_3 = 2, speed_4 = 2.5;
int w = 48, h = 48, t = 10, e = 9, g = 12;
void myinit();
void start_screen(int, int);
void cloud1();
void egg();
void basket(int, int);
void duck(int, int);
void print_score();
void egg_start();
void color();
void score();
void display(void);
void basket_set(int, int);
void myReshape(int, int);
void keys(unsigned char, int, int);
void menu(int);
void myinit()
{
}
void sun()
{
GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
GLfloat direction[] = { 1.0, 1.0, 1.0, 0.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
glMaterialfv(GL_FRONT, GL_SPECULAR, yellow);
glMaterialf(GL_FRONT, GL_SHININESS, 30);
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_DIFFUSE, yellow);
glLightfv(GL_LIGHT0, GL_SPECULAR, yellow);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glPushMatrix();
glTranslatef(0, 0.0, 0);
glutSolidSphere(0.5, 30, 30);
glPopMatrix();
glPopMatrix();
glFlush();
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
}
void cloud1()
{
float theta;
GLfloat angle;
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(100 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(130 + 50 * cos(theta) / 2, 580 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(140 + 50 * cos(theta) / 2, 600 + 50 * sin(theta) / 2);
}
glEnd();
glLineWidth(1.5);
glColor3f(1, 1, 1);
glBegin(GL_POLYGON);
for (int i = 0; i < 360; i++)
{
theta = i * PI * i / 180;
glVertex2f(170 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
}
glEnd();
glFlush();
}
void backk(int i, int j)
{
glColor3f(0, .5, 1);
glBegin(GL_QUADS);
glVertex2f(0.0 + i, 0.0 + j);
glVertex2f(600.0 + i, 0.0 + j);
glVertex2f(600.0 + i, -500 + j);
glVertex2f(0.0 + i, -500 + j);
glEnd();
glFlush();
}
void ground(int i, int j)
{
glBegin(GL_QUADS);
glColor3f(0, 1.0, 0);
glVertex2f(0.0 + i, 0.0 + j);
glVertex2f(600.0 + i, 0.0 + j);
glVertex2f(600.0 + i, -j);
glVertex2f(0.0 + i, -j);
glEnd();
}
void duck(int i, int j)
{
int h;
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(45 + i, 45 + j);
glVertex2f(70 + i, 20 + j);
glVertex2f(95 + i, 20 + j);
glVertex2f(120 + i, 45 + j);
glVertex2f(95 + i, 70 + j);
glVertex2f(70 + i, 70 + j);
glVertex2f(95 + i, 95 + j);
glVertex2f(82.5 + i, 107.5 + j);
glVertex2f(32.5 + i, 57.5 + j);
glEnd();
glFlush();
for (h = 0; h < 13; h += 4)
{
glBegin(GL_LINES);
glColor3f(0.7, 0.4, 0);
glVertex2f(57.5 + h + i, 52.5 + h + j);
glVertex2f(100 + h + i, 30 + h + j);
glEnd();
glFlush();
}
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex2f(82.5 + i, 107.5 + j);
glVertex2f(65 + i, 107.5 + j);
glVertex2f(50 + i, 95 + j);
glVertex2f(70 + i, 95 + j);
glEnd();
glFlush();
glColor3f(0.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_POINTS);
glVertex2f(76 + i, 101 + j);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_LOOP);
glVertex2f(72.5 + i, 107.5 + j);
glVertex2f(67.5 + i, 112.5 + j);
glVertex2f(72.5 + i, 110 + j);
glVertex2f(77.5 + i, 112.5 + j);
glEnd();
glFlush();
}
void display(void)
{
GLfloat aspect = GLfloat(a) / GLfloat(b);
glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
sun();
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, (GLdouble)a, 0.0, (GLdouble)b, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
cloud1();
ground(0, 650);
backk(0, 650);
duck(40, 375);
duck(180, 375);
duck(320, 375);
}
void myReshape(int w, int h)
{
}
void keys(unsigned char key, int x, int y)
{
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(a, b);
glutCreateWindow("EGG GAME");
myinit();
glutInitWindowPosition(100, 100);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutKeyboardFunc(keys);
glutIdleFunc(display);
glutReshapeFunc(myReshape);
glutMainLoop();
}
not using GLUT but this is What I see at first look.
glClear(GL_DEPTH_BUFFER_BIT);
why not clear also color? try glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
no glutSwapBuffers();
without this call at the end of display function your render is not updated when it needs to.
no glFlush/glFinish before swapping buffers
its safe to have them at the end. I see you got them in some of the rendering calls not all though.
using int operands for glVertex2f
Why not use glVertex2i instead when all of your coordinates are integers anyway. The int to float conversions slowing things down ...
Take a look at some simple GLUT example I just found:
cube.c
In there the Display look like this:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawBox(); // here yoru rendering stuff instead
glFlush(); // I usually add this before swapping buffers
glutSwapBuffers();
}
so change your code accordingly...
On top of all this I would maybe try to use Blending for the clouds ...

OpenGL depth test works but not as expected

Using Windows7, VS2013, Qt 5.6, OpenGL 4.4
The code in question is as follows
void TestClass::paintGL()
{
/*
* Clear the screen
*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glClearColor(0, 0.25, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(0.0);
glDepthFunc(GL_LEQUAL);
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
int i = 0;
i++;
}
/*
*/
//*************************************************
//double xx = mRotation.x() * mRotation.x();
//double xy = mRotation.x() * mRotation.y();
//double xz = mRotation.x() * mRotation.z();
//double xw = mRotation.x() * mRotation.scalar();
//double yy = mRotation.y() * mRotation.y();
//double yz = mRotation.y() * mRotation.z();
//double yw = mRotation.y() * mRotation.scalar();
//double zz = mRotation.z() * mRotation.z();
//double zw = mRotation.z() * mRotation.scalar();
//double m00 = 1 - 2 * (yy + zz);
//double m01 = 2 * (xy - zw);
//double m02 = 2 * (xz + yw);
//double m03 = 0;
//double m10 = 2 * (xy + zw);
//double m11 = 1 - 2 * (xx + zz);
//double m12 = 2 * (yz - xw);
//double m13 = 0;
//double m20 = 2 * (xz - yw);
//double m21 = 2 * (yz + xw);
//double m22 = 1 - 2 * (xx + yy);
//double m23 = 0;
//double m30 = 0;
//double m31 = 0;
//double m32 = -30;
//double m33 = 1;
//double blarg[] = {m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33};
//glLoadMatrixd(&blarg[0]);
//*************************************************
QMatrix4x4 yaw;
yaw.rotate(mYPR.x(), QVector3D(0, -1, 0));
QMatrix4x4 pitch;
pitch.rotate(mYPR.y(), QVector3D(1, 0, 0));
QMatrix4x4 roll;
roll.rotate(mYPR.z(), QVector3D(0, 0, -1));
QMatrix4x4 translate;
translate.translate(0, 0, -30);
//QMatrix4x4 vnToOpenGL(0, 0, -1, 0,
// 1, 0, 0, 0,
// 0, -1, 0, 0,
// 0, 0, 0, 1);
QMatrix4x4 vnToOpenGL(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
QMatrix4x4 openGLMatrix = vnToOpenGL * translate * yaw * pitch * roll * vnToOpenGL.transposed();
glLoadMatrixf(reinterpret_cast<const float*>(openGLMatrix.constData()));
int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
QString ytext(QString("yaw : ") + QString::number(mYPR.x()));
QString ptext(QString("pitch : ") + QString::number(mYPR.y()));
QString rtext(QString("roll : ") + QString::number(mYPR.z()));
QString dtext(QString("depth : ") + QString::number(depth));
QPainter painter(this);
painter.drawText(10, 10, ytext);
painter.drawText(10, 25, ptext);
painter.drawText(10, 40, rtext);
painter.drawText(10, 55, dtext);
painter.end();
//*************************************************
//double scalar = std::acos(mRotation.scalar()) * 2;
//double X = std::asin(mRotation.x()) * 2;
//double Y = std::asin(mRotation.y()) * 2;
//double Z = std::asin(mRotation.z()) * 2;
//glRotated(scalar * radToDeg, X * radToDeg, Y * radToDeg, Z * radToDeg);
glScaled(mScale, mScale, mScale);
QVector3D orthogonalPoint;
QVector3D orthogonalVector;
QVector3D currentNormal;
for (size_t index = 0; index < mSphere->getTriangles().size(); index++)
{
// BEGIN CODE IN QUESTION
glEnable(GL_DEPTH_TEST);
//glDepthMask(GL_TRUE);
//glClearDepth(0.0);
//glDepthFunc(GL_LEQUAL);
// END CODE IN QUESTION
currentNormal = mSphere->getTriangles()[index].getNormal();
orthogonalVector = QVector3D::crossProduct(QVector3D(currentNormal.x(), currentNormal.y(), currentNormal.z()),
QVector3D(currentNormal.x(), currentNormal.y(), 0));
orthogonalVector.normalize();
glLineWidth(1.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(currentNormal.x(), currentNormal.y(), currentNormal.z());
glEnd();
glLineWidth(3.0);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, -1);
glEnd();
glLineWidth(3.0);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glEnd();
glLineWidth(3.0);
glColor3f(0.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(currentNormal.x(), currentNormal.y(), currentNormal.z());
for (size_t fanIndex = 0; fanIndex < 9; ++fanIndex)
{
double degrees = static_cast<double>(fanIndex) * (360.0 / mTargetTesselations);
QMatrix4x4 matrix;
matrix.rotate(degrees, currentNormal.x(), currentNormal.y(), currentNormal.z());
orthogonalPoint = (orthogonalVector * matrix) / 20.0;
glVertex3d(currentNormal.x() + orthogonalPoint.x(),
currentNormal.y() + orthogonalPoint.y(),
currentNormal.z() + orthogonalPoint.z());
}
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(currentNormal.x(), currentNormal.y(), currentNormal.z());
for (size_t fanIndex = 0; fanIndex < 9; ++fanIndex)
{
double degrees = 360.0 - (static_cast<double>(fanIndex) * (360.0 / mTargetTesselations));
QMatrix4x4 matrix;
matrix.rotate(degrees, currentNormal.x(), currentNormal.y(), currentNormal.z());
orthogonalPoint = (orthogonalVector * matrix) / 20.0;
glVertex3d(currentNormal.x() + orthogonalPoint.x(),
currentNormal.y() + orthogonalPoint.y(),
currentNormal.z() + orthogonalPoint.z());
}
glEnd();
}
/*
* Don't forget about the model-view matrix
*/
glPopMatrix();
}
I had bee searching basically all night to figure out why the depth test was not working. Things in the distance were being drawn over the things in the foreground. Finally, after writing halfway through a question here on stackoverflow I placed the code
glEnable(GL_DEPTH_TEST);
//glDepthMask(GL_TRUE);
//glClearDepth(0.0);
//glDepthFunc(GL_LEQUAL);
at the start of my for loop in the paintGL function. Low and behold the depth was correct. So, now that I have it working I'd really like to know WHY it is working. Why does this work properly because I enabled 'GL_DEPTH_TEST' in the loop? If I don't manually change it shouldn't the state remain the same? I'd like to know because knowing is half the battle.

Drawing Circle with OpenGL

I'm trying to draw simple circle with C++/OpenGl
my code is:
#include <GL/glut.h>
#include <math.h>
void Draw() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glColor3f (0.0, 0.0, 0.0);
glVertex3f (0.1, 0.1, 0.0);
glVertex3f (0.9, 0.1, 0.0);
glVertex3f (0.9, 0.9, 0.0);
glVertex3f (0.1, 0.9, 0.0);
glEnd();
glFlush();
}
void DrawCircle(float cx, float cy, float r, int num_segments)
{
glBegin(GL_LINE_LOOP);
for(int ii = 0; ii < num_segments; ii++)
{
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void Initialize() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(950, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("Universum");
Initialize();
glutDisplayFunc(Draw);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
DrawCircle(0.5, 0.5, 0.2, 5);
glutMainLoop();
return 0;
}
I'm beginner with OpenGL and now i'm starting to learn,
Can someone please explain me why i don't get the circle (i only see the black box),
Thanks!
It looks like immediately after you draw the circle, you go into the main glut loop, where you've set the Draw() function to draw every time through the loop. So it's probably drawing the circle, then erasing it immediately and drawing the square. You should probably either make DrawCircle() your glutDisplayFunc(), or call DrawCircle() from Draw().
#include <Windows.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define window_width 1080
#define window_height 720
void drawFilledSun(){
//static float angle;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -10);
int i, x, y;
double radius = 0.30;
//glColor3ub(253, 184, 19);
glColor3ub(255, 0, 0);
double twicePi = 2.0 * 3.142;
x = 0, y = 0;
glBegin(GL_TRIANGLE_FAN); //BEGIN CIRCLE
glVertex2f(x, y); // center of circle
for (i = 0; i <= 20; i++) {
glVertex2f (
(x + (radius * cos(i * twicePi / 20))), (y + (radius * sin(i * twicePi / 20)))
);
}
glEnd(); //END
}
void DrawCircle(float cx, float cy, float r, int num_segments) {
glBegin(GL_LINE_LOOP);
for (int ii = 0; ii < num_segments; ii++) {
float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle
float x = r * cosf(theta);//calculate the x component
float y = r * sinf(theta);//calculate the y component
glVertex2f(x + cx, y + cy);//output vertex
}
glEnd();
}
void main_loop_function() {
int c;
drawFilledSun();
DrawCircle(0, 0, 0.7, 100);
glutSwapBuffers();
c = getchar();
}
void GL_Setup(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
gluPerspective(45, (float)width / height, .1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("GLUT Example!!!");
glutIdleFunc(main_loop_function);
GL_Setup(window_width, window_height);
glutMainLoop();
}
This is what I did. I hope this helps. Two types of circle are here. Filled and unfilled.
There is another way to draw a circle - draw it in fragment shader.
Create a quad:
float right = 0.5;
float bottom = -0.5;
float left = -0.5;
float top = 0.5;
float quad[20] = {
//x, y, z, lx, ly
right, bottom, 0, 1.0, -1.0,
right, top, 0, 1.0, 1.0,
left, top, 0, -1.0, 1.0,
left, bottom, 0, -1.0, -1.0,
};
Bind VBO:
unsigned int glBuffer;
glGenBuffers(1, &glBuffer);
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*20, quad, GL_STATIC_DRAW);
and draw:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_VALUE);
glVertexAttribPointer(ATTRIB_VERTEX , 3, GL_FLOAT, GL_FALSE, 20, 0);
glVertexAttribPointer(ATTRIB_VALUE , 2, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Vertex shader
attribute vec2 value;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
varying vec2 val;
void main() {
val = value;
gl_Position = projectionMatrix*viewMatrix*vertex;
}
Fragment shader
varying vec2 val;
void main() {
float R = 1.0;
float R2 = 0.5;
float dist = sqrt(dot(val,val));
if (dist >= R || dist <= R2) {
discard;
}
float sm = smoothstep(R,R-0.01,dist);
float sm2 = smoothstep(R2,R2+0.01,dist);
float alpha = sm*sm2;
gl_FragColor = vec4(0.0, 0.0, 1.0, alpha);
}
Don't forget to enable alpha blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
UPDATE: Read more
We will find the value of X and Y from this image. We know, sinθ=vertical/hypotenuse and cosθ=base/hypotenuse from the image we can say X=base and Y=vertical. Now we can write X=hypotenuse * cosθ and Y=hypotenuse * sinθ.
Now look at this code
void display(){
float x,y;
glColor3f(1, 1, 0);
for(double i =0; i <= 360;){
glBegin(GL_TRIANGLES);
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
i=i+.5;
x=5*cos(i);
y=5*sin(i);
glVertex2d(x, y);
glVertex2d(0, 0);
glEnd();
i=i+.5;
}
glEnd();
glutSwapBuffers();
}
glBegin(GL_POLYGON); // Middle circle
double radius = 0.2;
double ori_x = 0.0; // the origin or center of circle
double ori_y = 0.0;
for (int i = 0; i <= 300; i++) {
double angle = 2 * PI * i / 300;
double x = cos(angle) * radius;
double y = sin(angle) * radius;
glVertex2d(ori_x + x, ori_y + y);
}
glEnd();
Here is a code to draw a fill elipse, you can use the same method but replacing de xcenter and y center with radius
void drawFilledelipse(GLfloat x, GLfloat y, GLfloat xcenter,GLfloat ycenter) {
int i;
int triangleAmount = 20; //# of triangles used to draw circle
//GLfloat radius = 0.8f; //radius
GLfloat twicePi = 2.0f * PI;
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x, y); // center of circle
for (i = 0; i <= triangleAmount; i++) {
glVertex2f(
x + ((xcenter+1)* cos(i * twicePi / triangleAmount)),
y + ((ycenter-1)* sin(i * twicePi / triangleAmount))
);
}
glEnd();
}
I have done it using the following code,
glBegin(GL.GL_LINE_LOOP);
for(int i =0; i <= 300; i++){
double angle = 2 * Math.PI * i / 300;
double x = Math.cos(angle);
double y = Math.sin(angle);
gl.glVertex2d(x,y);
}
glEnd();
glBegin(GL_POLYGON);
double x = 2;
double y = 2;
for (int i = 0; i <= 360; i++) {
glVertex2d(x * sin(i), y * cos(i));
}
glEnd();

lighting the sun giving absurd results

I am trying to develop space simulator. I am trying to use sun as the light source. My problem is that the lighting dosent work as expected. Maybe i am using the wrong calculation for the normals. I am using a single "createsphere" function to create a sphere, and then use different coordinates and sizes to display them. The problem is that all the spheres on the screen show almost the same effect(i.e i've applied only one light source but it seems to have been implemented to all the spheres) .and also the light rotates along with them. I am not sure where the problem is ...i am posting my code ...
the code for sphere display
void DisplaySphere_sun (double R, GLuint texture)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int b,m = 0;
glScalef (0.0125 * R, 0.0125 * R, 0.0125 * R);
glBindTexture (GL_TEXTURE_2D, texture);
glBegin (GL_TRIANGLE_STRIP);
for ( b = 0; b <VertexCount; b++)
{
/*if((b%3)==0)
{
glNormal3f(normal[m].x,normal[m].y,normal[m].z);
m++;
}*/
glTexCoord2f (VERTEX[b].U, VERTEX[b].V);
/*glNormal3f(-VERTEX[b].X, -VERTEX[b].Y, -VERTEX[b].Z);*/
glVertex3f (VERTEX[b].Y, VERTEX[b].X, -VERTEX[b].Z);
}
m = 0;
for ( b = 0; b <VertexCount; b++)
{
/*if((b%3)==0)
{
glNormal3f(normal[m].x,normal[m].y,normal[m].z);
m++;
}*/
glTexCoord2f (VERTEX[b].U, -VERTEX[b].V);
/* glNormal3f(-VERTEX[b].X, -VERTEX[b].Y, -VERTEX[b].Z);*/
glVertex3f (VERTEX[b].Y, VERTEX[b].X, VERTEX[b].Z);
}
glEnd();
//glRotatef(120,0,0,0);
}
the code for creating a sphere
void CreateSphere (double R, double X, double Y, double Z) {
int n,m;
double a;
double b;
n = 0;
m = 0;
for( b = 0; b <= 90 - space; b+=space){
for( a = 0; a <= 360 - space; a+=space)
{
VERTEX[n].X = R * sin((a) / 180 * PI) * sin((b) / 180 * PI) - X;
VERTEX[n].Y = R * cos((a) / 180 * PI) * sin((b) / 180 * PI) + Y;
VERTEX[n].Z = R * cos((b) / 180 * PI) - Z;
VERTEX[n].V = (2 * b) / 360;
VERTEX[n].U = (a) / 360;
n++;
VERTEX[n].X = R * sin((a) / 180 * PI) * sin((b + space) / 180 * PI) - X;
VERTEX[n].Y = R * cos((a) / 180 * PI) * sin((b + space) / 180 * PI) + Y;
VERTEX[n].Z = R * cos((b + space) / 180 * PI) - Z;
VERTEX[n].V = (2 * (b + space)) / 360;
VERTEX[n].U = (a) / 360;
n++;
VERTEX[n].X = R * sin((a + space) / 180 * PI) * sin((b) / 180 * PI) - X;
VERTEX[n].Y = R * cos((a + space) / 180 * PI) * sin((b) / 180 * PI) + Y;
VERTEX[n].Z = R * cos((b) / 180 * PI) - Z;
VERTEX[n].V = (2 * b) / 360;
VERTEX[n].U = (a + space) / 360;
n++;
VERTEX[n].X = R * sin((a + space) / 180 * PI) * sin((b + space) /180 * PI) - X;
VERTEX[n].Y = R * cos((a + space) / 180 * PI) * sin((b + space) /180 * PI) + Y;
VERTEX[n].Z = R * cos((b + space) / 180 * PI) - Z;
VERTEX[n].V = (2 * (b + space)) / 360;
VERTEX[n].U = (a + space) / 360;
n++;
}
}
}
and code for lighting the sun
glPushMatrix();
gluLookAt (0.0, 10.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); //defines a viewing transformation.
// Now translate to the sun
glTranslatef(0.0, -7.0, 3.0);
/* For LIGHT0 */
GLfloat lightZeroPosition[] = {0.0f, 0.0f, 0.0f, 1.0f};
/*GLfloat lightvec[] = {0.5f, 0.2f, 0.0f, 1.0f};*/
GLfloat lightZeroColor[] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat amb[] = {1, 1, 1, 1};
GLfloat spec[] = {0.3, 0.3, 0.3, 1};
glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
glEnable(GL_LIGHT0);
glRotatef(angle,0,0,1);
DisplaySphere(5,textures);
// function to display the sun
glPopMatrix();
I'm a bit puzzled, why you don't draw the sun at the orign of the solar system? The sun is a star, and stars carry over 95% of their stellar systems mass, so the center of gravity of the whole thing is within the sun for most planets (only Jupiter has so much mass, that it shifts the center of gravity slightly outside the sun's photosphere radius).
As for your lighting problem, one normally doesn't illuminate light sources. Just switch off lighting when drawing the sun. Then when drawing the planets place the light source within the sun. OpenGL is not a global renderer, i.e. after you've drawn something, it completely forgets about it, i.e. you won't get any lighting interactions between the things you draw (means also, no shadows for free).
This is how I'd draw a solar system (pseudocode):
draw_solar_system():
glPushMatrix()
glDisable(GL_LIGHTING)
draw_origin_sphere(sun_radius)
glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_POSITION, (0., 0., 0., 1.))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (1., 1., 1., 1.))
glLightfv(GL_LIGHT0, GL_AMBIENT, (0., 0., 0., 1.))
for p in planets:
glPushMatrix()
glRotatef(p.orbital_inclination, p.axis_of_orbital_inclination)
glRotatef(p.orbital_angle, 0., 1., 0.)
glTranslatef(p.orbit_radius, 1., 0. 0.)
glRotate(p.axial_of_inclination, p.axis_of_axis_inclination)
glRotate(p.time_of_day, 0., 1., 0.)
draw_origin_sphere(p.radius)
glPopMatrix()
glPopMatrix()