using of glviewport() in OpenGL - c++

I read this tutorial and I execute it correctly.
However, I wanted to apply some changes. The first change was to see a different view of that circle, for example showing just the 1/4 of the circle. I know this is done by glViewPort(parameters). However, after changing the parameters, nothing happens. I have checked many forums to figure out why this problem occurs, but I couldn't figure out anything.
Can someone explain me more on this and how to use it? (To understand where the problem happens)
This is the code (Which is originally written on that tutorial)
Code:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
gluOrtho2D(0.0,200.0,0.0,200.0);
//glViewport(0, 0, 250, 250);
}
void setPixel(GLint x,GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void Circle(){
int xCenter=100,yCenter=100,r=50;
int x=0,y=r;
int p = 3/2 - r;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f( 1 ,0, 0);
while(x<=y){
setPixel(xCenter+x,yCenter+y);
setPixel(xCenter+y,yCenter+x);
setPixel(xCenter-x,yCenter+y);
setPixel(xCenter+y,yCenter-x);
setPixel(xCenter-x,yCenter-y);
setPixel(xCenter-y,yCenter-x);
setPixel(xCenter+x,yCenter-y);
setPixel(xCenter-y,yCenter+x);
if (p<0)
p += (2*x)+3;
else {
p += (2*(x-y))+5;
y -= 1;
}
x++;
}
glFlush();
}
int main(int argc,char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
glutCreateWindow("My Circl2e");
init();
glViewport(0,0,250,250);
//glLoadIdentity();
glutDisplayFunc(Circle);
glutMainLoop();
return 0;
}
p.s: In some examples I see they use setWindow(parameters) before using glViewPort(parameters). but setWindow() needs library which is not available for ubuntu.

The default GLUT reshape function calls glViewport() with the window size. From the documentation:
If a reshape callback is not registered for a window or NULL is passed to glutReshapeFunc (to deregister a previously registered callback), the default reshape callback is used. This default callback will simply call glViewport(0,0,width,height) on the normal plane (and on the overlay if one exists).
Since you call glViewport() so early, the window will be shaped after you make your call, overriding the viewport you specified.
You either need to register your own reshape function, and call glViewport() with your desired viewport parameters there, or call glViewport() at the start of your Circle() function.

Related

Ifstream doesn't work with OpenGL/freeglut

A program crashes if I try to use ifstream while having OpenGL/freeglut. My code:
#include <fstream>
#include <windows.h>
#include <GL/freeglut.h>
double x, y;
std::ifstream read("coordinates.txt");
void display() {
glBegin(GL_LINE_STRIP);
while (read >> x) //Crashes here
{
read >> y;
glVertex2d(x, y);
}
glEnd();
glFlush();
}
void key(unsigned char mychar, int x, int y) {
if (mychar == 27) {
exit(0);
}
}
void initialize()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-27, 27, -27, 27);
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(1920, 1080);
glutInitWindowPosition(0, 0);
glutCreateWindow("Lorenz Attractor");
initialize();
glutDisplayFunc(display);
glutKeyboardFunc(key);
glColor3d(0, 0, 1);
glutFullScreen();
glutMainLoopEvent();
Sleep(60000);
}
coordinates.txt:
1.1 1.03
2.5 2
3 5.3
I don't even need to include freeglut, I checked out an older project that was working perfectly before and now it crashes as well. Using Code::Blocks with MinGW. Why would this happen? Thanks!
display will be called more than one time. It's called whenever the display needs to be redrawn, such as when the window comes into view, another window is moved over top of it, the window is resized, etc.
display reads a file. Well, after the first time it reads the file, the file will be empty. After all, you opened the file in a global variable (FYI: never do that), and you kept reading until the file was empty.
Don't read files while you're drawing. Read the file into a data structure (say, a vector<float>). Do that before the rendering loop. Then, use the data structure to draw from.

OpenGL Optimization or...?

I'm making a OpenGL game, and I have problem with optimization. When I start it, it does not respond. If in Update() I just put a for loop and _time += 0.1f, I get a blank screen.
void Update(){
for(; ;){
_time += 0.1f;
Render();
}
}
void Render() {
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_colorProgram.use();
GLuint timeLocation = _colorProgram.getUniformLocation("time");
glUniform1f(timeLocation, _time);
_sprite.Render();
_colorProgram.unuse();
glutSwapBuffers();
}
int main(int argc, char** argv) {
std::printf("OpenGL version is %s",glGetString(GL_VERSION));
// Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(520, 200);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("OpenGL [ Shader #1 error pt 3 ]");
// Setup GLEW
if( GLEW_OK != glewInit()){
return 1;
} while( GL_NO_ERROR != glGetError() );
// After creating window
Init();
glutDisplayFunc(Render);
Update();
glutMainLoop();
}
The infinite loop in Update() never lets GLUT pump the event queue.
Use glutTimerFunc() or glutIdleFunc() to call Update() instead. That way execution flow periodically returns to GLUT and GLUT can do what it needs to keep the OS happy.
The proper way to run an animation with GLUT is to use a timer function. This way, GLUT can get back to its main loop, and call your display function. You're not supposed to call the display function directly from your own code.
For example, register a timer function during initialization (the first argument is a time in milliseconds):
glutTimerFunc(10, timerFunc, 0);
Then in the timer function:
void timerFunc(int value) {
_time += 0.1f;
glutPostRedisplay();
glutTimerFunc(10, timerFunc, 0);
}
There are two critical pieces in the code fragment above:
You do not call your Render() function directly. Instead, you call glutPostRedisplay() to tell GLUT that a redisplay is needed. It will then call your Render() function because you registered it as the display function with glutDisplayFunc().
You have to register the timer again. glutTimerFunc() fires the timer only once, not periodically. So you have to re-register it every time it fired.
There is one other problem in your code. You have these calls in your main():
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
...
glutInitDisplayMode(GLUT_DOUBLE);
The flags passed in the second call will override the ones from the first call. While GL_RGBA is the default anyway, you will not get a depth buffer because GL_DEPTH is missing in the second call. You can simply remove the second call, since the first one is most likely what you want.

Sierpinski gasket

i was writing a code in C/C++ and i face an error .
#include "glut.h"
#include <random>
// Classes and structs //
struct GLPoint {
GLfloat x, y;
};
// Method(s) Declration //
void drawDot(GLfloat, GLfloat);
void serpinski_render(void);
void myInti(void);
// Method(s) Implementation //
void drawDot(GLfloat x, GLfloat y){
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void serpinski_render(void)
{
glClear(GL_COLOR_BUFFER_BIT); // Clear the screen from anything is displayed on it
GLPoint T[3] = { { 10, 10 }, { 600, 10 }, { 300, 600 } }; // the three points of parent triangle
int index = rand() % 3; // this mean i will choose a random number between 0 , 3
GLPoint point = T[index];
drawDot(point.x, point.y);
for (unsigned int i = 0; i < 5500; i++) // a loop that going to run 5500 ( a very big number )
{
index = rand() % 3;
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot(point.x, point.y);
}
glFlush();
}
void myInti(void)
{
glClearColor(1, 1, 1, 0); // a white background
glColor3f(0, 0, 0); // black points
glPointSize(3); // 3 pixel point size
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 640, 0, 480);
}
// Main Method //
void main(int argc ,char ** argv )
{
glutInit(&argc, argv); // intilize toolkit
glutInitWindowPosition(100, 150);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480); // windows size is 640 x 480
glutDisplayFunc(serpinski_render);
myInti();
glutMainLoop();
}
i dont know if it will work fine but this code should produce me Sierpinski triangle .
and i face every time i use C++ library in this case the random lib this problem in the stdlib.h making me confused never face something like it before
Error 1 error C2381: 'exit' : redefinition; __declspec(noreturn) differs c:\program files (x86)\microsoft visual studio 12.0\vc\include\stdlib.h 376
There is an incompatibility between glut.h and Visual Studio .NET, which is the usage of both "glut.h" and in your case.
You can solve it by just declaring:
#include <random>
#include "glut.h"
instead of:
#include "glut.h"
#include <random>
Please read this description for further information and for an another solution. ("Header (.h) files" section)
Also your code will possibly fail because of not creating window. You can use glutCreateWindow to create a window. You can also solve this issue by arranging your main like below:
void main(int argc ,char ** argv )
{
glutInit(&argc, argv); // intilize toolkit
glutInitWindowPosition(100, 150);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480); // windows size is 640 x 480
glutCreateWindow("A title");
myInti();
glutDisplayFunc(serpinski_render);
glutMainLoop();
}
Please also read this information for glutCreateWindow function.
You probably have this code in glut.h:
# ifndef GLUT_BUILDING_LIB
extern _CRTIMP void __cdecl exit(int);
# endif
The glut.h header is quite old. This was probably a workaround for an old VC deficiency. Visual C now seems to have a declaration that conflicts with this one. The easy solution is to just delete these lines from the header, since there is a valid definition in stdlib.h.
By the way, all the glVertex, glBegin, glEnd, matrix stack, and many other OpenGL calls are deprecated in favor of shaders.
Perhaps there is also a newer/better glut available. I'd check that out.

GLUT displaying part of desktop instead of what's in my code

Last week, I tried a few examples I found while reading GLUT tutorials and everything was working great.
Now, when I retry those same examples, I get a weird behaviour: my GLUT window displays the part of the desktop that is at the place the window is (so if the GLUT window starts at (100,100) and is sized 500px by 500px, it displays the part of the desktop that starts at (100,100) and ends at (600,600)).
The following example that I tested last week should show a wire teapot on a black background. I'd like to know if there's something wrong with my code (since I don't recall changing anything in it) or if the problems come from the library not being linked correctly or if it's something else that I'm not aware of.
#include <GL/glut.h>
void displayFunc(void);
int glutWindow;
int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
// define the size
glutInitWindowSize(500,500);
// the position where the window will appear
glutInitWindowPosition(100,100);
glutWindow = glutCreateWindow("UITest");
glClearColor(0.0, 0.0, 0.0, 0.0);
glutDisplayFunc(displayFunc);
glutMainLoop();
return EXIT_SUCCESS;
}
void displayFunc(void){
glClear(GL_COLOR_BUFFER_BIT);
glutWireTeapot(0.5);
}
You need to add a call to glFlush() in the end of displayFunc().

OpenGL: From Visual Studio source code to XCode 4?

I am in a class in which we will be learning OpenGL. The professor is using Visual Studio, but that isn't working too well with my install of Parallels, so I just decided to use XCode (which I prefer anyway). I have got basic example code working, but I am having issues running the example that the professor gave us. Here it is:
#include <glut.h> //must be included for OpenGL
#include <gl\gl.h> //must be included for OpenGL
#include <time.h> //must be included for time functions
#include <iostream> //must be included for console input/output
using namespace std;
#define WINDOW_WID 800
#define WINDOW_HEI 600
int randomPx, randomPy;
/////////////////////////////////////////
void myInit(void)
{
randomPx = 400;
randomPy = 300;
glClearColor (1.0, 1.0, 1.0, 0.0); // set background color to black
glShadeModel (GL_FLAT);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
glColor3f(1,0,0); //set the drawing color
glPointSize(10); //set the point size
glBegin(GL_POINTS);
glVertex2d(randomPx,randomPy); //Set the position of the vertex
glEnd();
glutSwapBuffers (); //put everything on your screen
}
void myReshape ( int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION); // set "camera type"
glLoadIdentity (); // clear the matrix
glOrtho(0.0, w, 0.0, h, -1.0, 1.0); // viewing transformation
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
void Animation()
{
srand(time(NULL)+rand()); //set the seed for your rand function
randomPx = rand()%WINDOW_WID;
randomPy = rand()%WINDOW_HEI;
Sleep(200); //put the program to sleep for 200 ms
myDisplay();
}
void myMouse(int button, int state, int x, int y)
{
y = WINDOW_HEI - y;
switch (button)
{
case GLUT_LEFT_BUTTON: //when left mouse button is clicked
if (state == GLUT_DOWN)
{
cout << "When mouse is up, animation starts\n";
}
else if(state == GLUT_UP)
{
glutIdleFunc(Animation); //do Animation when idle
}
break;
case GLUT_RIGHT_BUTTON: //when right mouse button is clicked
if (state == GLUT_DOWN)
{
glutIdleFunc(NULL); //do nothing when idle
}
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
{
exit (-1); //exit your program
}
break;
}
myDisplay();
}
void myMotion(int x, int y)
{
y = WINDOW_HEI - y;
myDisplay();
}
void myKeyboard(unsigned char key, int x, int y)
{
//TODO
myDisplay();
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); // set display mode
// glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize (WINDOW_WID, WINDOW_HEI); // set screen window size
glutInitWindowPosition (100, 100); // set window position on screen
glutCreateWindow (argv[0]); // open the screen window
myInit ();
glutDisplayFunc(myDisplay); // register redraw function
glutReshapeFunc(myReshape); // register reshape function
glutMouseFunc(myMouse); //GLUT provides a way for you to register the function that will be responsable for processing events generated by mouse clicks.
glutMotionFunc(myMotion); //There are two types of motion that GLUT handles: active and passive motion. Active motion occurs when the mouse is moved and a button is pressed.
glutKeyboardFunc(myKeyboard);
//glutPassiveMotionFunc(myPassiveMotion); //Passive motion is when the mouse is moving but no buttons are pressed. If an application is tracking motion, an event will be generated per frame during the period that the mouse is moving.
//glutEntryFunc(processMouseEntry); //GLUT is also able to detect when the mouse leaves or enters the window region. A callback function can be registered to handle these two events.
glutMainLoop(); // go into a perpetual loop
return 0;
}
I took out the imports statements, and replaced them with the imports for example XCode OpenGL code:
#include <iostream>
#include <GLUT/glut.h>
#include <time.h>
And I don't get any error messages, but when I run the application, and click on the window, it does not start the animation it is supposed to. (I know it works, because in Visual Studio on every other computer in the class it worked fine.)
It does register the click on the screen by printing out: "When mouse is up, animation starts"
But after that, it just gives me the Spinning Beachball of Death until I stop it from running via XCode. So is there something else I have to adjust to get this working?
First of all, why are you using a backslash for your import gl.h? Secondly, you should link your code to the GLUT and OpenGL library, so you should include/import them as OpenGL/gl.h and GLUT/glut.h. But your main problem here is the sleep function. It doesn't exist on macs and thus, your code crashes when it tries to animate. Use [NSThread sleepForTimeInterval:0.2] instead if you want to wait for 200 ms. But you will have to change your file extension to .mm in order to use objective-c code and also import the Foundation library to use the NSThread class.
About the sleep.. use
#include <unistd.h> //FROM C
and use
sleep(0.2)
wich is at seconds.. so 2000 miliseconds = 0.2 seconds.. so
just switch from sleep(2000) to sleep(0.2)