Calling gluPerspective and gluLookAt gives me an undefined reference? - c++

I'm trying the following source, from Instant Glew:
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glu.h>
#include <GL/gl.h>
void initGraphics()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
const float lightPos[4] = {1, .5, 1, 0};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void onResize(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(40, (float) w / h, 1, 100);
glMatrixMode(GL_MODELVIEW);
}
void onDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0);
glutSolidTeapot(1);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Teapot");
initGraphics();
glutDisplayFunc(onDisplay);
glutReshapeFunc(onResize);
glutMainLoop();
return 0;
}
My build setup is the Windows 10 VSCode, with MSYS2, and a Makefile like this:
OBJS = 01-teapot.cpp
OBJ_NAME = C:/<"MyProjectPath">/build/01-teapot
INC_PATH = -IC:/msys64/mingw64/include/GL -LC:/msys64/mingw64/include/GL
INC_LINK_LIBS = -lglew32 -lopengl32 -lfreeglut
compiling :
g++ -Wall $(OBJS) $(INC_PATH) $(INC_LINK_LIBS) -o $(OBJ_NAME) -g
But the output is like:
C:\Users\<"myUser">\AppData\Local\Temp\cc5d3AtP.o: In function `onResize(int, int)':
c:\<"MyProjectPath">\PaPu_Instant_GLEW/01-teapot.cpp:22: undefined reference to `gluPerspective'
C:\Users\<"myUser">\AppData\Local\Temp\cc5d3AtP.o: In function `onDisplay()':
c:\<"MyProjectPath">\PaPu_Instant_GLEW/01-teapot.cpp:31: undefined reference to `gluLookAt'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:32: compilando] Error 1
I really don't know where I'm failing. Did I forget to link some lib? I tried to add -lglut -lGLU already, on the linked libs, but the compiler can't find it...

gluLookAt is a function from the GL Utility library. You need to include -lglu32 in the linker options. It's explained in Using GLUT with MinGW.
Also the order in which you give the libraries matter; see my related answer for reference. In your case, replace glfw3 with freeglut.
I believe you are using GLUT and GLU for learning OpenGL which is okay but be informed that they were part of OpenGL 1 back in the day but is no longer an integral part of OpenGL and are deprecated. If you're doing production-level work, I'd recommend using a more mature library like GLFW (instead of GLUT/FreeGLUT); GLM has all the convenience functions that GLU provides. See towards the end of datenwolf's answer.

Related

Is there any way to call OpenGL code writing by c++ in python via pybind11?

I've writed a toy example using OpenGL and c++
#include <GL/glut.h>
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glOrtho(-5, 5, -5, 5, 5, 15);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
return;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0, 0);
glutWireTeapot(3);
glFlush();
return;
}
void test()
{
int argc = 0;
char **argv=NULL;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(300, 300);
glutCreateWindow("OpenGL 3D View");
init();
glutDisplayFunc(display);
glutMainLoop();
}
And then build the code using
gcc -o test test.c -lGL -lGLU -lglut
It works fine. But I want to call this function in Python, than I've tried
# include <pybind11/pybind11.h>
...
PYBIND11_MODULE(py2cpp, m)
{
m.doc() = "opengl test";
m.def("display", &test, "test opengl");
}
Build code above using
g++ -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` -lGL -lGLU -lglut test.cpp -o py2cpp`python3-config --extension-suffix` -I /home/xiaohanbao/anaconda3/envs/ros/include/python3.8
I compiled the code successfully. But when I import the library using import py2cpp, I got
Import Error: /path/py2cpp.cpython-38-x86_64-linux-gnu.so: undefined symbol: glutInitWindowPosition
Is there any way to fix it?

QOpenGLWidget show black screen

I tried the QOpenGLWidget example described here:
https://stackoverflow.com/a/31524956/4564882
but I get only a black widget. The code is exactly the same. this the code associated to the QopenGLWidget:
OGLWidget::OGLWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
OGLWidget::~OGLWidget()
{
}
void OGLWidget::initializeGL()
{
glClearColor(0,0,0,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
}
void OGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f( 0.5, -0.5, 0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f( 0.0, 0.5, 0);
glEnd();
}
void OGLWidget::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (float)w/h, 0.01, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5,0,0,0,0,1,0);
}
I tried the example here: https://doc.qt.io/archives/qt-5.3/qtopengl-2dpainting-example.html. It works fine (trying the both base class: QGLWidget and QOpenGLWidget. this is the code associated to the Widget:
GLWidget::GLWidget(Helper *helper, QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), helper(helper)
{
elapsed = 0;
setFixedSize(200, 200);
setAutoFillBackground(false);
}
void GLWidget::animate()
{
elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
repaint();
}
void GLWidget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
painter.setRenderHint(QPainter::Antialiasing);
helper->paint(&painter, event, elapsed);
painter.end();
}
I use Qt 5.5.1 binairies built on my machine. I let the Build Configuration by default, so it is based on Qt ANGLE not Desktop OpenGL.
What is the problem of such a behaviour?
In my case, my laptop uses NVIDIA external graphics card. So I went to NVIDIA Control Panel -> Manage 3D Settings -> Program Settings, and then selected "high-performance" for the .EXE file. This worked.
The problem was because I use Qt5 binaries built with the default configuration. The default in Qt 5.5 is "dynamic" GL -- both ANGLE (ES2)
ANGLE ((Almost Native Graphics Layer Engine) is an open source project by
Google. Its aim is to map OpenGL ES 2.0 API calls to DirectX 9 API.)
and Desktop backends (Desktop OpenGL)are built, the decision on which one to use is taken at runtime.
The problem is that ANGLE only supports OpenGL>3.x, so the first code that I test is deprecated and not supported by ANGLE. The second is supported, that's why it worked.
So, I rebuild Qt to target Desktop OpenGL only to support my deprecated code, using:
configure -debug-and-release -opensource -opengl desktop -platform win32-msvc2015
and then run nmake, link my application to the new binaries, and my code works well!
I had a black screen on desktop. I solved the problem by adding this line of code:
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
For example, put it here:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

Cannot install glut for Dev-c++ on windows 64 bit

I want to install glut library for Dev-c++, I do the following:
Download and install Dev-c++ from here, (Dev-Cpp 5.7.1 TDM-GCC x64 4.8.1 Setup.exe)
Add glut from: Tool -> Check for
Packages... -> install glut 3.7.6 from Devpak site
(Base working directory: C:\Program Files (x86)\Dev-Cpp)
Copy glut.h, glutf90.h from include\GL to MinGW64\include\GL and
MinGW64\x86_64-w64-mingw32\include\GL (I don't know where is the correct folder so I add to somewhere else...)
Copy libglut32.a from lib\ to MinGW64\lib (reference from youtube here)
Open Dev-c++ and
Create an empty C++ project, add these options to project Linker Parameters:-lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32
Add some file, like this:
//Lab01_Perimitives.cpp
/* -- INCLUDE FILES ------------------------------------------------------ */
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
/* ----------------------------------------------------------------------- */
void myInit( void ) {
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glColor3f( 1.0, 0.0, 1.0 );
glPointSize( 3.0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
void myDisplay( void ) {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glBegin(GL_POLYGON);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(0.25, 0.25, 0.0);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(0.75, 0.25, 0.0);
glColor3f(0.5f,0.5f,1.0f);
glVertex3f(0.75, 0.75, 0.0);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(0.25, 0.75, 0.0);
glEnd();
glutSwapBuffers();
}
/* ----------------------------------------------------------------------- */
int main( int argc, char *argv[] ) {
// Initialize GLUT.
glutInit( &argc, argv );
// Set the mode to draw in.
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
// Set the window size in screen pixels.
glutInitWindowSize( 640, 480 );
// Set the window position in screen pixels.
glutInitWindowPosition( 100, 150 );
// Create the window.
glutCreateWindow( "Lab01" );
// Set the callback funcion to call when we need to draw something.
myInit( );
glutDisplayFunc( myDisplay );
// Initialize some things.
// Now that we have set everything up, loop responding to events.
glutMainLoop( );
}
/* ----------------------------------------------------------------------- */
But when I compile I get these error:
c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe skipping incompatible C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/libglut32.a when searching for -lglut32
c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe skipping incompatible c:/program files (x86)/dev-cpp/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../lib/libglut32.a when searching for -lglut32
...etc...
c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe cannot find -lglut32
E:\Mon hoc\Do hoa may tinh\Lab01\collect2.exe [Error] ld returned 1 exit status
E:\Mon hoc\Do hoa may tinh\Lab01\Makefile.win recipe for target 'Lab01.exe' failed
What is problem here, how to fix it?
My computer is running Windows 8.1 64 bit

Compile error with OpenGL

Here is the program that I am trying to run
////////////////////////////////////////////////////
// square.cpp
//
// Stripped down OpenGL program that draws a square.
//
// Sumanta Guha.
////////////////////////////////////////////////////
#include <iostream>
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
using namespace std;
// Drawing (display) routine.
void drawScene(void)
{
// Clear screen to background color.
glClear(GL_COLOR_BUFFER_BIT);
// Set foreground (or drawing) color.
glColor3f(0.0, 0.0, 0.0);
// Draw a polygon with specified vertices.
glBegin(GL_POLYGON);
glVertex3f(20.0, 20.0, 0.0);
glVertex3f(80.0, 20.0, 0.0);
glVertex3f(80.0, 80.0, 0.0);
glVertex3f(20.0, 80.0, 0.0);
glEnd();
// Flush created objects to the screen, i.e., force rendering.
glFlush();
}
// Initialization routine.
void setup(void)
{
// Set background (or clearing) color.
glClearColor(1.0, 1.0, 1.0, 0.0);
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
// Set viewport size to be entire OpenGL window.
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
// Set matrix mode to projection.
glMatrixMode(GL_PROJECTION);
// Clear current projection matrix to identity.
glLoadIdentity();
// Specify the orthographic (or perpendicular) projection,
// i.e., define the viewing box.
glOrtho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0);
// Set matrix mode to modelview.
glMatrixMode(GL_MODELVIEW);
// Clear current modelview matrix to identity.
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
// Press escape to exit.
case 27:
exit(0);
break;
default:
break;
}
}
// Main routine: defines window properties, creates window,
// registers callback routines and begins processing.
int main(int argc, char **argv)
{
// Initialize GLUT.
glutInit(&argc, argv);
// Set display mode as single-buffered and RGB color.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Set OpenGL window size.
glutInitWindowSize(500, 500);
// Set position of OpenGL window upper-left corner.
glutInitWindowPosition(100, 100);
// Create OpenGL window with title.
glutCreateWindow("square.cpp");
// Initialize.
setup();
// Register display routine.
glutDisplayFunc(drawScene);
// Register reshape routine.
glutReshapeFunc(resize);
// Register keyboard routine.
glutKeyboardFunc(keyInput);
// Begin processing.
glutMainLoop();
return 0;
}
I am certain I have glut and OpenGL installed and up to date, and this is the error that I am getting (I am compiling the code the way it is laid out in the book which is from 2011):
ubuntu:~/Downloads/Code$ gcc square.cpp -o square -I
/usr/include/ -L /usr/lib -lglut -lGL -lGLU -lX11
/tmp/ccAq6h4h.o:square.cpp:function
__static_initialization_and_destruction_0(int, int): error: undefined reference to 'std::ios_base::Init::Init()'
/tmp/ccAq6h4h.o:square.cpp:function
__static_initialization_and_destruction_0(int, int): error: undefined reference to 'std::ios_base::Init::~Init()' collect2: ld returned 1
exit status
I wrote my own code and left it as a c file and it compiled
Was a simple error of wrong files being compiled.

Why does my opengl freeglut application compile as C but not as C++?

It isn't a problem with the code because it compiles when I tell the compiler to compile it as C but it doesn't compile when I set the settings to default (which is to compile it as C++). When I compile it as C++ I get numerous errors along the lines of "undefined reference to glClear"
I'm using Microsoft's Visual Studio C++ compiler. I have everything properly linked.
The code is:
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
void display(void)
{
/* Clear all pixels */
glClear(GL_COLOR_BUFFER_BIT);
/* draw white polygon (rectangle) with
* corners at (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.25, 0.25, 0.0);
glVertex3f(0.75, 0.25, 0.0);
glVertex3f(0.75, 0.75, 0.0);
glVertex3f(0.25, 0.75, 0.0);
glEnd();
/* don't wait!
* start processing buffered OpenGL routines
*/
glFlush();
}
void init(void)
{
/* Select clearing background color */
glClearColor(0.0, 0.0, 0.0, 0.0);
/* Initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with “hello”
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow("hello");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ISO C requires main to return int. */
}
Also, if anyone has a proper resource for learning opengl with C++ could you please recommend it?
It's likely because glClear is not declared in any of the header files currently included. In C, an undeclared function is often assumed to have a certain type based on its arguments, and returning an int. So when compiling with C, you might get a warning about it being undeclared (I hopefully you have warnings enabled, and read them when compiling?), but it will do its best to compile and link it.
C++ is more strict about undeclared functions.
As Alexadre Jasmin and Bart have pointed out, verify that you are linking OpenGL libraries correctly. I use -lGLU -lGL -lglut with freeglut on ubuntu.
If that doesn't solve the problem, try adding #define GLUT_DISABLE_ATEXIT_HACK at the top of your cpp file.