When i try to run this code after compiling it, i got only a window border without content, so where is the error?
Note: i am using ubuntu and gcc for compiling
gcc -lglut Simple.c -o Simple
The output
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL Library
#include <GL/glu.h> // Header File For The GLu Library
void SetupRC(void);
void RenderScene(void);
void ChangeSize(GLsizei w, GLsizei h);
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT);
// set the color to these values
// R G B
glColor3f(56.0f, 19.0f,68.0f);
// Draw a filled rectangle with current color
glRectf(-25.0f, 50.0f, 50.0f, -25.0f);
// Flush drawing commands
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(400,200);
glutInitWindowSize(640,468);
glutCreateWindow("Simple");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
return 0;
}
// Setup the rendering state
void SetupRC(void)
{
glClearColor(0.0f, 2.0f, 1.0f, 0.0f);
}
// Handling window resizing
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
// Prevent divide by zero
if (h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
aspectRatio = (GLfloat) w / (GLfloat) h;
if (w <= h) {
glOrtho(-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
}
else
glOrtho(-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Try adding a glutSwapBuffers() to the end of RenderScene().
One thing. You have a depth buffer so you should also add GL_DEPTH_BUFFER_BIT to the clear call.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Related
I do not understand how this main function works. I have a display function, which uses glDrawArrays, but I do not see it being called. I only see it being used as a parameter for glutDisplayFunction.
Here is my main:
int main(int argc, char** argv){
// Set up the window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Hello Triangle");
// Tell glut where the display function is
glutDisplayFunc(display);
// A call to glewInit() must be done after glut is initialized!
GLenum res = glewInit();
// Check for any errors
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
// Set up your objects and shaders
init();
// Begin infinite event loop
glutMainLoop();
return 0;
}
The problem is, I need to create two different triangles, on the same window, using seperate VAOs and VBOs. I've created the seperate VAO and VBO for my second triangle. However, I do not see how I am meant to generate and link my buffers, draw my arrays, switch to my second buffer, and draw those arrays, when I do not even know when my display function is being called.
My display function looks like this:
void display(){
glClear(GL_COLOR_BUFFER_BIT);
// NB: Make the call to draw the geometry in the currently activated vertex buffer. This is where the GPU starts to work!
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
}
All operations could be done in separate function named asyouwant called from main
example:
#include <GL/glut.h>
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(300, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello world :D");
glutDisplayFunc(displayMe); // = > draw in displayme function
glutMainLoop();
return 0;
}
void displayMe(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.5, 0.0, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
// a second geoform
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.0, -0.5, 0.0);
glEnd();
glFlush();
}
As complement: for VAO and buffer
1- Init (declare VAO , declare buffer of vertices, ...)
GLuint VaoID;
glGenVertexArrays(1, &VaoID);
glBindVertexArray(VaoID);
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
Once time only
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
2- Use it (bind and draw in display fucntion)
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
void changeSize(int w, int h)
{
if(h == 0)
h = 1;
float ratio = w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(40,ratio,1.5,20);
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT );
glLoadIdentity();
glTranslatef(0.0,0.0,-5.0);
glDrawArrays(GL_TRIANGLES,0,3);
glutSwapBuffers();
}
void init()
{
GLfloat verts[] = {
0.0, 1.0,
-1.0, -1.0,
1.0, -1.0
};
GLuint bufferid;
glGenBuffers(1,&bufferid);
glBindBuffer(GL_ARRAY_BUFFER,bufferid);
glBufferData(GL_ARRAY_BUFFER,sizeof(verts),verts,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
if(glGetError()==GL_NO_ERROR)
printf("no error");
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("MM 2004-05");
glewInit();
init();
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
if (GLEW_ARB_vertex_program && GLEW_ARB_fragment_program)
printf("Ready for GLSL\n");
else {
printf("No GLSL support\n");
//exit(1);
}
glutMainLoop();
return 0;
}
When using glGenBuffers my screen turns out black and shows no error. If i draw some other shape without using buffers they are displayed but not with buffer objects.
openGL version:3.0
operating system:ubuntu
IDE:eclipse
When using glGenBuffers you're using the OpenGL-3.0 specification. To draw anything in OpenGL-3.0+ you need to use shaders, hence why the screen is black; your triangle isn't being shaded.
You are using calls for generic vertex attributes here:
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
Generic vertex attributes can only be used in combination with shaders. As long as you're using the fixed function pipeline, you also have to use fixed function vertex attributes.
The corresponding calls using fixed function attributes are:
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, 0);
I have small code drawing a square initially but when I maximize the window it changes to rectangle. I know this has do with aspect ratio and when I add glutReshapeFunc(Reshape); call it works perfectly, I mean after maximizing the window, it remains square only. ReshapFunc is called every time display is modified and before the first display as well.
I am not getting just by adding reshapefunc, how it maintains aspect ratio. Please help me understanding this. I am copying my code here:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.5, 0.5, 1.0);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5);
glVertex2f(-0.5, 0.5);
glEnd();
glutSwapBuffers();
glFlush();
}
void Reshape(int w, int h) {
glutPostRedisplay();
}
void init()
{
glClearColor(1.0, 0.0, 1.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("basics");
glutDisplayFunc(display);
// If I comment this, it will become rectangle.
glutReshapeFunc(Reshape);
init();
glutMainLoop();
}
Your problem is related to the use of gluOrtho2D (...). If you want to preserve aspect ratio, your projection matrix needs to be defined based on the dimensions of your window.
I suggest you do this in your reshape function:
GLdouble aspect = (GLdouble)w / (GLdouble)h;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
glViewport (0, 0, w, h);
I wrote some lines of code to draw a spinning rectangle:
#include "glut.h"
static GLfloat spin = 0.0; /* current angle */
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0); /* rotate Oxyz (OZ) */
glColor3f(1.0, 1.0, 1.0); /* bgr-color: white; */
glRectf(-25.0, -25.0, 25.0, 25.0); /* Rectangle */
glPopMatrix();
glutSwapBuffers(); /* Swap 2 buffer */
}
void spinDisplay(void)
{
spin = spin + 2.0; /* Add 2 degrees for every loop action */
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay(); /* Alert: Redraw */
}
/* Change window mode */
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h); /* change viewport */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Mouse interaction */
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON: /* left mouse */
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay); /* idle mode switch to spinDisplay */
break;
//case GLUT_MIDDLE_BUTTON: /* middle mouse button */
//if (state == GLUT_DOWN)
//glutIdleFunc(NULL);
//break;
default:
break;
}
}
/* main */
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); /* double buffer */
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("spinning rectangle");
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape); /* reshape func (redraw) when window size changed */
glutMouseFunc(mouse); /* mouse func */
glutMainLoop();
return 0;
}
And I wanna save framebuffer to image (JPEG, BMP, TIFF) or file. Could you tell me how? Do I need to use some lib like jpeglib, libtiff?
Here is a simple opengl program by me. I'm trying to clear the screen before I draw a triangle. I've called glClear() in my init() function, however, it seemed that it failed to clear the screen.
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
void myIdleFunc()
{
glBegin(GL_TRIANGLES);
{
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f(-1.0f, -1.0f);
glVertex2f(1.0f, -1.0f);
}
glEnd();
glFlush();
usleep(1000000);
}
void init()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutCreateWindow("Hello, World!");
init();
glutIdleFunc(myIdleFunc);
glutMainLoop();
return 1;
}
Here is a screen-shot, the text is from the gnome terminal in the back ground.
Where's your display callback? You shouldn't use the idle function for drawing.
All drawing needs to take place in the appropriate callbacks, the GL context might not be active until glutMainLoop starts running, and with no active context, your commands simply get ignored (without a context, there might not even be a place to store errors for retrieval with glGetError).
NOTE: Usually you want to clear the buffer at the beginning of every frame. You might get away with clearing just once with single-buffering, but double-buffering is better and requires you to somehow render the entire area between each swap.
Your problem is, that you do clear the screen in your initialization code. But you need to clear it every frame, so right at the start of your display (or in your case idle) function.
I don't use GLUT but a really simple way to display something like this is:
while( !done ) { /* Loop until done. Do drawing. */
glClear( GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
{
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f(-1.0f, -1.0f);
glVertex2f(1.0f, -1.0f);
}
glEnd();
glFlush();
SwapBuffers( );
etc... event handling....
}
Run this code and probably you will get the solution.
#include<GL/gl.h>
#include<GL/glut.h>
#include<stdio.h>
double x_0 = -100;
double y_0 = -25;
double x_1 = 100;
double y_1 = -25;
double x_2 = 100;
double y_2 = 25;
double x_3 = -100;
double y_3 = 25;
void
init(void)
{
/*initialize the x-y co-ordinate*/
glClearColor(0,0,0,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-320, 319,-240, 239);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void
drawRectangle()
{
glBegin(GL_LINES);
glVertex2d(x_0, y_0);
glVertex2d(x_1, y_1);
glVertex2d(x_1, y_1);
glVertex2d(x_2, y_2);
glVertex2d(x_2, y_2);
glVertex2d(x_3, y_3);
glVertex2d(x_3, y_3);
glVertex2d(x_0, y_0);
glEnd();
glFlush();
}
int
main(int argc, char *argv[])
{
double x_0, y_0, x_1, y_1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(400, 400);
glutCreateWindow("Clear Screen");
init();
drawRectangle();
/* clear the screen. You can uncomment following three lines to view the effect of clearing */
// glClearColor(0, 0, 0, 0);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// /* don't forget to flush */
// glFlush();
/***/
glutMainLoop();
}
Compile and run -
gcc file.c -lglut -lGLU -lGL
./a.out