I am reading Schaum's outlines COMPUTER GRAPHICS. Book says that a simple graphic pipeline is something like this: geometric representation --> transformation --> scan conversion
(though the author has decided to teach scan conversion chapter before transformation chapter). I wish to learn this simple pipeline through an example in openGL. suppose I wish to create a line with end coordinates (150,400) and (700,100) in window of size (750,500). Below code works very well. All I am asking to experts is to explain the 'steps in sequence' when is transformation happening and when scan conversion. I know it may sound stupid but I really need to get this straight. I am just an adult beginner learning graphics at my own as a hobby.
My guess is that scan conversion is not happening here in program. it is done by openGL automatically between glBegin and glEnd calls. Am I right?
#include <GL/glut.h>
void init(void)
{
glClearColor (0.5, 0.2, 0.3, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor4f(0.5,0.7,0.3,0.0);
glLineWidth(3);
}
void display(void)
{
glBegin(GL_LINES);
glVertex2i(50, 400);
glVertex2i(700, 100);
glEnd();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100,150);
glutInitWindowSize(750,500); // aspect ratio of 3/2
glutCreateWindow (argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop(); // this is when the frame buffer is displayed on the screen
return (0);
}
All stages done within OpenGL implementation (mostly in hardware). You specify states and data, then GL will - if speaking in terms of old GL 1.0 - assemble data into vertices, pass every vertex through transformation stage, rasterize resulting primitives into fragments, perform per-fragment tests (that may discard some fragments), and update resulting pixels on render target.
There is no point in user code that may be on 'one stage' in pipeline - it doesn't have callbacks, and usually as many as possible stages working at the same time.
Related
I am novice to OpenGL and I read that glutWireCubedraws a wire cube. Now that it is not appearing on when I run my code, I am wondering what does it do? Does it draw a cube or where have I gone wrong in my code?
#include<GL/glut.h>
GLdouble cubeSize= 10.0;
//FUNCTIONS DECLARATIONS - PROTOTYPES
void init(void);
void display(void);
int main(int argc, char ** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("Wire Cube");
init();
glutDisplayFunc(display);
glutMainLoop();
}
//FUNCTIONS IMPLEMENTAION - DEFINITION
void init(void){
glClearColor(0.0,0.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void display(void){
glBegin(GL_POLYGON);
glutWireCube(5.0);
glEnd();
glFlush();
}
Calling glutWireCube is not allowed inside a glBegin/glEnd block. Only glVertex to specify vertices and all the functions to set the current values of some vertex attributes (like glNormal, glColor, ...) can be used there.
How glutWireCube internally works is not specified. It might as well use immediate mode, but in this case, it will do its own glBegin/glEnd calls.
Conceptually, trying to put a cube into a GL_POLYGON is also not going to work. GL_POLYGON is for drawing a single, flat, convex polygon, and it is totally impossible to draw a whole cube as one polygon.
Furthermore, you do not set up any of the GL_MODELVIEW or GL_PROJECTION matrices. This means you directly draw in clip space, and glutWireCube with size 5 will draw a cube which completely lies outside of your viewing frustum, so you will see nothing.
The exact same code snippet is working on another machine but its not working properly for me. The GLUT is working absolutely fine as it open the created window but the line segment is not shown on the window which means there is a problem with opengl. It is not even changing the background color of the window.
I even test the opengl on my windows with a testing application and its working fine.
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void init(void){
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 400.0, 0.0, 400.0);
}
void linesegment(void){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2i(180, 15);
glVertex2i(10, 145);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(400, 400);
glutCreateWindow("Testing Open GL");
init();
glutDisplayFunc(linesegment);
glutMainLoop();
return 0;
}
Most likely you're running into the rather new class of problems introduced by compositing graphics systems (Aero in Windows, Quartz Extreme on MacOS X and a multitude of various programs on Linux/X11). The gist of the problem is, that compositing is inherently double buffered: There's always an offscreen (back) buffer for the window to be drawn. And when a program indicates that it's finished with drawing the compositor will integrate it into the on-screen image.
This however brings a few caveats. Most importantly, single buffered drawing somehow needs to indicate that it's finished. While OpenGL's glFinish call should suffice from a implementors point of view, most compositing systems are not sensitive to it. You'll have to create a double buffered window pixel format and do a buffer swap to make the compositor present your image.
So for your program:
replace GLUT_SINGLE with GLUT_DOUBLE in glutInitDisplayMode
replace glFlush with glutSwapBuffers
I am starting with openGL and c++, and I was wondering why I don't see anything on the window. Here is my code:
#include <GLUT/GLUT.h>
#include <stdlib.h>
void init() {
glClearColor(0, 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3i(-0.5, -0.5, 0);
glVertex3i(0, 0.5, 0);
glVertex3i(0.5, -0.5, 0);
glEnd();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(400, 400);
glutCreateWindow("Window");
init();
glutDisplayFunc(display);
glutMainLoop();
}
I have a few questions:
If I run the program like this all I see is a white window... Didn't I set the color to blue?
When I do glutSwapBuffers() at the end of display function and run the program, I see the blue window without the triangle. So, I thought glutSwapBuffers() function only worked with double buffering.
And the most important, where the hell is my triangle? O.o Didn't I translate the camera with glTranslatf() function to -10 in the z-axes? If you are wondering why I used gluPerspective, I have to say that I am trying out new things, but neither works if I use gluOrtho2D().
I don't know if I am missing something or what. Maybe I need to search more information about this, but I think most of the code is correct.
1 & 2) Well you don't have to call glutSwapBuffers() when using single buffer. But you have to call glFlush(), so the draw commands are executed on the GPU.
3) I noticed that you are creating vertices with double coordinates, but you are calling integer version of glVertex** function (decimal part will be truncated) - it means that you will be drawing triangle with zero size.
Use glVertex3d() or glVertex3f() instead of glVertex3i().
Small note: intermediate mode is deprecated in the latest OpenGL.
Anyone knows why this happens when trying to generate a simple square in OpenGL?
I am using the following source code from the book Computer Graphics Through OpenGL: From Theory to Experiments.
////////////////////////////////////////////////////
// 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've been trying for the longest time...
For more details here:
The screen opens displaying only the background, if you drag it along, it will then proceed to track the background, and this is the result of moving the window to the bottom and then moving it up to the original position again. I've tested the same source code on a linux machine, and it works fine... :(
EDIT: I have tried using glutSwapBuffers() and that didn't seem to work either.
On Windows Vista and newer Windows operating systems, there is a component known as the Desktop Window Manager (DWM) which has a special mode called "Desktop Composition" that draws windows into offscreen buffers and then composites them. It does this to provide new visual effects such as live window previews in the Alt+Tab screen.
A consequence of this new architecture is that you cannot draw single buffered applications (in windowed mode anyway) the same way you could in Windows XP (or in Windows Vista+ with Desktop Composition disabled). In a nutshell, the DWM uses a copy of your render context's back buffer for composition. You should switch to double buffered drawing.
To use double buffered drawing in GLUT, you would use GLUT_DOUBLE instead of GLUT_SINGLE in your call to glutInitDisplayMode (...). Additionally, you need to replace your calls to glFlush (...) with glutSwapBuffers (...).
Try adding a call to glutSwapBuffers(); at the end of drawScene and removing GLUT_SINGLE from glutInitDisplayMode. Single-buffer mode has all sorts of compatibility issues. On Windows it uses the software rasterizer which is VERY slow and has even more issues.
If that doesn't work, try clearing the depth buffer by changing glClear to glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); and glClearcolor to glClearColor(1.0, 1.0, 1.0, 1.0);.
Also, this example uses legacy OpenGL, which is significantly slower than modern OpenGL and has many other problems. Unless you are using a GPU that's more than a decade old, you have zero reason to use it. Technically, modern GPUs aren't even required to support it. If you need a good modern OpenGL tutorial, http://open.gl is a good one. Just look for an OpenGL 2.1 (or later) tutorial.
I have an openGL code rendering an image, and I need reload this image on code to reedit it, in a loop. How can I load this in the code?
glutInit (&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
//
glClearColor(1.0, 0.0, 0.0, 0.0);
glutInitWindowPosition(0,0);
glutInitWindowSize(800,800);
glutCreateWindow("Model");
//glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
//glFrontFace(GL_CCW);
//
glFrontFace(GL_CW);
//
glEnable(GL_DEPTH_TEST);
float near = 10000;
float far = (131943+500000);
int f = 80000;
//glFrustum(-f, f, -f, f, near, far);
//
glOrtho(-f, f, -f, f, near, far);
float s = 1;
glScalef(s,s,.125);
glTranslated(0,0, -200000);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(rotation);
glutMainLoop();
In Display() function a model is loaded, I need load this model rendered, and edit it again. Maybe i need to load the pixels from window, because a loop will edit the model, till get the wanted shape
You should render it to texture, and then work on the allocated texture buffer to render it on screen finally.
You could erase your code, because it doesn't give any valuable information, besides the fact you aren't using shaders. Which should also be considered, as it is the proper and the fastest way to do what you want.
Another good keyword for google might be "Multi-pass rendering".