• Advertisement

AtomicOrbital

Member
  • Content count

    1
  • Joined

  • Last visited

Community Reputation

128 Neutral

About AtomicOrbital

  • Rank
    Newbie
  1. OpenGL Moving a single object around in 2D

    Here is a basic bare bones multiple triangle animation using modern OpenGL 3.x with inline vertex and fragment shaders. compile it using :     g++ -o 005_tri_mo_mu_f8_ver3_simple 005_tri_mo_mu_f8_ver3_simple.cpp  -lGL -lGLEW -lglut -lGLU   // g++ -o opengl_tri_multi_move opengl_tri_multi_move.cpp -lGL -lGLU -lGLEW -lglut // optirun ./opengl_tri_multi_move #include <GL/glew.h> #include <GL/freeglut.h> #include <vector> #include <iostream> #include <string.h> // strlen #include <cstdio> // printf, sprintf in cpp c++ // --------- #include <iomanip> // std::setprecision //#include <locale> // to insert commas into large numbers #include <sstream> #define WINDOW_TITLE_PREFIX "move multiple triangles" int CurrentWidth = 1100, CurrentHeight = 1000, WindowHandle = 0; unsigned FrameCount = 0; #define YES 1 #define NO 0 //#define DEBUG YES #define DEBUG NO int did_load_program = NO; int x1_reached_edge = NO; int y1_reached_edge = NO; GLfloat x_max = 0.9, y_max = 0.9; GLfloat x_min = -0.9, y_min = -0.9; GLfloat min_incr = -0.3, max_incr = 0.3; // GLfloat size_triangle_side = 0.007; GLfloat size_triangle_side = 0.2; struct struct_program { static GLuint Load( const char * vert, const char * geom, const char * frag ) { GLuint prog = glCreateProgram(); if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert ); if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom ); if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag ); glLinkProgram( prog ); CheckStatus( prog ); return prog; } private: static void CheckStatus( GLuint obj ) { GLint status = GL_FALSE, len = 10; if( glIsShader(obj) ) glGetShaderiv ( obj, GL_COMPILE_STATUS, & status ); if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, & status ); if( status == GL_TRUE ) return; if( glIsShader(obj) ) glGetShaderiv ( obj, GL_INFO_LOG_LENGTH, & len ); if( glIsProgram(obj) ) glGetProgramiv( obj, GL_INFO_LOG_LENGTH, & len ); std::vector< char > log( len, 'X' ); if( glIsShader(obj) ) glGetShaderInfoLog ( obj, len, NULL, &log[0] ); if( glIsProgram(obj) ) glGetProgramInfoLog( obj, len, NULL, &log[0] ); std::cerr << & log[0] << std::endl; exit( -1 ); } static void AttachShader( GLuint program, GLenum type, const char * src ) { GLuint shader = glCreateShader( type ); glShaderSource( shader, 1, & src, NULL ); glCompileShader( shader ); CheckStatus( shader ); glAttachShader( program, shader ); glDeleteShader( shader ); } }; #define GLSL(version, shader) "#version " #version "\n" #shader const char* vert = GLSL ( 400 core, layout( location = 0 ) in vec4 vPosition; void main() { gl_Position = vPosition; } ); const char* frag = GLSL ( 400 core, out vec4 fColor; void main() { fColor = vec4( 0.0, 0.0, 1.0, 1.0 ); } ); //#define total_num_triangles 1500 //#define total_num_triangles 3 //#define total_num_triangles 10000000 // #define total_num_triangles 100000 #define total_num_triangles 10 #define index_ArrayBuffer 0 #define NumBuffers 1 //num_vertex_arrays GLuint vPosition = 0; //GLuint VAOs[total_num_triangles]; GLuint vertex_array_object; GLuint Buffers[NumBuffers]; const GLuint NumVertices = 3; #define X 0 #define Y 1 //GLfloat tri_location[total_num_triangles][2]; GLfloat vertex_locations[ 3 * total_num_triangles][2]; // 3 vertex per triangle, X&Y per vertex //GLfloat incr[total_num_triangles][2]; GLfloat triangle_incr[total_num_triangles][2]; // ------------------------ bool get_direction(GLfloat curr_location, GLfloat min_location, GLfloat max_location) { bool answer = false; if (curr_location < min_location || curr_location > max_location) { answer = true; } return answer; } void setup_opengl() { glGenVertexArrays(NumBuffers, & vertex_array_object); glBindVertexArray(vertex_array_object); glGenBuffers(NumBuffers, Buffers); glBindBuffer(GL_ARRAY_BUFFER, Buffers[index_ArrayBuffer]); // ---------- glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) ); glEnableVertexAttribArray(vPosition); glBindVertexArray(vertex_array_object); } void display(void) { ++FrameCount; glClear(GL_COLOR_BUFFER_BIT); // glGenVertexArrays(total_num_triangles, & vertex_array_object); // glGenVertexArrays(NumBuffers, & vertex_array_object); // std::cout << "----- top of display ------ " << std::endl; // ---------------- int curr_vertex = 0; int curr_triangle = 0; for (; curr_triangle < total_num_triangles; curr_triangle++) { if (get_direction(vertex_locations[curr_vertex ][X], x_min, x_max) || get_direction(vertex_locations[curr_vertex + 1][X], x_min, x_max) || get_direction(vertex_locations[curr_vertex + 2][X], x_min, x_max)) { triangle_incr[curr_triangle][X] *= -1.0; } if (get_direction(vertex_locations[curr_vertex ][Y], y_min, y_max) || get_direction(vertex_locations[curr_vertex + 1][Y], y_min, y_max) || get_direction(vertex_locations[curr_vertex + 2][Y], y_min, y_max)) { triangle_incr[curr_triangle][Y] *= -1.0; } // triangle vertex 1 vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X]; vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y]; if (YES == DEBUG) { std::cout << "tri " << curr_triangle; std::cout << " X " << vertex_locations[curr_vertex][X] << " Y " << vertex_locations[curr_vertex][Y]; } curr_vertex++; // triangle vertex 2 vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X]; vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y]; if (YES == DEBUG) { std::cout << " X " << vertex_locations[curr_vertex][X] << " Y " << vertex_locations[curr_vertex][Y]; } curr_vertex++; // triangle vertex 3 vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X]; vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y]; if (YES == DEBUG) { std::cout << " X " << vertex_locations[curr_vertex][X] << " Y " << vertex_locations[curr_vertex][Y] << std::endl; } curr_vertex++; } // ---------- glBindVertexArray(vertex_array_object); // glGenBuffers(NumBuffers, Buffers); // glBindBuffer(GL_ARRAY_BUFFER, Buffers[index_ArrayBuffer]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_locations), vertex_locations, GL_STATIC_DRAW); // glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_locations), vertex_locations, GL_DYNAMIC_DRAW); // // glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) ); // glEnableVertexAttribArray(vPosition); // glBindVertexArray(vertex_array_object); glDrawArrays(GL_TRIANGLES, 0, 3 * total_num_triangles); // glDrawArrays(GL_TRIANGLES, 0, total_num_triangles); // ---------- glutSwapBuffers(); } // --------------- void process_SHIFT_ALT_CTRL(unsigned char key, int x, int y) { switch(key) { case 27: { // printf ("just hit ESC key\n"); exit(8); } } } // -------------- const char * insert_commas_into_int(int given_integer) { std::ostringstream stm ; stm << given_integer; std::string str_num(stm.str()); int size_str = str_num.size() ; // std::cout << " num digits in " << given_integer << " is " << size_str << std::endl; for( int i = size_str ; i > 0 ; i -= 3 ) { if (i != size_str) str_num.insert( i, 1, ',' ) ; } // std::cout << str_num << '\n' ; return str_num.c_str(); } // -------------- void TimerFunction(int Value) { if (0 != Value) { char* TempString = (char*) malloc(512 + strlen(WINDOW_TITLE_PREFIX)); sprintf( TempString, "%s: %s triangles doing %d Frames Per Second @ %d x %d", WINDOW_TITLE_PREFIX, insert_commas_into_int(total_num_triangles), FrameCount * 4, CurrentWidth, CurrentHeight ); glutSetWindowTitle(TempString); free(TempString); } FrameCount = 0; glutTimerFunc(250, TimerFunction, 1); } GLfloat get_random_in_range(GLfloat minimum, GLfloat maximum) { return(minimum + (float)rand()/((float)RAND_MAX/(maximum - minimum))); } void IdleFunction(void) { glutPostRedisplay(); } static void define_callbacks() { glutDisplayFunc(display); glutKeyboardFunc( process_SHIFT_ALT_CTRL ); glutIdleFunc(IdleFunction); glutTimerFunc(0, TimerFunction, 0); } int main(int argc, char** argv) { // initialize random seed srand ( time(NULL) ); glutInit(&argc, argv); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE ); glutInitWindowSize(CurrentWidth, CurrentHeight); glutInitContextVersion(4, 0); glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow(argv[0]); glewExperimental = GL_TRUE; if( GLEW_OK != glewInit() ) exit(EXIT_FAILURE); int curr_vertex = 0; int curr_triangle = 0; for (; curr_triangle < total_num_triangles; curr_triangle++) { triangle_incr[curr_triangle][X] = get_random_in_range(min_incr, max_incr) / 50.0; triangle_incr[curr_triangle][Y] = get_random_in_range(min_incr, max_incr) / 50.0; if (YES == DEBUG) { std::cout << " triangle_incr X " << triangle_incr[curr_triangle][X] << " triangle_incr Y " << triangle_incr[curr_triangle][Y] << std::endl; } GLfloat x_curr = get_random_in_range(min_incr, max_incr); GLfloat y_curr = get_random_in_range(min_incr, max_incr); // triangle vertex 1 vertex_locations[curr_vertex][X] = x_curr; vertex_locations[curr_vertex][Y] = y_curr; if (YES == DEBUG) { std::cout << "tri " << curr_triangle << std::endl; std::cout << " vertex 1 X " << vertex_locations[curr_vertex][X] << " Y " << vertex_locations[curr_vertex][Y] << std::endl; } // triangle vertex 2 vertex_locations[curr_vertex + 1][X] = x_curr; vertex_locations[curr_vertex + 1][Y] = y_curr - size_triangle_side; if (YES == DEBUG) { std::cout << " vertex 2 X " << vertex_locations[curr_vertex + 1][X] << " Y " << vertex_locations[curr_vertex + 1][Y] << std::endl; } // triangle vertex 3 vertex_locations[curr_vertex + 2][X] = x_curr - size_triangle_side; vertex_locations[curr_vertex + 2][Y] = y_curr - size_triangle_side; if (YES == DEBUG) { std::cout << " vertex 3 X " << vertex_locations[curr_vertex + 2][X] << " Y " << vertex_locations[curr_vertex + 2][Y] << std::endl; } curr_vertex += 3; // 3 vertex per triangle } // ----------- GLuint program = struct_program::Load( vert, NULL, frag ); glUseProgram(program); // ----------- setup_opengl(); define_callbacks(); glutMainLoop(); }
  • Advertisement