Just 4 fun, I start learning C/C++ and OpenGL and I wanted to share my 1st small test as some sort of free tutorial for C/C++ OpenGL ... (I'm a true beginner in both C/C++ and OpenGL)
/* OpenGL Sample #1
SStar scrolling with 4 parallaxs
*/
/* WHAT WE WANT TO DISPLAY ON SCREEN MUST BE ADDED IN THIS FUNCTION */
void My_glRendering( void )
{
int i;
glClearColor( 0.0, 0.0, 0.0, 0.0); /* Set backdrop as black */
glClear( GL_COLOR_BUFFER_BIT ); /* Clear the backdrop with glClearColor color */
glColor3f( 1.0, 1.0, 1.0 );
for( i = 0; i < 257 ; i++ ){
PosXY[i][1] -= 0.0001f ;
if ( i < 64 )
PosXY[i][1] -= 0.0001f ;
if ( i < 128 )
PosXY[i][1] -= 0.0001f ;
if ( i < 192 )
PosXY[i][1] -= 0.0001f ;
if ( PosXY[i][1] <=0.0 )
PosXY[i][1] = 1.0;
glBegin(GL_POINTS) ;
glVertex3f( PosXY[i][1], PosXY[i][2], 0.0f );
glEnd() ;
}
glFlush();
}
/* MAIN C PROCEDURE STARTUP-SEQUENCE IS HERE */
int main(int argc, char** argv)
{
int i;
for( i = 1; i < 257 ; i++ ){
PosXY[i][1] = rand() % 100000 / 100000.0 ;
PosXY[i][2] = rand() % 100000 / 100000.0 ;
}
glutInit(&argc, argv); /* Initialize Glut */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); /* Define display mode properties such as single buffer, color mode and */
glutInitWindowSize( 640, 480 ); /* define the sizes of the window to create */
glutInitWindowPosition( 300, 300 );
glutCreateWindow("AmiDARK Test Window"); /* Create the final rendering window */
/* WHAT WE WANT TO DISPLAY ON SCREEN MUST BE ADDED IN THIS FUNCTION */
void My_glRendering( void )
{
int i, multiplier;
glClearColor( 0.0, 0.0, 0.0, 0.0); /* Set backdrop as black */
glClear( GL_COLOR_BUFFER_BIT ); /* Clear the backdrop with glClearColor color */
glColor3f( 1.0, 1.0, 1.0 );
for( i = 0; i < 257 ; i++ ){
multiplier = i / 4.0;
PosXY[i][1] -= ( 0.00001f * multiplier ) ;
if ( PosXY[i][1] < 0.0 )
PosXY[i][1] = 1.0;
}
glBegin(GL_POINTS) ;
for( i = 00; i < 257 ; i++ ){
glVertex3f( PosXY[i][1], PosXY[i][2], 0.0f );
}
glEnd() ;
glFlush();
}
/* MAIN C PROCEDURE STARTUP-SEQUENCE IS HERE */
int main(int argc, char** argv)
{
int i;
for( i = 1; i < 257 ; i++ ){
PosXY[i][1] = rand() % 100000 / 100000.0 ;
PosXY[i][2] = rand() % 100000 / 100000.0 ;
}
glutInit(&argc, argv); /* Initialize Glut */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); /* Define display mode properties such as single buffer, color mode and */
glutInitWindowSize( 640, 480 ); /* define the sizes of the window to create */
glutInitWindowPosition( 300, 300 );
glutCreateWindow("AmiDARK Test Window"); /* Create the final rendering window */
/* WHAT WE WANT TO DISPLAY ON SCREEN MUST BE ADDED IN THIS FUNCTION */
void My_glRendering( void )
{
int i;
glClearColor( 0.0, 0.0, 0.0, 0.0); /* Set backdrop as black */
glClear( GL_COLOR_BUFFER_BIT ); /* Clear the backdrop with glClearColor color */
glColor3f( 1.0, 1.0, 1.0 );
/* MAIN C PROCEDURE STARTUP-SEQUENCE IS HERE */
int main(int argc, char** argv)
{
int i;
for( i = 1; i < 256 ; i++ ){
PosXY[i][1] = rand() % 100000 / 100000.0 ;
PosXY[i][2] = rand() % 100000 / 100000.0 ;
}
glutInit(&argc, argv); /* Initialize Glut */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); /* Define display mode properties such as single buffer, color mode and */
glutInitWindowSize( 640, 480 ); /* define the sizes of the window to create */
glutInitWindowPosition( 300, 300 );
glutCreateWindow("AmiDARK Test Window"); /* Create the final rendering window */
glutPostRedisplay tells glut to start rendering. glFlush empties the OpenGL command queue.
Idle function is always being called by GLUT while the rendering function is actually only called when something happens to the window eg. it is moved. I am not sure this is true for the amiga port of GLUT though.
Anyway because the rendering function is rarely called you should use the idle function to update your geometry and other stuff, then when that is done you use glutPostRedisplay to tell GLUT that now would be a good time to do some rendering.
I've understood but, I noticed something, if I don't define a function for glutIdleFunc(). Nothing is updated on screen until I move or resize the window.
Strange... Issue ?
All we have to decide is what to do with the time that is given to us.
@Shadow: Do you think it should be the best to ask flush() to force emptying the queue and during this time, make other calculations that are not related to graphics ? and then use glutPostRedisplay() to update the display when everything is done ?
All we have to decide is what to do with the time that is given to us.
I've understood but, I noticed something, if I don't define a function for glutIdleFunc(). Nothing is updated on screen until I move or resize the window.
Strange... Issue ?
That's what it's supposed to do, although there was a bug that resulted in a newly opened window remaining gray until the window was moved/resized. I fixed that a few days ago.
Have a look at my frame-rate independent animation template to see how to do animation (if you're not animating, you don't need to update the display).
I think I've understood the principle of refreshing the display now. I'll take a look at animations ...
As I'm beginner on C/C++, I didn't found how to convert an integer into a string, because I'd like to display debug informations during my dev tests such as frame rate, etc ... Do you have any info ?
All we have to decide is what to do with the time that is given to us.
freddix wrote: @Shadow: Do you think it should be the best to ask flush() to force emptying the queue and during this time, make other calculations that are not related to graphics ? and then use glutPostRedisplay() to update the display when everything is done ?
GlFlush() causes your program to wait until the graphics card/driver has finished processing all the commands that you just gave it. It's usually not needed. You would use it only if you want to read back the image that you've just drawn in order to use it for something (e.g., as a reflection map).
GlutPostRedisplay() tells GLUT to call your render function. It does not actually update the screen. This is usually called from the idle/timer function. Basically, perform all calculations to update the position of objects and then call glutPostRedisplay() in order to render them at their new locations.
Normally glutSwapBuffers() is put at the end of the render function. If a screen is double-buffered, this will update the screen to display the new image. If double-buffering isn't enabled, glutSwapBuffers() still doesn't hurt.
I think I've understood the principle of refreshing the display now. I'll take a look at animations ...
As I'm beginner on C/C++, I didn't found how to convert an integer into a string, because I'd like to display debug informations during my dev tests such as frame rate, etc ... Do you have any info ?
You could use snprintf. If you're using C++, you could also have a look at the sstream and string classes. Snprintf() is probably easier to get started with, but using sstream is less fiddly.
Shadow's example converts an int into a C string. I second Hans' advice and use stringstreams instead if you're in C++. There is a brief description of stringstreams on CppReference.com.
Also, if you do use C, snprintf instead of sprintf because sprintf allows buffer overruns (writing past the end of allocated memory) while snprintf keeps track of the length of the buffer it is writing to.
GlFlush() causes your program to wait until the graphics card/driver has finished processing all the commands that you just gave it. It's usually not needed. You would use it only if you want to read back the image that you've just drawn in order to use it for something (e.g., as a reflection map).
Can we render the 3D in something else than a window ? (a texture for example, this could be better for future shader use)
@Samurai_Crow: Thank you for this link, now I understand how the function work. It work now how I expected.
All we have to decide is what to do with the time that is given to us.