simple OpenGL code, but won't draw anything.

Trying to create this seemingly simply program and make it draw.
It is a pseudocode example from the text book.
It compiles and runs without errors, but all I get is a blank white screen.
It should be drawing GL_LINE_STRIPs.

Suggestions??
Thanks.


// Experiment 2
// Experimentation with scaling and translation
// 6 Oct 2015

#include <windows.h>
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/Glut.h>
using namespace std;

#define PI 3.14159265

// ******************************************************************
// Global Variables

	const float screenWidth = 800.0;		// max screen width in pixels
	const float screenHeight = 600.0;		// max screen height in pixels
	float color[] = { 0.0, 0.0, 0.0 };		// color
	GLdouble A = screenWidth / 4.0;			// scaling and translation variables
	GLdouble B = 0.0;
	GLdouble C = screenHeight / 2.0;
	GLdouble D = C;

// ******************************************************************
// Function Declarations

	void myInit(void);				// my initialization routine
	void myDisplay(void);				// the redraw function
	void Random_Color();				// generate a random color
	float f(float x);				// any f(x) I want
	void Print_Msg(int, char*);			// Print messages to screen

// ******************************************************************

int main(int argc, char* argv[])
{
	srand(time(NULL));				// seed RNG
	Random_Color();					// gen a random color for drawing

	glutInit(&argc, argv);				// initialize the toolkit
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);	// set the display mode
	glutInitWindowSize(screenWidth, screenHeight);	// set the window size

	glutInitWindowPosition(0, 0);			// set window starting position

	glutCreateWindow("Experiment 2");		// open the screen window
	glutDisplayFunc(myDisplay);			// register the redraw function
	myInit();					// call my initialization routine
	glFlush();
	glutMainLoop();					// go into a perpetual loop

}

// ******************************************************************
// START FUNCTION DEFINITIONS
// ******************************************************************

// ******************************************************************
// myInit()

void myInit(void) {

	glClearColor(1.0, 1.0, 1.0, 0.0);		// the background color is white
	// glColor3f(0.0f, 0.0f, 0.0f);			// the drawing color is black
	glPointSize(2.0);				// a 'dot' is 2 by 2 pixels
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, screenWidth, 0.0, screenHeight);
}

// ******************************************************************
// myDisplay()

void myDisplay(void) {

	glClear(GL_COLOR_BUFFER_BIT);			// clear the screen
	glColor3f(color[0], color[1], color[2]);	// set drawing color

	glBegin(GL_LINE_STRIP);				// Draw line strips
	for (int x = 0; x <= 300; x += 3) {		// scaled and 
		glVertex2d(A * x + B, C * f(x) + D);	// translated
	}
	glEnd();
	glFlush();					// send all output to display

}

// ******************************************************************
// Random_Color()

void Random_Color(void) {
	// This routine will generate a random color and store it in color[0-2].
	// color[] is a global array of floats.

	for (int c = 0; c < 3; c++) { color[c] = ((float)(rand() % 100) / 100); }
}


// ******************************************************************
// f()

float f(float x) {
	// any f(x) I want

	return cos(2 * PI * x);
}


// ******************************************************************
// Add next function here


// ******************************************************************
// Print_Msg()

void Print_Msg(int Msg, char* Message) {
	// Receives an Int value and a char string
	// If the INT is zero, simply print the string argument.
	// If the INT is non-zero, print the corresponding message from the
	// list below, ignoring the string, if any, supplied as the 2nd arg.

	switch (Msg) {
	case 0: cout << endl << Message;		        // print msg as given
		break;
	case 1: cout << endl << "Error 1" << endl;	// Placeholder
		break;
	case 2: cout << endl << "Error 2" << endl;	// Placeholder
		break;
	default: break;
	}                       // end SWITCH
	cout << endl;      // pad a line before returning
}                           	// end function. Returns nothing.


x is always an integer, so cos(2 * PI * x) is always 1. Thus C * f(x) + D is always 600, i.e. you’re drawing a horizontal line exactly along the edge of the window. Depending upon floating-point rounding error, the line may or may not be drawn; even if it is drawn, it won’t be particularly visible.

Also, successive X coordinates are 0, 600, 1200, …, so most of them are far to the right of the viewport.

Thanks, that was helpful. But still confusing…

I modified the call to f(x) to cast x to float:
f((float)x)

But, in the call to cosine: cos(2.0 * PI * x), the output is still = 1.

However, casting the whole expression to int: cos((int)2.0 * PI * x)) , seems to work.

So it is odd that casting the cosine argument to an int works since cosine expects a double.

Well, I think I can close this inquiry as complete since we figured out that the code was in fact drawing, just not somewhere where I could see it.
I just need to confirm that the functions and methods are getting the type of variables they are expecting.
Thanks for all the help.

The attached output shows the values:
printf("%f, %f, %f
", 2.0 * PI * x, cos(2.0 * PI * x), cos((int)(2.0 * PI * x)));

0.000000, 1.000000, 1.000000
18.849556, 1.000000, 0.660317
37.699112, 1.000000, 0.765414
56.548668, 1.000000, 0.853220
75.398224, 1.000000, 0.921751
94.247780, 1.000000, 0.969459
113.097335, 1.000000, 0.995267
131.946891, 1.000000, 0.584209
150.796447, 1.000000, 0.699251
169.646003, 1.000000, 0.798496
188.495559, 1.000000, 0.879703
207.345115, 1.000000, 0.941037
226.194671, 1.000000, 0.981111
245.044227, 1.000000, 0.999022
263.893783, 1.000000, 0.626468
282.743338, 1.000000, 0.736213

[QUOTE=rstout;1279755]Thanks, that was helpful. But still confusing…

I modified the call to f(x) to cast x to float:
f((float)x)

But, in the call to cosine: cos(2.0 * PI * x), the output is still = 1.
[/QUOTE]
That won’t help in the slightest. If you want to draw a sine wave, you have to change the step to something much less than one, so that you’re getting multiple samples per cycle.

You missed an opening parenthesis somewhere.

Not really. The compiler knows that cos() expects a double and will convert it.

The reason that this works is that casting the argument to an int means that it’s no longer a multiple of 2PI. Pi is irrational, so a non-zero integer will never be a multiple of pi. Beyond that, the value modulo 2pi will be different for each call, meaning that the cosine will also be different.