/*------------------------------------- Render Context initialization -------------------------------------*/ bool Context::init(const Display& disp, bool useVsync) { terminate(); if (disp.is_running() == false) { LS_LOG_ERR("\tAttempted to initialize a render context with no display.\n"); return false; } // Attach the OpenGL context to our window handle LS_LOG_MSG("Initializing an OpenGL rendering context."); pContext = SDL_GL_CreateContext(disp.get_window()); if (!pContext) { LS_LOG_ERR( "\tUnable to create a render context through SDL.", "\n\t", SDL_GetError(), '\n' ); terminate(); return false; } LS_LOG_MSG("\tSuccessfully created a basic render context."); // Quick setup in order to normalize OpenGL to the display coordinates. this->make_current(disp); const math::vec2i&& displayRes = disp.get_resolution(); glViewport(0, 0, displayRes[0], displayRes[1]); LS_LOG_GL_ERR(); // Set the default back buffer color const ls::draw::color::color& mgcPnk = ls::draw::color::magenta; glClearColor(mgcPnk[0], mgcPnk[1], mgcPnk[2], mgcPnk[3]); LS_LOG_GL_ERR(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); LS_LOG_GL_ERR(); set_vsync(useVsync); LS_LOG_MSG( "\tSuccessfully initialized a OpenGL 3.3-compatible render context:" "\n\tV-Sync: ", get_vsync() ); LS_LOG_MSG("\tSuccessfully initialized the OpenGL 3.3 render context.\n"); return true; }
void create_graphics_context(void* window) { // Create context gl_context = SDL_GL_CreateContext((SDL_Window*) window); if (gl_context) { DEBUG(0, NE_MESSAGE, "Created OpenGL context " << gl_context); } else { DEBUG(0, NE_ERROR, "Failed to create an OpenGL context. Error: " << SDL_GetError()); return; } // Output OpenGL info DEBUG(0, NE_INFO, "<b>-- OpenGL --<br>Version:</b> " << NE_GL_VERSION << "<br><b>Vendor:</b> " << NE_GL_VENDOR << "<br><b>Renderer:</b> " << NE_GL_RENDERER << "<br><b>Shading Language Version:</b> " << NE_GL_SHADING_LANGUAGE_VERSION); // Initialize GLEW GLenum error = glewInit(); Assert(error == GLEW_OK); if (error != GLEW_OK) { DEBUG(0, NE_ERROR, "GLEW failed to initialise."); return; } glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glShadeModel(GL_SMOOTH); CHECK_GL_ERROR(); glEnable(GL_DEPTH_TEST); CHECK_GL_ERROR(); glDepthFunc(GL_LEQUAL); CHECK_GL_ERROR(); glEnable(GL_BLEND); CHECK_GL_ERROR(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // https://www.opengl.org/sdk/docs/man/html/glBlendFunc.xhtml CHECK_GL_ERROR(); set_vsync(true); }
NE_API void toggle_vsync() { set_vsync(!vsync_state); }
int main(int argc, char *argv[]) { signal(SIGHUP,sighup); signal(SIGINT,sigint); const int screen_x = 1260, screen_y = 1000; int running = 1, ticks_prev, ticks_curr; float delta, cam_th = 0.0f, cam_x, cam_z, planet_th = 0.0f, sat_th = 0.0f; float lt1_diffuse[] = { 1.0f, 0.0f, 0.0f, 1.0f }; float lt2_diffuse[] = { 0.0f, 1.0f, 0.0f, 1.0f }; float green_diffuse[] = { 0.0f, 1.0f, 0.0f, 1.0f }; float red_diffuse[] = { 1.0f, 0.0f, 0.0f, 1.0f }; float ballColor[] = { 1.0f, 0.0f, 0.0f, 1.0f }; float lt_origin[] = { 0.0f, 0.0f, 0.0f, 1.0f }; float myRed,myGreen; myRed = myGreen = 0.0f; SDL_Surface *surface; SDL_Event event; GLUquadric *quadric; float mySpeed = 3; // initialize SDL if (0 > SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) bail("failed to initialize SDL"); surface = SDL_SetVideoMode(screen_x, screen_y, 32, SDL_OPENGL); if (!surface) bail("failed to set video mode"); set_vsync(1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_WM_SetCaption("Avatar GUI Test", 0); ticks_prev = SDL_GetTicks(); // initialize GL glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glEnable(GL_LIGHT3); glEnable(GL_LIGHT4); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDepthFunc(GL_LESS); glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 1); glClearDepth(1); glViewport(0, 0, screen_x, screen_y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, (float)screen_x / screen_y, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); quadric = gluNewQuadric(); gluQuadricNormals(quadric, GLU_SMOOTH); gluQuadricTexture(quadric, GL_FALSE); // render loop // enum state { idle, thinking }; // enum state next_state = idle; // enum state current_state = idle; myRed = 0.0f; myGreen = 1.0f; ballColor[0] = myRed; ballColor[1] = myGreen; while (running) { while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: if (SDLK_ESCAPE == event.key.keysym.sym) running = 0; if (SDLK_F1 == event.key.keysym.sym){ next_state=idle; } if (SDLK_F2 == event.key.keysym.sym){ next_state= thinking; } if (SDLK_F3 == event.key.keysym.sym){ mySpeed--; } if (SDLK_F4 == event.key.keysym.sym){ mySpeed++; } break; case SDL_QUIT: running = 0; break; } } // calculate the time delta between this frame and the previous ticks_curr = SDL_GetTicks(); delta = (ticks_curr - ticks_prev) / 1000.0f; ticks_prev = ticks_curr; //Transition from one state to another if(next_state != current_state){ if(current_state == idle){ myRed += 1.0f*delta; //printf("myRed = %f , delta= %f, mySpeed= %f\n", myRed, delta, mySpeed); myGreen -= 1.0f*delta; if(myGreen <= 0.0f){ current_state = next_state; } mySpeed += 1.5f*delta; } if(current_state == thinking){ myRed -= 1.0f*delta; myGreen += 1.0f*delta; if(myRed <= 0.0f){ current_state = next_state; } mySpeed -= 1.5f*delta; } //Update colors accordingly ballColor[0] = myRed; ballColor[1] = myGreen; } //cam_th += delta * 0.1f; sat_th += mySpeed * delta * (180.0f / M_PI); planet_th += delta * (180.0f / M_PI); cam_x = 0.1f * cos(cam_th); cam_z = 0.1f * sin(cam_th); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(cam_x, 10, cam_z, 0, 0, 0, 0, 1, 0); /* // render the basis vectors glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3f(0, 0, 0); glVertex3f(2, 0, 0); glColor3f(0, 1, 0); glVertex3f(0, 0, 0); glVertex3f(0, 2, 0); glColor3f(0, 0, 1); glVertex3f(0, 0, 0); glVertex3f(0, 0, 2); glEnd(); */ // set the position to the planet's center //glRotatef(planet_th, 0, 1, 0); //glTranslatef(5, 3 * cos(planet_th * 0.03f), 0); // render the first satellite glPushMatrix(); glRotatef(sat_th, 0, 1, 1); glTranslatef(2, 0, 0); glLightfv(GL_LIGHT1, GL_DIFFUSE, ballColor); glLightfv(GL_LIGHT1, GL_POSITION, lt_origin); glColor3f(myRed, myGreen, 0); gluSphere(quadric, 0.2f, 64, 64); glPopMatrix(); // render the second satellite glPushMatrix(); glRotatef(sat_th, 0, -1, 1); glTranslatef(2, 0, 0); glLightfv(GL_LIGHT2, GL_DIFFUSE, ballColor); glLightfv(GL_LIGHT2, GL_POSITION, lt_origin); glColor3f(myRed, myGreen, 0); gluSphere(quadric, 0.2f, 64, 64); glPopMatrix(); // render the third satellite glPushMatrix(); glRotatef(sat_th, 0.5, -0.5, 0.5); glTranslatef(0, 2, 0); glLightfv(GL_LIGHT3, GL_DIFFUSE, ballColor); glLightfv(GL_LIGHT3, GL_POSITION, lt_origin); glColor3f(myRed, myGreen, 0); gluSphere(quadric, 0.2f, 64, 64); glPopMatrix(); // render the fourth satellite glPushMatrix(); glRotatef(sat_th, 2, -0.5, 0.5); glTranslatef(0, 2, 0); glLightfv(GL_LIGHT4, GL_DIFFUSE, ballColor); glLightfv(GL_LIGHT4, GL_POSITION, lt_origin); glColor3f(myRed, myGreen, 0); gluSphere(quadric, 0.2f, 64, 64); glPopMatrix(); // render the planet around which the satellites rotate glEnable(GL_LIGHTING); glColor3f(0.3, 0.3, 0.3); gluSphere(quadric, 1, 64, 64); glDisable(GL_LIGHTING); glRasterPos2i(100, 120); glColor4f(0.0f, 0.0f, 1.0f, 1.0f); //glutBitmapString(GLUT_BITMAP_9_BY_15, "text to render"); SDL_GL_SwapBuffers(); } return 0; }
void crtc_ega_device::handle_line_timer() { int new_vsync = m_vsync; m_character_counter = 0; m_cursor_x = -1; /* Check if VSYNC is active */ if ( m_vsync_ff ) { m_vsync_width_counter = ( m_vsync_width_counter + 1 ) & 0x0F; /* Check if we've reached end of VSYNC */ if ( m_vsync_width_counter == m_vert_retr_end ) { m_vsync_ff = 0; new_vsync = FALSE; } } if ( m_raster_counter == m_max_ras_addr ) { m_raster_counter = 0; m_line_address = ( m_line_address + m_horiz_disp + 1 ) & 0xffff; } else { m_raster_counter = ( m_raster_counter + 1 ) & 0x1F; } m_line_counter = ( m_line_counter + 1 ) & 0x3ff; /* Check if we've reached the end of active display */ if ( m_line_counter == m_vert_disp_end ) { m_line_enable_ff = false; } /* Check if VSYNC should be enabled */ if ( m_line_counter == m_vert_retr_start ) { m_vsync_width_counter = 0; m_vsync_ff = 1; new_vsync = TRUE; } /* Check if we have reached the end of the vertical area */ if ( m_line_counter == m_vert_total ) { m_line_counter = 0; m_line_address = m_disp_start_addr; m_line_enable_ff = true; set_vblank( FALSE ); /* also update the cursor state now */ update_cursor_state(); if (m_screen != NULL) m_screen->reset_origin(); } if ( m_line_enable_ff ) { /* Schedule DE off signal change */ m_de_off_timer->adjust(attotime::from_ticks( m_horiz_disp + 1, m_clock )); /* Is cursor visible on this line? */ if ( m_cursor_state && (m_raster_counter >= (m_cursor_start_ras & 0x1f)) && (m_raster_counter <= m_cursor_end_ras) && (m_cursor_addr >= m_line_address) && (m_cursor_addr < (m_line_address + m_horiz_disp + 1)) ) { m_cursor_x = m_cursor_addr - m_line_address; /* Schedule CURSOR ON signal */ m_cur_on_timer->adjust( attotime::from_ticks( m_cursor_x, m_clock ) ); } } /* Schedule HSYNC on signal */ m_hsync_on_timer->adjust( attotime::from_ticks( m_horiz_blank_start, m_clock ) ); /* Set VBlank signal */ if ( m_line_counter == m_vert_disp_end + 1 ) { set_vblank( TRUE ); } /* Schedule our next callback */ m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 2, m_clock ) ); /* Set VSYNC and DE signals */ set_vsync( new_vsync ); set_de( m_line_enable_ff ? TRUE : FALSE ); }
void mc6845_device::handle_line_timer() { int new_vsync = m_vsync; m_character_counter = 0; m_cursor_x = -1; /* Check if VSYNC is active */ if ( m_vsync_ff ) { UINT8 vsync_width = m_supports_vert_sync_width ? (m_sync_width >> 4) & 0x0f : 0; m_vsync_width_counter = ( m_vsync_width_counter + 1 ) & 0x0F; /* Check if we've reached end of VSYNC */ if ( m_vsync_width_counter == vsync_width ) { m_vsync_ff = 0; new_vsync = FALSE; } } // For rudimentary 'interlace and video' support, m_raster_counter increments by 1 rather than the correct 2. // The correct test would be: // if ( m_raster_counter == (MODE_INTERLACE_AND_VIDEO ? m_max_ras_addr + 1 : m_max_ras_addr) ) if ( m_raster_counter == m_max_ras_addr ) { /* Check if we have reached the end of the vertical area */ if ( m_line_counter == m_vert_char_total ) { m_adjust_counter = 0; m_adjust_active = 1; } m_raster_counter = 0; m_line_counter = ( m_line_counter + 1 ) & 0x7F; m_line_address = ( m_line_address + m_horiz_disp ) & 0x3fff; /* Check if we've reached the end of active display */ if ( m_line_counter == m_vert_disp ) { m_line_enable_ff = false; m_current_disp_addr = m_disp_start_addr; } /* Check if VSYNC should be enabled */ if ( m_line_counter == m_vert_sync_pos ) { m_vsync_width_counter = 0; m_vsync_ff = 1; new_vsync = TRUE; } } else { // For rudimentary 'interlace and video' support, m_raster_counter increments by 1 rather than the correct 2. // m_raster_counter = ( m_raster_counter + (MODE_INTERLACE_AND_VIDEO ? 2 : 1) ) & 0x1F; m_raster_counter = ( m_raster_counter + 1 ) & 0x1F; } if ( m_adjust_active ) { /* Check if we have reached the end of a full cycle */ if ( m_adjust_counter == m_vert_total_adj ) { m_adjust_active = 0; m_raster_counter = 0; m_line_counter = 0; m_line_address = m_disp_start_addr; m_line_enable_ff = true; /* also update the cursor state now */ update_cursor_state(); if (m_screen != NULL) m_screen->reset_origin(); } else { m_adjust_counter = ( m_adjust_counter + 1 ) & 0x1F; } } if ( m_line_enable_ff ) { /* Schedule DE off signal change */ m_de_off_timer->adjust(attotime::from_ticks( m_horiz_disp, m_clock )); /* Is cursor visible on this line? */ if ( m_cursor_state && (m_raster_counter >= (m_cursor_start_ras & 0x1f)) && (m_raster_counter <= m_cursor_end_ras) && (m_cursor_addr >= m_line_address) && (m_cursor_addr < (m_line_address + m_horiz_disp)) ) { m_cursor_x = m_cursor_addr - m_line_address; /* Schedule CURSOR ON signal */ m_cur_on_timer->adjust( attotime::from_ticks( m_cursor_x, m_clock ) ); } } /* Schedule HSYNC on signal */ m_hsync_on_timer->adjust( attotime::from_ticks( m_horiz_sync_pos, m_clock ) ); /* Schedule our next callback */ m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 1, m_clock ) ); /* Set VSYNC and DE signals */ set_vsync( new_vsync ); set_de( m_line_enable_ff ? TRUE : FALSE ); }