Symbol(s) not found for architecture x86_64 (OpenGL with xcode) - c++

I am very new to using OpenGL. The program I am trying to run is provided by my professor so I have not actually written any of it, I am having problems getting the program to run. The program is suppose to just make a white square on a black screen. I am using mac Sierra 10.12.2. Also I have already changed the deployment target to 10.8 because of the errors from compiling in anything later than that. Now when I try to build and run in xcode I get 2 errors.
These are the errors im getting,
Undefined symbols for architecture x86_64:
"exit(int)", referenced from:
myKeyboard(unsigned char, int, int) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Now here is the code exactly as I am trying to compile it.
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
const int screenHeight = 480; // window height is 480
const int screenWidth = 640 ; //window width is 640
// <<<<<<<<<<<<<<<<<<<<< Prototypes >>>>>>>>>>>>>>>>>>
void exit(int) ;
// <<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>
void myInit(void)
{
glClearColor(1.0,1.0,1.0,0.0); // set white background color
glColor3f(0.0f, 0.0f, 0.0f); // set the drawing color
glPointSize(4.0); // a ?dot? is 4 by 4 pixels
glLineWidth(4.0); // a ?dot? is 4 by 4 pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
// <<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
glBegin(GL_POINTS);
// glBegin(GL_LINE_STRIP) ;
// glBegin(GL_LINE_LOOP) ;
// glBegin(GL_POLYGON);
glVertex2i(289, 190); // Dubhe
glVertex2i(320, 128) ; // Merak
glVertex2i(239, 67) ; // Phecda
glVertex2i(194, 101) ; // Megrez
glVertex2i(129, 83) ; // Alioth
glVertex2i(75, 73) ; // Mizar
glVertex2i(74, 74) ; // Alcor
glEnd();
glFlush(); // send all output to display
}
// <<<<<<<<<<<<<<<<<<<<<<<< myKeyboard >>>>>>>>>>>>>>
void myKeyboard(unsigned char theKey, int mouseX, int mouseY)
{
switch(theKey)
{
case 'Q':
case 'q':
exit(-1); //terminate the program
default:
break; // do nothing
}
}
// <<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>
int main(int argc, char** argv)
{
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize(640, 480); // set window size
glutInitWindowPosition(100, 150); // set window position on screen
glutCreateWindow("Big Deep - Type Q or q to quit") ; // open the screen window
glutDisplayFunc(myDisplay); // register redraw function
glutKeyboardFunc(myKeyboard); // register the keyboard action function
myInit();
glutMainLoop(); // go into a perpetual loop
}
Any help would be greatly appreciated!

You need to add the following near the top of your source file:
#include <stdlib.h>
and remove this line:
void exit(int) ;
First, you should always use the proper system headers to get the declarations of system library functions. This is especially true on macOS where the declaration can have important attributes which affect how the function is linked.
However, the lack of such attributes is not really what tripped you up in this case. The issue here is that you're building a C++ program. In C++, a function's argument types are part of its symbol name. You can see this in the error message you've quoted. But the exit() function is part of the C standard library. It's not natively a C++ interface. Its symbol name is _exit, with no indication of its argument count or types.
Your code has incorporated references to a symbol that translates to exit(int) while the actual symbol in the system library is just _exit. They don't match, so you get a symbol-not-found linker error.
The stdlib.h header takes special care to wrap its function declarations in extern "C" { ... } when it's included for a C++ translation unit. So, including that header to get the declaration tells the C++ compiler not to use a C++-style symbol name but to instead just use the C-style symbol name.
You could also "solve" the issue by putting extern "C" on the declaration of exit() in your own code, but that's the wrong approach. Just include the proper header.

Related

C++ opengl intersecting glScissor

A Project I am working on involves me using glScissor, in some cases i need to perform a scissor on an area twice (or more), with the goal of only rendering what is within both scissor boxes.
The issue im running into is that the second scissor box just overrides the previous one, meaning only the last box set is used instead of both.
I have tried existing solutions such as setting scissor1, push matrix, enable scissor_test, set scissor2, disable scissor_test, popmatrix, disable scissor_test. As proposed here: glScissor() call inside another glScissor()
I could not get these to produce any difference, I had also tried glPushAttrib instead of matrix but still no difference.
Here is an example program I wrote for scissor testing, its compiled by g++ and uses freeglut, the scissoring takes place in display():
/*
Compile: g++ .\scissor.cpp -lglu32 -lfreeglut -lopengl32
*/
#include <GL/gl.h>//standard from mingw, already in glut.h - header library
#include <GL/glu.h>//standard from mingw, already in glut.h - utility library
#include <GL/glut.h>//glut/freeglut - more utilities, utility tool kit
void display();
void reshape(int, int);
void timer(int);
void init(){
glClearColor(0, 0, 0, 1);
}
int main(int argc, char **argv){
glutInit(&argc, argv);//init glut
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);//init display mode, add double buffer mode
//init window
glutInitWindowPosition(200, 100);//if not specified, it will display in a random spot
glutInitWindowSize(500, 500);//size
//create window
glutCreateWindow("Window 1");
//give glut a function pointer so it can call that function later
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);//call certain function after a specified amount of time
init();
glutMainLoop();//once this loop runs your program has started running, when the loop ends the program terminates
}
float xPos = -10;
int state = 1;//1 = right, -1 = left
//our rendering happens here
void display(){
//clear previous frame
glClear(GL_COLOR_BUFFER_BIT);//pass in flag of frame buffer
//draw next frame below
glLoadIdentity();//reset rotations, transformations, ect. (resets coordinate system)
//we are using a model view matrix by default
//TEST
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, 100, 1000);
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
glScissor(50, 0, 1000, 1000);
//assuming both scissors intersect, we should only see the square between 50 and 100 pixels
//draw
glBegin(GL_QUADS);//every set of 3 verticies is a triangle
//GL_TRIANGLES = 3 points
//GL_QUADS = 4 points
//GL_POLYGON = any amount of points
glVertex2f(xPos, 1);//the 2 is the amount of args we pass in, the f means theyr floats
glVertex2f(xPos, -1);
glVertex2f(xPos+2, -1);
glVertex2f(xPos+2, 1);
glEnd();//tell opengl your done drawing verticies
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
glDisable(GL_SCISSOR_TEST);
//display frame buffer on screen
//glFlush();
glutSwapBuffers();//if double buffering, call swap buffers instead of flush
}
//gets called when window is reshaped
void reshape(int width, int hight){
//set viewport and projection
//viewport is a rectangle where everything is drawn, like its the window
glViewport(0, 0, width, hight);
//matrix modes: there is model view and projection, projection has depth
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//reset current matrix after changing matrix mode
gluOrtho2D(-10, 10, -10, 10);//specify 2d projection, set opengl's coordinate system
glMatrixMode(GL_MODELVIEW);//change back to model view
}
//this like makes a loop
void timer(int a){
glutPostRedisplay();//opengl will call the display function the next time it gets the chance
glutTimerFunc(1000/60, timer, 0);
//update positions and stuff
//this can be done here or in the display function
switch(state){
case 1:
if(xPos < 8)
xPos += 0.15;
else
state = -1;
break;
case -1:
if(xPos > -10)
xPos -= 0.15;
else
state = 1;
break;
}
}
I tried following example solutions, such as push/pop matrix/attrib, but couldnt get anything to work
There is no first or second scissor box. There is just the scissor box. You can change the scissor box and that change will affect subsequent rendering. But at any one time, there is only one.
What you want is to use the stencil buffer to discard fragments outside of an area defined by rendering certain values into the stencil buffer.

Multiple undefined reference errors when linking freeglut and codelite (minGW32 c++)

While trying to install (if that's the right word) opengl onto my codelite IDE to create c++ opengl programs, I have run into multiple undefined reference errors in the freeglut_std.h file as well as well known functions like glutMainLoop() are also "undefined".
So I have actually found the function definitions in the freeglut_std.h file and I have tried messing with the header file to make sure that there is no false conditions causing my definitions not to be created. (like making #if true ..... #endif (so that the code will for sure run)). I have experience in C but have never linked files like this before. Going through several webpages like: https://www.ntu.edu.sg/home/ehchua/programming/opengl/HowTo_OpenGL_C.html , https://www.transmissionzero.co.uk/computing/using-glut-with-mingw/ I linked my files. (Also note, that this question has been asked before however most posts had different solutions that didn't work for me)
So here is how codelite is compling my files (with not erroneous code) :
C:/mingw-w64/i686-7.3.0-posix-dwarf-rt_v5-rev0/mingw32/bin/g++.exe -c "C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL/main.cpp" -g -O0 -Wall -I"C:\mingw-w64\i686-7.3.0-posix-dwarf-rt_v5-rev0\mingw32\include" -o ./Debug/main.cpp.o -I. -I.
C:/mingw-w64/i686-7.3.0-posix-dwarf-rt_v5-rev0/mingw32/bin/g++.exe -o ./Debug/cpp_openGL #"cpp_openGL.txt" -L. -m32 -static-libgcc -static-libstdc++ -static -lpthread -L"C:\mingw-w64\i686-7.3.0-posix-dwarf-rt_v5-rev0\mingw32\lib" -Wl,--subsystem,windows -lfreeglut -lopengl32 -lglu32
mingw32-make.exe[1]: Leaving directory 'C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL'
====0 errors, 0 warnings====
However for something like this (actual test code):
/*
* GL01Hello.cpp: Test OpenGL C/C++ Setup
*/
#include <windows.h> // For MS Windows
#include <GL/glut.h> // GLUT, includes glu.h and gl.h
/* Handler for window-repaint event. Call back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer
// Draw a Red 1x1 Square centered at origin
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(-0.5f, -0.5f); // x, y
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
glFlush(); // Render now
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutCreateWindow("OpenGL Setup Test"); // Create a window with the given title
glutInitWindowSize(320, 320); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutDisplayFunc(display); // Register display callback handler for window re-paint
glutMainLoop(); // Enter the infinitely event-processing loop
return 0;
}
I get the following errors:
./Debug/main.cpp.o: In function `glutInit_ATEXIT_HACK':
C:/mingw-w64/i686-7.3.0-posix-dwarf-rt_v5-rev0/mingw32/include/GL/freeglut_std.h:623: undefined reference to `_imp____glutInitWithExit#12'
./Debug/main.cpp.o: In function `glutCreateWindow_ATEXIT_HACK':
C:/mingw-w64/i686-7.3.0-posix-dwarf-rt_v5-rev0/mingw32/include/GL/freeglut_std.h:625: undefined reference to `_imp____glutCreateWindowWithExit#8'
./Debug/main.cpp.o: In function `glutCreateMenu_ATEXIT_HACK':
C:/mingw-w64/i686-7.3.0-posix-dwarf-rt_v5-rev0/mingw32/include/GL/freeglut_std.h:627: undefined reference to `_imp____glutCreateMenuWithExit#8'
./Debug/main.cpp.o: In function `main':
C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL/main.cpp:32: undefined reference to `_imp__glutInitWindowSize#8'
C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL/main.cpp:33: undefined reference to `_imp__glutInitWindowPosition#8'
C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL/main.cpp:34: undefined reference to `_imp__glutDisplayFunc#4'
C:/Users/admin/Documents/codelite/workspaces/c_plus_plus/cpp_openGL/main.cpp:35: undefined reference to `_imp__glutMainLoop#0'
collect2.exe: error: ld returned 1 exit status
====7 errors, 0 warnings====
The file that it is complain about is freeglut_std.h, the following is copied from the file:
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
#ifndef FREEGLUT_BUILDING_LIB
#if defined(__GNUC__)
#define FGUNUSED __attribute__((unused))
#else
#define FGUNUSED
#endif
static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }//<--has problem with
#define glutInit glutInit_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }//<--has problem with
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); } //<--has problem with
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
#endif
#endif
#ifdef __cplusplus
}
#endif
Note that I could get rid the 3-undefined references with:
#define GLUT_DISABLE_ATEXIT_HACK
However the remaining errors still exist.
A final note in freeglut_std.h the following lines exist (are these not definitions)
FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
And something must be working since it doesn't complain about
glutinit(param...)
glutCreateWindow(param...)
UPDATE
I should let you guys know that I have a freeglut.dll file saved in the same location as my application. However that shouldn't matter because I also tried a static build white I used -DFREEGLUT_STATIC in the complier command, and linked -lfreeglut_static This had the same result, except the _imp_ part of the error was gone.
So in short I am bamboozled here, Any help is always greatly appreciated.
(p.s. please spare me mods).

GL_INVALID_OPERATION error 1218 (0x0502) when using simple OpenGL commands glvertex2i, glColor3ub

This is my first time using OpenGL, so this may be a stupid question, but my code is pulling a GL_INVALID_OPERATION error (1218 or 0x0502) between glBegin() and glEnd(). I'm only calling a couple simple commands but glGetError() returns 0 at the start of this function, and 1218 at the end.
This function is intended to be used to draw a single instance of any simple shape, and after stepping through in the debugger, the variables are what I intended them to be. Also note that, despite this being a stupid question, I spent several hours last night and several hours today searching Google and my textbook for possible solutions, and have found nothing helpful due to the vague nature of OpenGL errors.
void drawShape(GLenum type, int numPoints, GLubyte r, GLubyte g, GLubyte b, vertex vertices, ...) {
glBegin(type);
glColor3ub(r, g, b);
// iterate through vertices
va_list vertexList;
va_start(vertexList, vertices); // use vertexList for iteration
for (int i = 0; i < numPoints; ++i) {
vertex point = i == 0 ? vertices : va_arg(vertexList, vertex);
// add a new point at (x, y)
glVertex2i(std::get<0>(point), std::get<1>(point));
}
glEnd();
}
This function is called as follows:
drawShape(GL_LINE, 2, 0, 0, 0, vertex{ 10, 10 }, vertex{ 400, 10 });
And the context I'm using is FreeGLUT which is initialized as follows:
// gross workaround for calling init with no arguments
int argc = 1;
char *argv[1] = { (char*)"" };
glutInitContextVersion(4, 1);
glutInit(&argc, argv);
// RGB window, double buffer
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
// sets values necessary for window initialization
glutInitWindowPosition(INIT_X, INIT_Y);
glutInitWindowSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// draw the window and create the scene
glutCreateWindow(WORKING_WINDOW_TITLE);
glClearColor(1, 1, 1, 1); // set clear color to white
glutDisplayFunc(render);
glutMainLoop();
The problem lies in the call to glBegin itself. GL_LINE is not a valid parameter for this function. Due to this, all commands after that are not called inside a valid glBegin/glEnd block.
If you want to draw lines, the correct parameter is GL_LINES.
The first step when debugging an OpenGL application that doesn't support a debug context should always be to identify which function call produces the first error. This can, for example, be done by calling glGetError() after each OpenGL call until the problematic line is found. Also note, that glError returns errors in arbitrary order if more than one error happened.

c++ program and scope variables [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I compiled this c++ program with dev-c++ and give "was not declared in this scope" for all variables.
#include <cstdlib> // standard definitions
#include <iostream> // C++ I/O
#include <cstdio> // C I/O (for sprintf)
#include <cmath> // standard definitions
#include <GL/glut.h> // GLUT
#include <GL/glu.h> // GLU
#include <GL/gl.h> // OpenGL
using namespace std; // make std accessible
//-----------------------------------------------------------------------
// Global data
//-----------------------------------------------------------------------
GLint TIMER_DELAY = 10000; // timer delay (10 seconds)
GLfloat RED_RGB[] = {1.0, 0.0, 0.0}; // drawing colors
GLfloat BLUE_RGB[] = {0.0, 0.0, 1.0};
//-----------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------
static bool isReversed = false; // draw reversed colors?
//-----------------------------------------------------------------------
// Callbacks
// The global variable "isReversed" describes the drawing state.
// When false, a blue rectangle is drawn on top of red diamond.
// When true the colors are reversed. The "isReversed" variable is
// complemented whenever the left mouse button is clicked or the
// timer goes off (every 10 seconds).
//-----------------------------------------------------------------------
void myReshape(int w, int h) {
cout << "MyReshape called width=" << w << " height=" << h << endl;
glViewport (0, 0, w, h); // update the viewport
glMatrixMode(GL_PROJECTION); // update projection
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 0.0, 1.0); // map unit square to viewport
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay(); // request redisplay
}
// draw diamond and rectangle
void drawObjects(GLfloat* diamColor, GLfloat* rectColor) {
glColor3fv(diamColor); // set diamond color
glBegin(GL_POLYGON); // draw the diamond
glVertex2f(0.90, 0.50);
glVertex2f(0.50, 0.90);
glVertex2f(0.10, 0.50);
glVertex2f(0.50, 0.10);
glEnd();
glColor3fv(rectColor); // set rectangle color
glRectf(0.25, 0.25, 0.75, 0.75); // draw the rectangle
}
void myDisplay(void) { // display callback
cout << "MyDisplay called" << endl;
glClearColor(0.5, 0.5, 0.5, 1.0); // background is gray
glClear(GL_COLOR_BUFFER_BIT); // clear the window
if (isReversed) // draw the objects
drawObjects(BLUE_RGB, RED_RGB);
else
drawObjects(RED_RGB, BLUE_RGB);
glutSwapBuffers(); // swap buffers
}
void myTimer(int id) { // timer callback
cout << "Timer just went off. Reversing colors." << endl;
isReversed = !isReversed; // reverse drawing colors
glutPostRedisplay(); // request redraw
glutTimerFunc(TIMER_DELAY, myTimer, 0); // reset timer for 10 seconds
}
void myMouse(int b, int s, int x, int y) { // mouse click callback
if (s == GLUT_DOWN) {
cout << "Mouse click detected at coordinates x="
<< x << " and y=" << y << endl;
if (b == GLUT_LEFT_BUTTON) {
isReversed = !isReversed;
cout << "Left mouse click. Reversing colors." << endl;
glutPostRedisplay();
}
}
}
// keyboard callback
void myKeyboard(unsigned char c, int x, int y) {
switch (c) { // c is the key that is hit
case 'q': // 'q' means quit
exit(0);
break;
default:
cout << "Hit q to quit. All other characters ignored" << endl;
break;
}
}
//-----------------------------------------------------------------------
// Main program
// This does all the set up for the program. It creates the game
// and then passes control to glut.
//-----------------------------------------------------------------------
int main(int argc, char** argv)
{
cout <<
"Colors swap every 10 seconds.\n"
"Click left mouse button to swap colors.\n" <<
"Try resizing and covering/uncovering the window.\n" <<
"Hit q to quit." << endl;
glutInit(&argc, argv); // OpenGL initializations
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);// double buffering and RGB
glutInitWindowSize(400, 400); // create a 400x400 window
glutInitWindowPosition(0, 0); // ...in the upper left
glutCreateWindow(argv[0]); // create the window
glutDisplayFunc(myDisplay); // setup callbacks
glutReshapeFunc(myReshape);
glutMouseFunc(myMouse);
glutKeyboardFunc(myKeyboard);
glutTimerFunc(TIMER_DELAY, myTimer, 0);
glutMainLoop(); // start it running
return 0; // ANSI C expects this
}
Where is the problem?
[Error] 'glutPostRedisplay' was not declared in this scope
[Error] 'glutSwapBuffers' was not declared in this scope
[Error] 'glutPostRedisplay' was not declared in this scope
[Error] 'glutTimerFunc' was not declared in this scope
[Error] 'GLUT_DOWN' was not declared in this scope
[Error] 'GLUT_LEFT_BUTTON' was not declared in this scope
[Error] 'glutPostRedisplay' was not declared in this scope
etc.
From the GLUT docs here:
The header files for GLUT should be included in GLUT programs with the following include directive (which you have):
#include <GL/glut.h>
Because a very large window system software vendor (who will remain nameless) has an apparent inability to appreciate that OpenGL's API is independent of their window system API, portable ANSI C GLUT programs should not directly include <GL/gl.h> or <GL/glu.h>. Instead, ANSI C GLUT programs should rely on <GL/glut.h> to include the necessary OpenGL and GLU related header files.
If you are not on windows, this may be causing an issue.
It does look like this file is not being included correctly since even the symbolic constants (e.g. for GLUT_DOWN) are not being resolved.
You should look for the header files that declare these functions and variables and include them in this source file.
A good place to start would be this GL directory you seem to be including glut.h from, assuming it exists.
Check building without calling functions in main(). Then try one by one. I think the error is coming from one of your include files.
Are there any classes defined in those files. Check there header files are ok or not. Check for the existence of header files in specified paths.
Then check the namespaces. If you defined a class with a namespace, don't forget to use using namespace namespace_name or specify full qualified name for variables.

Initialise a QGLWidget with a glClearColor

I have a QMainWindow with a QGLWidget in it. I want the widget to display a 'clear' colour of my own choice, instead of the default black screen.
void MyQGLWidget::initializeGL(void) {
glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
}
void MyQGLWidget::paintGL(void) {
qDebug("Painting grey-ness");
glClear(GL_COLOR_BUFFER_BIT);
// ... Do more stuff, but only after a certain event has happened ...
}
This works, and I noticed that the method is called 4 times during the start-up. However, I only want to paint it blank once in the paintGL() method, because this method is being called very often after the start-up, and there actually is small but significant performance loss if the buffers are cleared at every call.
So I changed the code to this:
void MyQGLWidget::paintGL(void) {
static bool screenOnBlank = false;
if (!screenOnBlank) {
qDebug("Painting grey-ness");
glClear(GL_COLOR_BUFFER_BIT);
screenOnBlank = true;
}
// ... Do more stuff, but only after a certain event has happened ...
}
Now the clearing is only done once, but I am left with a black screen, rather that with the grey screen of glClearColor. Why is this? Why does QGLWidget paint my screen black again? And more importantly, how can I make sure the screen is my own default colour, without repainting it blank at every time step?
Short answer:
In most platforms, the state of your backbuffer is undefined after performing a buffer swap. You can find more details here. Hence, you cannot rely on the behaviour that your buffer remains as you left it before the swap operations. Then, to ensure your program is cross-platform, you have no other choice than calling glClear() at each drawing.
In practice:
It is possible that your platform/configuration do guarantee that your buffer is unchanged, or don't guarantee it but it is still the case in practice. If you know you are in those cases after experimenting (see below), but still have your screen turned black, it means that somehow in your code, you did something "wrong" that makes Qt explicitly call glClear() with its own glClearColor().
You can use this code to see if the buffer remains unchanged after swapBuffers(). It is actually the case in my configuration: Qt 4.8 on Linux 64bits:
// -------- main.cpp --------
#include <QApplication>
#include "GLWidget.h"
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
GLWidget * w = new GLWidget();
w->show();
return app.exec();
}
// -------- GLWidget.h --------
#include <QGLWidget>
#include <QTimer>
class GLWidget: public QGLWidget
{
Q_OBJECT
public:
GLWidget() : i(0), N(60)
{
timer.setInterval(16);
connect(&timer, SIGNAL(timeout()),
this, SLOT(animationLoop()));
timer.start();
}
protected:
void initializeGL()
{
glClearColor(1.0, 0.0, 0.0, 1.0);
}
void resizeGL(int w, int h)
{
glViewport(0, 0, (GLint)w, (GLint)h);
}
void paintGL()
{
bool test = false;
if(i<N)
{
if(test)
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
else
{
if(test)
{
glClearColor(0.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
}
}
private slots:
void animationLoop()
{
i++;
if(i>2*N) i=0;
updateGL();
}
private:
int i, N;
QTimer timer;
};
if test == true, then I always call glClearColor() followed by glClear(), but alternating between a red color and a green color every second. I indeed see the color switching back and forth between red and green.
if test == false, then I only call glClearColor() once and for all in initializeGL(). Then in paintGL, I alternate between calling glClear() or not calling it. The screen stays red, i.e. never turns black (or display a unicorn) even when glClear() is not called.
Hence, regarding your problem:
Either your configuration is different than mine (the implementation of swapBuffers is provided by Qt and differs according to the underlying window system)
Or your code is broken.
Simple way to check: compile my code, and see if it still reproduces the issue. If it does, then you are in case 1., and there is nothing you can do about it (can be considered a bug of Qt, of rather an inconsistency, since the correct behaviour is not specified anywhere in the documentation). Otherwise, you are in case 2., and then you should provide more of your code so we could determine where is the issue.