Ejemplo n.º 1
0
static double update_video_nocorrect_pts(struct MPContext *mpctx)
{
    struct sh_video *sh_video = mpctx->sh_video;
    double frame_time = 0;
    while (1) {
        // In nocorrect-pts mode there is no way to properly time these frames
        if (load_next_vo_frame(mpctx, false))
            break;
        frame_time = sh_video->next_frame_time;
        if (mpctx->restart_playback)
            frame_time = 0;
        struct demux_packet *pkt = video_read_frame(mpctx);
        if (!pkt)
            return -1;
        if (mpctx->sh_audio)
            mpctx->delay -= frame_time;
        // video_read_frame can change fps (e.g. for ASF video)
        update_fps(mpctx);
        int framedrop_type = check_framedrop(mpctx, frame_time);

        void *decoded_frame = decode_video(sh_video, pkt, framedrop_type,
                                           sh_video->pts);
        talloc_free(pkt);
        if (decoded_frame) {
            filter_video(mpctx, decoded_frame);
        }
        break;
    }
    return frame_time;
}
Ejemplo n.º 2
0
int osd_update(mame_time emutime)
{
	win_window_info *window;

	// if we're throttling, paused, or if the UI is up, synchronize
	if (effective_throttle())
		update_throttle(emutime);

	// update the FPS computations
	update_fps(emutime);

	// update all the windows, but only if we're not skipping this frame
	if (!skiptable[effective_frameskip()][frameskip_counter])
	{
		profiler_mark(PROFILER_BLIT);
		for (window = win_window_list; window != NULL; window = window->next)
			winwindow_video_window_update(window);
		profiler_mark(PROFILER_END);
	}

	// if we're throttling and autoframeskip is on, adjust
	if (effective_throttle() && effective_autoframeskip() && frameskip_counter == 0)
		update_autoframeskip();

	// poll the joystick values here
	winwindow_process_events(TRUE);
	wininput_poll();
	check_osd_inputs();

	// increment the frameskip counter
	frameskip_counter = (frameskip_counter + 1) % FRAMESKIP_LEVELS;

	// return whether or not to skip the next frame
	return skiptable[effective_frameskip()][frameskip_counter];
}
static void run_game()
{
	game_data game;

	initialize_game(&game, wsi::milliseconds());

	running = true;

	for (;;)
	{
		wsi::update(&screen);

		bool rendering = wsi::should_render();

		int64_t millisecond_clock_now = wsi::milliseconds();

		unsigned ticks_elapsed = 0;
		float fractional_ticks = 0;
		calc_game_elapsed_time(&game, &ticks_elapsed, &fractional_ticks, millisecond_clock_now);

		game_command action = { 0 };
		process_inputs(&action);

		if (!running) break;

		update_game(&game, ticks_elapsed, &action, millisecond_clock_now);
		update_fps();

		if (action.toggle_pause)
		{
			pause_eviz_dx12(game.paused);
		}

		if (rendering)
		{
			float dpi = (float)screen.dpi.cx;
			float x_dips = screen.dimensions.cx * 96.0f / dpi;
			float y_dips = screen.dimensions.cy * 96.0f / dpi;
			set_swapchain_options_dx12(&wsi::screen_window, NULL, x_dips, y_dips, dpi, &swapchain_opts);
			rebuild_hud_string(&game);
			dx12_render_stats stats;
			render_game_dx12(hud_string, &game, fractional_ticks, screen.prefs.vsync, &stats);
			if (stats.latency) {
				const float alpha = 0.1f;
				frame_latency = (1-alpha)*frame_latency + alpha*stats.latency;
				frame_latency_stddev = stats.stddev_jitter;
				frame_latency_minmaxd = stats.minmax_jitter;
				current_frametime_cpu = (1 - alpha)*current_frametime_cpu + alpha*stats.cpu_frame_time;
				current_frametime_gpu = (1 - alpha)*current_frametime_gpu + alpha*stats.gpu_frame_time;
			}
		}

		//wsi::limit_fps(max_fps);
	}
}
Ejemplo n.º 4
0
void fps_break() {
	/* calculate how long that frame took and store time passed in globals */
	int current_ticks = SDL_GetTicks();
	int tick_wait = (current_ticks - fps_last_ticks) < fps_ticks_per_frame ? 
		(fps_ticks_per_frame - (current_ticks - fps_last_ticks)) : 0;
	/* block for 60fps*/
	SDL_Delay(tick_wait);
	/* store total frame ticks for FPS display */
	fps_current_frame_ticks = (current_ticks - fps_last_ticks) + tick_wait;
	fps_last_ticks = current_ticks;
	update_fps(NULL);
	return;
}
Ejemplo n.º 5
0
static void
frame_callback(void *data, struct wl_callback *callback, uint32_t time)
{
	struct gears *gears = data;

	update_fps(gears, time);

	gears->angle = (GLfloat) (time % 8192) * 360 / 8192.0;

	window_schedule_redraw(gears->window);

	if (callback)
		wl_callback_destroy(callback);
}
Ejemplo n.º 6
0
void render()
{
    glClearColor(0.0, 0.0, 0.1, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    glPolygonOffset(0.0, 0.0);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    do_render(false);

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glPolygonOffset(-1.0, -1.0);
    glLineWidth(2.0f);
    do_render(true);

    glutSwapBuffers();

    update_fps();
}
Ejemplo n.º 7
0
void c_RendererViewer::display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
    //glClearDepth(1.0f);
    glDepthFunc(GL_LEQUAL);

    glColor3f(1.0f, 0.f, 0.f);
    //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    //glShadeModel(GL_SMOOTH);

    draw("");

    glutSwapBuffers();
    update_fps();
    check_gl_errors();

    return;
}
Ejemplo n.º 8
0
static int motion_redraw(RASPITEX_STATE *raspitex_state) {

    // Start with a clear screen
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		RedrawGui();

		/*
    GLCHK(glUseProgram(motion_shader.program));
		GLCHK(glUniform1i(motion_shader.uniform_locations[0], 0));

    // Bind the OES texture which is used to render the camera preview
		glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, raspitex_state->texture);

		// Bind score texture
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, guiBuffer.id);

    GLCHK(glEnableVertexAttribArray(motion_shader.attribute_locations[0]));

    GLCHK(glVertexAttribPointer(motion_shader.attribute_locations[0], 2, GL_FLOAT, GL_FALSE, 0, varray));
    GLCHK(glDrawArrays(GL_TRIANGLES, 0, 6));

    GLCHK(glDisableVertexAttribArray(motion_shader.attribute_locations[0]));
		GLCHK(glBindTexture(GL_TEXTURE_2D, 0));
		glActiveTexture(GL_TEXTURE0);
    GLCHK(glUseProgram(0));
		*/
		motion_video1(raspitex_state);

		GLCHK(glEnable(GL_BLEND));
		GLCHK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
		RedrawTextures();
		GLCHK(glDisable(GL_BLEND));

		update_fps();

    return 0;
}
Ejemplo n.º 9
0
int main(int argc, char **argv) {
    srand(time(NULL));
    rand();
    if (!glfwInit()) {
        return -1;
    }
    #ifdef __APPLE__
        glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
        glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
        glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    #endif
    if (!glfwOpenWindow(800, 600, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {
        return -1;
    }
    glfwSwapInterval(VSYNC);
    glfwDisable(GLFW_MOUSE_CURSOR);
    glfwSetWindowTitle("Modern GL");
    glfwSetKeyCallback(on_key);
    glfwSetMouseButtonCallback(on_mouse_button);

    #ifndef __APPLE__
        if (glewInit() != GLEW_OK) {
            return -1;
        }
    #endif

    if (db_init()) {
        return -1;
    }

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LINE_SMOOTH);
    glLogicOp(GL_INVERT);
    glClearColor(0.53, 0.81, 0.92, 1.00);

    GLuint vertex_array;
    glGenVertexArrays(1, &vertex_array);
    glBindVertexArray(vertex_array);

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glfwLoadTexture2D("texture.tga", 0);

    GLuint block_program = load_program(
        "shaders/block_vertex.glsl", "shaders/block_fragment.glsl");
    GLuint matrix_loc = glGetUniformLocation(block_program, "matrix");
    GLuint camera_loc = glGetUniformLocation(block_program, "camera");
    GLuint sampler_loc = glGetUniformLocation(block_program, "sampler");
    GLuint timer_loc = glGetUniformLocation(block_program, "timer");
    GLuint position_loc = glGetAttribLocation(block_program, "position");
    GLuint normal_loc = glGetAttribLocation(block_program, "normal");
    GLuint uv_loc = glGetAttribLocation(block_program, "uv");

    GLuint line_program = load_program(
        "shaders/line_vertex.glsl", "shaders/line_fragment.glsl");
    GLuint line_matrix_loc = glGetUniformLocation(line_program, "matrix");
    GLuint line_position_loc = glGetAttribLocation(line_program, "position");

    Chunk chunks[MAX_CHUNKS];
    int chunk_count = 0;

    FPS fps = {0, 0};
    float matrix[16];
    float x = (rand_double() - 0.5) * 10000;
    float z = (rand_double() - 0.5) * 10000;
    float y = 0;
    float dy = 0;
    float rx = 0;
    float ry = 0;
    int px = 0;
    int py = 0;

    int loaded = db_load_state(&x, &y, &z, &rx, &ry);
    ensure_chunks(chunks, &chunk_count,
        floorf(roundf(x) / CHUNK_SIZE),
        floorf(roundf(z) / CHUNK_SIZE), 1);
    if (!loaded) {
        y = highest_block(chunks, chunk_count, x, z) + 2;
    }

    glfwGetMousePos(&px, &py);
    double previous = glfwGetTime();
    while (glfwGetWindowParam(GLFW_OPENED)) {
        update_fps(&fps, SHOW_FPS);
        double now = glfwGetTime();
        double dt = MIN(now - previous, 0.2);
        previous = now;

        if (exclusive) {
            int mx, my;
            glfwGetMousePos(&mx, &my);
            float m = 0.0025;
            rx += (mx - px) * m;
            ry -= (my - py) * m;
            if (rx < 0) {
                rx += RADIANS(360);
            }
            if (rx >= RADIANS(360)){
                rx -= RADIANS(360);
            }
            ry = MAX(ry, -RADIANS(90));
            ry = MIN(ry, RADIANS(90));
            px = mx;
            py = my;
        }
        else {
            glfwGetMousePos(&px, &py);
        }

        if (left_click) {
            left_click = 0;
            int hx, hy, hz;
            if (hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz))
            {
                if (hy > 0) {
                    set_block(chunks, chunk_count, hx, hy, hz, 0);
                }
            }
        }

        if (right_click) {
            right_click = 0;
            int hx, hy, hz;
            if (hit_test(chunks, chunk_count, 1, x, y, z, rx, ry,
                &hx, &hy, &hz))
            {
                if (!player_intersects_block(2, x, y, z, hx, hy, hz)) {
                    set_block(chunks, chunk_count, hx, hy, hz, block_type);
                }
            }
        }

        int sz = 0;
        int sx = 0;
        ortho = glfwGetKey(GLFW_KEY_LSHIFT);
        if (glfwGetKey('Q')) break;
        if (glfwGetKey('W')) sz--;
        if (glfwGetKey('S')) sz++;
        if (glfwGetKey('A')) sx--;
        if (glfwGetKey('D')) sx++;
        if (dy == 0 && glfwGetKey(GLFW_KEY_SPACE)) {
            dy = 8;
        }
        float vx, vy, vz;
        get_motion_vector(flying, sz, sx, rx, ry, &vx, &vy, &vz);
        float speed = flying ? 20 : 5;
        int step = 8;
        float ut = dt / step;
        vx = vx * ut * speed;
        vy = vy * ut * speed;
        vz = vz * ut * speed;
        for (int i = 0; i < step; i++) {
            if (flying) {
                dy = 0;
            }
            else {
                dy -= ut * 25;
                dy = MAX(dy, -250);
            }
            x += vx;
            y += vy + dy * ut;
            z += vz;
            if (collide(chunks, chunk_count, 2, &x, &y, &z)) {
                dy = 0;
            }
        }

        int p = floorf(roundf(x) / CHUNK_SIZE);
        int q = floorf(roundf(z) / CHUNK_SIZE);
        ensure_chunks(chunks, &chunk_count, p, q, 0);

        update_matrix_3d(matrix, x, y, z, rx, ry);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // render chunks
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, x, y, z);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            if (chunk_distance(chunk, p, q) > RENDER_CHUNK_RADIUS) {
                continue;
            }
            if (!chunk_visible(chunk, matrix)) {
                continue;
            }
            draw_chunk(chunk, position_loc, normal_loc, uv_loc);
        }

        // render focused block wireframe
        int hx, hy, hz;
        if (hit_test(chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz)) {
            glUseProgram(line_program);
            glLineWidth(1);
            glEnable(GL_COLOR_LOGIC_OP);
            glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
            GLuint buffer = make_cube_buffer(hx, hy, hz, 0.51);
            draw_lines(buffer, line_position_loc, 3, 48);
            glDeleteBuffers(1, &buffer);
            glDisable(GL_COLOR_LOGIC_OP);
        }

        update_matrix_2d(matrix);

        // render crosshairs
        glUseProgram(line_program);
        glLineWidth(4);
        glEnable(GL_COLOR_LOGIC_OP);
        glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
        GLuint buffer = make_line_buffer();
        draw_lines(buffer, line_position_loc, 2, 4);
        glDeleteBuffers(1, &buffer);
        glDisable(GL_COLOR_LOGIC_OP);

        glfwSwapBuffers();
    }
    db_save_state(x, y, z, rx, ry);
    db_close();
    glfwTerminate();
    return 0;
}
Ejemplo n.º 10
0
int main(int argc, char **argv) {
    srand(time(NULL));
    rand();
    if (argc == 2 || argc == 3) {
        char *hostname = argv[1];
        int port = DEFAULT_PORT;
        if (argc == 3) {
            port = atoi(argv[2]);
        }
        db_disable();
        client_enable();
        client_connect(hostname, port);
        client_start();
    }
    if (!glfwInit()) {
        return -1;
    }
    create_window();
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(VSYNC);
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    glfwSetKeyCallback(window, on_key);
    glfwSetMouseButtonCallback(window, on_mouse_button);
    glfwSetScrollCallback(window, on_scroll);

    #ifndef __APPLE__
        if (glewInit() != GLEW_OK) {
            return -1;
        }
    #endif

    if (db_init()) {
        return -1;
    }

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LINE_SMOOTH);
    glLogicOp(GL_INVERT);
    glClearColor(0.53, 0.81, 0.92, 1.00);

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    load_png_texture("texture.png");

    GLuint block_program = load_program(
        "shaders/block_vertex.glsl", "shaders/block_fragment.glsl");
    GLuint matrix_loc = glGetUniformLocation(block_program, "matrix");
    GLuint camera_loc = glGetUniformLocation(block_program, "camera");
    GLuint sampler_loc = glGetUniformLocation(block_program, "sampler");
    GLuint timer_loc = glGetUniformLocation(block_program, "timer");
    GLuint position_loc = glGetAttribLocation(block_program, "position");
    GLuint normal_loc = glGetAttribLocation(block_program, "normal");
    GLuint uv_loc = glGetAttribLocation(block_program, "uv");

    GLuint line_program = load_program(
        "shaders/line_vertex.glsl", "shaders/line_fragment.glsl");
    GLuint line_matrix_loc = glGetUniformLocation(line_program, "matrix");
    GLuint line_position_loc = glGetAttribLocation(line_program, "position");

    GLuint item_position_buffer = 0;
    GLuint item_normal_buffer = 0;
    GLuint item_uv_buffer = 0;
    int previous_block_type = 0;

    Chunk chunks[MAX_CHUNKS];
    int chunk_count = 0;

    Player players[MAX_PLAYERS];
    int player_count = 0;

    FPS fps = {0, 0};
    float matrix[16];
    float x = (rand_double() - 0.5) * 10000;
    float z = (rand_double() - 0.5) * 10000;
    float y = 0;
    float dy = 0;
    float rx = 0;
    float ry = 0;
    double px = 0;
    double py = 0;

    int loaded = db_load_state(&x, &y, &z, &rx, &ry);
    ensure_chunks(chunks, &chunk_count,
        floorf(roundf(x) / CHUNK_SIZE),
        floorf(roundf(z) / CHUNK_SIZE), 1);
    if (!loaded) {
        y = highest_block(chunks, chunk_count, x, z) + 2;
    }

    glfwGetCursorPos(window, &px, &py);
    double previous = glfwGetTime();
    while (!glfwWindowShouldClose(window)) {
        update_fps(&fps, SHOW_FPS);
        double now = glfwGetTime();
        double dt = MIN(now - previous, 0.2);
        previous = now;

        if (exclusive && (px || py)) {
            double mx, my;
            glfwGetCursorPos(window, &mx, &my);
            float m = 0.0025;
            rx += (mx - px) * m;
            ry -= (my - py) * m;
            if (rx < 0) {
                rx += RADIANS(360);
            }
            if (rx >= RADIANS(360)){
                rx -= RADIANS(360);
            }
            ry = MAX(ry, -RADIANS(90));
            ry = MIN(ry, RADIANS(90));
            px = mx;
            py = my;
        }
        else {
            glfwGetCursorPos(window, &px, &py);
        }

        int sz = 0;
        int sx = 0;
        ortho = glfwGetKey(window, 'F');
        fov = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) ? 15.0 : 65.0;
        if (glfwGetKey(window, 'Q')) break;
        if (glfwGetKey(window, 'W')) sz--;
        if (glfwGetKey(window, 'S')) sz++;
        if (glfwGetKey(window, 'A')) sx--;
        if (glfwGetKey(window, 'D')) sx++;
        float m = dt * 1.0;
        if (glfwGetKey(window, GLFW_KEY_LEFT)) rx -= m;
        if (glfwGetKey(window, GLFW_KEY_RIGHT)) rx += m;
        if (glfwGetKey(window, GLFW_KEY_UP)) ry += m;
        if (glfwGetKey(window, GLFW_KEY_DOWN)) ry -= m;
        float vx, vy, vz;
        get_motion_vector(flying, sz, sx, rx, ry, &vx, &vy, &vz);
        if (glfwGetKey(window, GLFW_KEY_SPACE)) {
            if (flying) {
                vy = 1;
            }
            else if (dy == 0) {
                dy = 8;
            }
        }
        if (glfwGetKey(window, 'Z')) {
            vx = -1; vy = 0; vz = 0;
        }
        if (glfwGetKey(window, 'X')) {
            vx = 1; vy = 0; vz = 0;
        }
        if (glfwGetKey(window, 'C')) {
            vx = 0; vy = -1; vz = 0;
        }
        if (glfwGetKey(window, 'V')) {
            vx = 0; vy = 1; vz = 0;
        }
        if (glfwGetKey(window, 'B')) {
            vx = 0; vy = 0; vz = -1;
        }
        if (glfwGetKey(window, 'N')) {
            vx = 0; vy = 0; vz = 1;
        }
        float speed = flying ? 20 : 5;
        int step = 8;
        float ut = dt / step;
        vx = vx * ut * speed;
        vy = vy * ut * speed;
        vz = vz * ut * speed;
        for (int i = 0; i < step; i++) {
            if (flying) {
                dy = 0;
            }
            else {
                dy -= ut * 25;
                dy = MAX(dy, -250);
            }
            x += vx;
            y += vy + dy * ut;
            z += vz;
            if (collide(chunks, chunk_count, 2, &x, &y, &z)) {
                dy = 0;
            }
        }
        if (y < 0) {
            y = highest_block(chunks, chunk_count, x, z) + 2;
        }

        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            chunk->dirty = 0;
        }

        if (left_click) {
            left_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (hy > 0 && is_destructable(hw)) {
                set_block(chunks, chunk_count, hx, hy, hz, 0, 1);
            }
        }

        if (right_click) {
            right_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 1, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (is_obstacle(hw)) {
                if (!player_intersects_block(2, x, y, z, hx, hy, hz)) {
                    set_block(chunks, chunk_count, hx, hy, hz, block_type, 1);
                }
            }
        }

        if (middle_click) {
            middle_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (is_selectable(hw)) {
                block_type = hw;
            }
        }

        if (teleport) {
            teleport = 0;
            if (player_count) {
                int index = rand_int(player_count);
                Player *player = players + index;
                x = player->x;
                y = player->y;
                z = player->z;
                rx = player->rx;
                ry = player->ry;
                ensure_chunks(chunks, &chunk_count,
                    floorf(roundf(x) / CHUNK_SIZE),
                    floorf(roundf(z) / CHUNK_SIZE), 1);
            }
        }

        client_position(x, y, z, rx, ry);
        char buffer[RECV_BUFFER_SIZE];
        while (client_recv(buffer, RECV_BUFFER_SIZE)) {
            float ux, uy, uz, urx, ury;
            if (sscanf(buffer, "U,%*d,%f,%f,%f,%f,%f",
                &ux, &uy, &uz, &urx, &ury) == 5)
            {
                x = ux; y = uy; z = uz; rx = urx; ry = ury;
                ensure_chunks(chunks, &chunk_count,
                    floorf(roundf(x) / CHUNK_SIZE),
                    floorf(roundf(z) / CHUNK_SIZE), 1);
                y = highest_block(chunks, chunk_count, x, z) + 2;
            }
            int bx, by, bz, bw;
            if (sscanf(buffer, "B,%*d,%*d,%d,%d,%d,%d",
                &bx, &by, &bz, &bw) == 4)
            {
                set_block(chunks, chunk_count, bx, by, bz, bw, 0);
                if ((int)roundf(x) == bx && (int)roundf(z) == bz) {
                    y = highest_block(chunks, chunk_count, x, z) + 2;
                }
            }
            int pid;
            float px, py, pz, prx, pry;
            if (sscanf(buffer, "P,%d,%f,%f,%f,%f,%f",
                &pid, &px, &py, &pz, &prx, &pry) == 6)
            {
                Player *player = find_player(players, player_count, pid);
                if (!player && player_count < MAX_PLAYERS) {
                    player = players + player_count;
                    player_count++;
                    player->id = pid;
                    player->position_buffer = 0;
                    player->normal_buffer = 0;
                    player->uv_buffer = 0;
                    printf("%d other players are online\n", player_count);
                }
                if (player) {
                    update_player(player, px, py, pz, prx, pry);
                }
            }
            if (sscanf(buffer, "D,%d", &pid) == 1) {
                delete_player(players, &player_count, pid);
                printf("%d other players are online\n", player_count);
            }
        }

        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            if (chunk->dirty) {
                update_chunk(chunk);
            }
        }

        int p = floorf(roundf(x) / CHUNK_SIZE);
        int q = floorf(roundf(z) / CHUNK_SIZE);
        ensure_chunks(chunks, &chunk_count, p, q, 0);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        update_matrix_3d(matrix, x, y, z, rx, ry);

        // render chunks
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, x, y, z);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            if (chunk_distance(chunk, p, q) > RENDER_CHUNK_RADIUS) {
                continue;
            }
            if (!chunk_visible(chunk, matrix)) {
                continue;
            }
            draw_chunk(chunk, position_loc, normal_loc, uv_loc);
        }

        // render players
        for (int i = 0; i < player_count; i++) {
            Player *player = players + i;
            draw_player(player, position_loc, normal_loc, uv_loc);
        }

        // render focused block wireframe
        int hx, hy, hz;
        int hw = hit_test(
            chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz);
        if (is_obstacle(hw)) {
            glUseProgram(line_program);
            glLineWidth(1);
            glEnable(GL_COLOR_LOGIC_OP);
            glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
            GLuint cube_buffer = make_cube_buffer(hx, hy, hz, 0.51);
            draw_lines(cube_buffer, line_position_loc, 3, 48);
            glDeleteBuffers(1, &cube_buffer);
            glDisable(GL_COLOR_LOGIC_OP);
        }

        update_matrix_2d(matrix);

        // render crosshairs
        glUseProgram(line_program);
        glLineWidth(4);
        glEnable(GL_COLOR_LOGIC_OP);
        glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
        GLuint line_buffer = make_line_buffer();
        draw_lines(line_buffer, line_position_loc, 2, 4);
        glDeleteBuffers(1, &line_buffer);
        glDisable(GL_COLOR_LOGIC_OP);

        // render selected item
        update_matrix_item(matrix);
        if (block_type != previous_block_type) {
            previous_block_type = block_type;
            make_single_cube(
                &item_position_buffer, &item_normal_buffer, &item_uv_buffer,
                0, 0, 0, 0.5, block_type);
        }
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, 0, 0, 5);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        glDisable(GL_DEPTH_TEST);
        draw_single_cube(
            item_position_buffer, item_normal_buffer, item_uv_buffer,
            position_loc, normal_loc, uv_loc);
        glEnable(GL_DEPTH_TEST);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    client_stop();
    db_save_state(x, y, z, rx, ry);
    db_close();
    glfwTerminate();
    return 0;
}
Ejemplo n.º 11
0
static inline void run_tick()
{
static bool can_tick = true;
static bool last_freezekey = false;
static bool last_framekey = false;
static int frameskip = 0;

	input_poll();
	
	// input handling for a few global things
	if (justpushed(ESCKEY))
	{
		if (settings->instant_quit)
		{
			game.running = false;
		}
		else if (!game.paused)		// no pause from Options
		{
			game.pause(GP_PAUSED);
		}
	}
	else if (justpushed(F3KEY))
	{
		game.pause(GP_OPTIONS);
	}
	
	// freeze frame
	if (settings->enable_debug_keys)
	{
		if (inputs[FREEZE_FRAME_KEY] && !last_freezekey)
		{
			can_tick = true;
			freezeframe ^= 1;
			framecount = 0;
		}
		
		if (inputs[FRAME_ADVANCE_KEY] && !last_framekey)
		{
			can_tick = true;
			if (!freezeframe)
			{
				freezeframe = 1;
				framecount = 0;
			}
		}
		
		last_freezekey = inputs[FREEZE_FRAME_KEY];
		last_framekey = inputs[FRAME_ADVANCE_KEY];
	}
	
	// fast-forward key (F5)
	if (inputs[FFWDKEY] && (settings->enable_debug_keys || Replay::IsPlaying()))
	{
		game.ffwdtime = 2;
	}
	
	if (can_tick)
	{
		game.tick();
		
		if (freezeframe)
		{
			char buf[1024];
			sprintf(buf, "[] Tick %d", framecount++);
			font_draw_shaded(4, (SCREEN_HEIGHT-GetFontHeight()-4), buf, 0, &greenfont);
			can_tick = false;
		}
		else
		{
			Replay::DrawStatus();
		}
		
		if (settings->show_fps)
		{
			update_fps();
		}
		
		if (!flipacceltime)
		{
			//platform_sync_to_vblank();
			screen->Flip();
		}
		else
		{
			flipacceltime--;
			if (--frameskip < 0)
			{
				screen->Flip();
				frameskip = 256;
			}
		}
		
		memcpy(lastinputs, inputs, sizeof(lastinputs));
	}
	else
	{	// frame is frozen; don't hog CPU
		SDL_Delay(20);
	}
	
	// immediately after a game tick is when we have the most amount of time before
	// the game needs to run again. so now's as good a time as any for some
	// BGM audio processing, wouldn't you say?
	org_run();
}
Ejemplo n.º 12
0
Archivo: video.c Proyecto: xnoreq/mpv
void write_video(struct MPContext *mpctx, double endpts)
{
    struct MPOpts *opts = mpctx->opts;
    struct vo *vo = mpctx->video_out;

    if (!mpctx->d_video)
        return;

    // Actual playback starts when both audio and video are ready.
    if (mpctx->video_status == STATUS_READY)
        return;

    if (mpctx->paused && mpctx->video_status >= STATUS_READY)
        return;

    update_fps(mpctx);

    int r = video_output_image(mpctx, endpts);
    MP_TRACE(mpctx, "video_output_image: %d\n", r);

    if (r < 0)
        goto error;

    if (r == VD_WAIT) // Demuxer will wake us up for more packets to decode.
        return;

    if (r == VD_EOF) {
        mpctx->video_status =
            vo_still_displaying(vo) ? STATUS_DRAINING : STATUS_EOF;
        mpctx->delay = 0;
        mpctx->last_av_difference = 0;
        MP_VERBOSE(mpctx, "video EOF (status=%d)\n", mpctx->video_status);
        return;
    }

    if (mpctx->video_status > STATUS_PLAYING)
        mpctx->video_status = STATUS_PLAYING;

    mpctx->time_frame -= get_relative_time(mpctx);
    update_avsync_before_frame(mpctx);

    if (r != VD_NEW_FRAME) {
        mpctx->sleeptime = 0; // Decode more in next iteration.
        return;
    }

    // Filter output is different from VO input?
    struct mp_image_params p = mpctx->next_frame[0]->params;
    if (!vo->params || !mp_image_params_equal(&p, vo->params)) {
        // Changing config deletes the current frame; wait until it's finished.
        if (vo_still_displaying(vo))
            return;

        const struct vo_driver *info = mpctx->video_out->driver;
        char extra[20] = {0};
        if (p.w != p.d_w || p.h != p.d_h)
            snprintf(extra, sizeof(extra), " => %dx%d", p.d_w, p.d_h);
        MP_INFO(mpctx, "VO: [%s] %dx%d%s %s\n",
                info->name, p.w, p.h, extra, vo_format_name(p.imgfmt));
        MP_VERBOSE(mpctx, "VO: Description: %s\n", info->description);

        int vo_r = vo_reconfig(vo, &p, 0);
        if (vo_r < 0) {
            mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
            goto error;
        }
        init_vo(mpctx);
        mpctx->time_frame = 0; // display immediately
    }

    double time_frame = MPMAX(mpctx->time_frame, -1);
    int64_t pts = mp_time_us() + (int64_t)(time_frame * 1e6);

    // wait until VO wakes us up to get more frames
    if (!vo_is_ready_for_frame(vo, pts)) {
        if (video_feed_async_filter(mpctx) < 0)
            goto error;
        return;
    }

    int64_t duration = -1;
    double diff = -1;
    double vpts0 = mpctx->next_frame[0] ? mpctx->next_frame[0]->pts : MP_NOPTS_VALUE;
    double vpts1 = mpctx->next_frame[1] ? mpctx->next_frame[1]->pts : MP_NOPTS_VALUE;
    if (vpts0 != MP_NOPTS_VALUE && vpts1 != MP_NOPTS_VALUE)
        diff = vpts1 - vpts0;
    if (diff < 0 && mpctx->d_video->fps > 0)
        diff = 1.0 / mpctx->d_video->fps; // fallback to demuxer-reported fps
    if (diff >= 0) {
        // expected A/V sync correction is ignored
        diff /= opts->playback_speed;
        if (mpctx->time_frame < 0)
            diff += mpctx->time_frame;
        duration = MPCLAMP(diff, 0, 10) * 1e6;
    }

    mpctx->video_pts = mpctx->next_frame[0]->pts;
    mpctx->last_vo_pts = mpctx->video_pts;
    mpctx->playback_pts = mpctx->video_pts;

    mpctx->osd_force_update = true;
    update_osd_msg(mpctx);
    update_subtitles(mpctx);

    vo_queue_frame(vo, mpctx->next_frame[0], pts, duration);
    mpctx->next_frame[0] = NULL;

    mpctx->shown_vframes++;
    if (mpctx->video_status < STATUS_PLAYING) {
        mpctx->video_status = STATUS_READY;
        // After a seek, make sure to wait until the first frame is visible.
        vo_wait_frame(vo);
    }
    update_avsync_after_frame(mpctx);
    screenshot_flip(mpctx);

    mp_notify(mpctx, MPV_EVENT_TICK, NULL);

    if (!mpctx->sync_audio_to_video)
        mpctx->video_status = STATUS_EOF;

    if (mpctx->video_status != STATUS_EOF) {
        if (mpctx->step_frames > 0) {
            mpctx->step_frames--;
            if (!mpctx->step_frames && !opts->pause)
                pause_player(mpctx);
        }
        if (mpctx->max_frames == 0)
            mpctx->stop_play = AT_END_OF_FILE;
        if (mpctx->max_frames > 0)
            mpctx->max_frames--;
    }

    mpctx->sleeptime = 0;
    return;

error:
    MP_FATAL(mpctx, "Could not initialize video chain.\n");
    uninit_video_chain(mpctx);
    error_on_track(mpctx, mpctx->current_track[STREAM_VIDEO][0]);
    handle_force_window(mpctx, true);
    mpctx->sleeptime = 0;
}
Ejemplo n.º 13
0
void write_video(struct MPContext *mpctx, double endpts)
{
    struct MPOpts *opts = mpctx->opts;
    struct vo *vo = mpctx->video_out;

    if (!mpctx->d_video)
        return;

    update_fps(mpctx);

    // Whether there's still at least 1 video frame that can be shown.
    // If false, it means we can reconfig the VO if needed (normally, this
    // would disrupt playback, so only do it on !still_playing).
    bool still_playing = vo_has_next_frame(vo, true);
    // For the last frame case (frame is being displayed).
    still_playing |= mpctx->playing_last_frame;
    still_playing |= mpctx->last_frame_duration > 0;

    double frame_time = 0;
    int r = update_video(mpctx, endpts, !still_playing, &frame_time);
    MP_TRACE(mpctx, "update_video: %d (still_playing=%d)\n", r, still_playing);

    if (r == VD_WAIT) // Demuxer will wake us up for more packets to decode.
        return;

    if (r < 0) {
        MP_FATAL(mpctx, "Could not initialize video chain.\n");
        int uninit = INITIALIZED_VCODEC;
        if (!opts->force_vo)
            uninit |= INITIALIZED_VO;
        uninit_player(mpctx, uninit);
        if (!mpctx->current_track[STREAM_AUDIO])
            mpctx->stop_play = PT_NEXT_ENTRY;
        mpctx->error_playing = true;
        handle_force_window(mpctx, true);
        return; // restart loop
    }

    if (r == VD_EOF) {
        if (!mpctx->playing_last_frame && mpctx->last_frame_duration > 0) {
            mpctx->time_frame += mpctx->last_frame_duration;
            mpctx->last_frame_duration = 0;
            mpctx->playing_last_frame = true;
            MP_VERBOSE(mpctx, "showing last frame\n");
        }
    }

    if (r == VD_NEW_FRAME) {
        MP_TRACE(mpctx, "frametime=%5.3f\n", frame_time);

        if (mpctx->video_status > STATUS_PLAYING)
            mpctx->video_status = STATUS_PLAYING;

        if (mpctx->video_status >= STATUS_READY) {
            mpctx->time_frame += frame_time / opts->playback_speed;
            adjust_sync(mpctx, frame_time);
        }
    } else if (r == VD_EOF && mpctx->playing_last_frame) {
        // Let video timing code continue displaying.
        mpctx->video_status = STATUS_DRAINING;
        MP_VERBOSE(mpctx, "still showing last frame\n");
    } else if (r <= 0) {
        // EOF or error
        mpctx->delay = 0;
        mpctx->last_av_difference = 0;
        mpctx->video_status = STATUS_EOF;
        MP_VERBOSE(mpctx, "video EOF\n");
        return;
    } else {
        if (mpctx->video_status > STATUS_PLAYING)
            mpctx->video_status = STATUS_PLAYING;

        // Decode more in next iteration.
        mpctx->sleeptime = 0;
        MP_TRACE(mpctx, "filtering more video\n");
    }

    // Actual playback starts when both audio and video are ready.
    if (mpctx->video_status == STATUS_READY)
        return;

    if (mpctx->paused && mpctx->video_status >= STATUS_READY)
        return;

    mpctx->time_frame -= get_relative_time(mpctx);
    double audio_pts = playing_audio_pts(mpctx);
    if (!mpctx->sync_audio_to_video || mpctx->video_status < STATUS_READY) {
        mpctx->time_frame = 0;
    } else if (mpctx->audio_status == STATUS_PLAYING &&
               mpctx->video_status == STATUS_PLAYING)
    {
        double buffered_audio = ao_get_delay(mpctx->ao);
        MP_TRACE(mpctx, "audio delay=%f\n", buffered_audio);

        if (opts->autosync) {
            /* Smooth reported playback position from AO by averaging
             * it with the value expected based on previus value and
             * time elapsed since then. May help smooth video timing
             * with audio output that have inaccurate position reporting.
             * This is badly implemented; the behavior of the smoothing
             * now undesirably depends on how often this code runs
             * (mainly depends on video frame rate). */
            float predicted = (mpctx->delay / opts->playback_speed +
                                mpctx->time_frame);
            float difference = buffered_audio - predicted;
            buffered_audio = predicted + difference / opts->autosync;
        }

        mpctx->time_frame = (buffered_audio -
                                mpctx->delay / opts->playback_speed);
    } else {
        /* If we're more than 200 ms behind the right playback
         * position, don't try to speed up display of following
         * frames to catch up; continue with default speed from
         * the current frame instead.
         * If untimed is set always output frames immediately
         * without sleeping.
         */
        if (mpctx->time_frame < -0.2 || opts->untimed || vo->untimed)
            mpctx->time_frame = 0;
    }

    double vsleep = mpctx->time_frame - vo->flip_queue_offset;
    if (vsleep > 0.050) {
        mpctx->sleeptime = MPMIN(mpctx->sleeptime, vsleep - 0.040);
        return;
    }
    mpctx->sleeptime = 0;
    mpctx->playing_last_frame = false;

    // last frame case
    if (r != VD_NEW_FRAME)
        return;

    //=================== FLIP PAGE (VIDEO BLT): ======================


    mpctx->video_pts = mpctx->video_next_pts;
    mpctx->last_vo_pts = mpctx->video_pts;
    mpctx->playback_pts = mpctx->video_pts;

    update_subtitles(mpctx);
    update_osd_msg(mpctx);

    MP_STATS(mpctx, "vo draw frame");

    vo_new_frame_imminent(vo);

    MP_STATS(mpctx, "vo sleep");

    mpctx->time_frame -= get_relative_time(mpctx);
    mpctx->time_frame -= vo->flip_queue_offset;
    if (mpctx->time_frame > 0.001)
        mpctx->time_frame = timing_sleep(mpctx, mpctx->time_frame);
    mpctx->time_frame += vo->flip_queue_offset;

    int64_t t2 = mp_time_us();
    /* Playing with playback speed it's possible to get pathological
     * cases with mpctx->time_frame negative enough to cause an
     * overflow in pts_us calculation, thus the MPMAX. */
    double time_frame = MPMAX(mpctx->time_frame, -1);
    int64_t pts_us = mpctx->last_time + time_frame * 1e6;
    int duration = -1;
    double pts2 = vo_get_next_pts(vo, 0); // this is the next frame PTS
    if (mpctx->video_pts != MP_NOPTS_VALUE && pts2 == MP_NOPTS_VALUE) {
        // Make up a frame duration. Using the frame rate is not a good
        // choice, since the frame rate could be unset/broken/random.
        float fps = mpctx->d_video->fps;
        double frame_duration = fps > 0 ? 1.0 / fps : 0;
        pts2 = mpctx->video_pts + MPCLAMP(frame_duration, 0.0, 5.0);
    }
    if (pts2 != MP_NOPTS_VALUE) {
        // expected A/V sync correction is ignored
        double diff = (pts2 - mpctx->video_pts);
        diff /= opts->playback_speed;
        if (mpctx->time_frame < 0)
            diff += mpctx->time_frame;
        if (diff < 0)
            diff = 0;
        if (diff > 10)
            diff = 10;
        duration = diff * 1e6;
        mpctx->last_frame_duration = diff;
    }
    if (mpctx->video_status != STATUS_PLAYING)
        duration = -1;

    MP_STATS(mpctx, "start flip");
    vo_flip_page(vo, pts_us | 1, duration);
    MP_STATS(mpctx, "end flip");

    if (audio_pts != MP_NOPTS_VALUE)
        MP_STATS(mpctx, "value %f ptsdiff", mpctx->video_pts - audio_pts);

    mpctx->last_vo_flip_duration = (mp_time_us() - t2) * 0.000001;
    if (vo->driver->flip_page_timed) {
        // No need to adjust sync based on flip speed
        mpctx->last_vo_flip_duration = 0;
        // For print_status - VO call finishing early is OK for sync
        mpctx->time_frame -= get_relative_time(mpctx);
    }
    mpctx->shown_vframes++;
    if (mpctx->video_status < STATUS_PLAYING)
        mpctx->video_status = STATUS_READY;
    update_avsync(mpctx);
    screenshot_flip(mpctx);

    mp_notify(mpctx, MPV_EVENT_TICK, NULL);

    if (!mpctx->sync_audio_to_video)
        mpctx->video_status = STATUS_EOF;
}
Ejemplo n.º 14
0
int main(int argc, char **argv) {
    srand(time(NULL));
    rand();
    if (!glfwInit()) {
        return -1;
    }
    create_window();
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(VSYNC);
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    glfwSetKeyCallback(window, on_key);
    glfwSetMouseButtonCallback(window, on_mouse_button);

    #ifndef __APPLE__
        if (glewInit() != GLEW_OK) {
            return -1;
        }
    #endif

    if (db_init()) {
        return -1;
    }

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LINE_SMOOTH);
    glLogicOp(GL_INVERT);
    glClearColor(0.53, 0.81, 0.92, 1.00);

    GLuint vertex_array;
    glGenVertexArrays(1, &vertex_array);
    glBindVertexArray(vertex_array);

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    load_png_texture("texture.png");

    GLuint block_program = load_program(
        "shaders/block_vertex.glsl", "shaders/block_fragment.glsl");
    GLuint matrix_loc = glGetUniformLocation(block_program, "matrix");
    GLuint camera_loc = glGetUniformLocation(block_program, "camera");
    GLuint sampler_loc = glGetUniformLocation(block_program, "sampler");
    GLuint timer_loc = glGetUniformLocation(block_program, "timer");
    GLuint position_loc = glGetAttribLocation(block_program, "position");
    GLuint normal_loc = glGetAttribLocation(block_program, "normal");
    GLuint uv_loc = glGetAttribLocation(block_program, "uv");

    GLuint line_program = load_program(
        "shaders/line_vertex.glsl", "shaders/line_fragment.glsl");
    GLuint line_matrix_loc = glGetUniformLocation(line_program, "matrix");
    GLuint line_position_loc = glGetAttribLocation(line_program, "position");

    GLuint item_position_buffer = 0;
    GLuint item_normal_buffer = 0;
    GLuint item_uv_buffer = 0;
    int previous_block_type = 0;

    Chunk chunks[MAX_CHUNKS];
    int chunk_count = 0;

    FPS fps = {0, 0};
    float matrix[16];
    float x = (rand_double() - 0.5) * 10000;
    float z = (rand_double() - 0.5) * 10000;
    float y = 0;
    float dy = 0;
    float rx = 0;
    float ry = 0;
    double px = 0;
    double py = 0;

    int loaded = db_load_state(&x, &y, &z, &rx, &ry);
    ensure_chunks(chunks, &chunk_count,
        floorf(roundf(x) / CHUNK_SIZE),
        floorf(roundf(z) / CHUNK_SIZE), 1);
    if (!loaded) {
        y = highest_block(chunks, chunk_count, x, z) + 2;
    }

    glfwGetCursorPos(window, &px, &py);
    double previous = glfwGetTime();
    while (!glfwWindowShouldClose(window)) {
        update_fps(&fps, SHOW_FPS);
        double now = glfwGetTime();
        double dt = MIN(now - previous, 0.2);
        previous = now;

        if (exclusive && (px || py)) {
            double mx, my;
            glfwGetCursorPos(window, &mx, &my);
            float m = 0.0025;
            rx += (mx - px) * m;
            ry -= (my - py) * m;
            if (rx < 0) {
                rx += RADIANS(360);
            }
            if (rx >= RADIANS(360)){
                rx -= RADIANS(360);
            }
            ry = MAX(ry, -RADIANS(90));
            ry = MIN(ry, RADIANS(90));
            px = mx;
            py = my;
        }
        else {
            glfwGetCursorPos(window, &px, &py);
        }

        if (left_click) {
            left_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (hy > 0 && is_destructable(hw)) {
                set_block(chunks, chunk_count, hx, hy, hz, 0);
            }
        }

        if (right_click) {
            right_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 1, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (is_obstacle(hw)) {
                if (!player_intersects_block(2, x, y, z, hx, hy, hz)) {
                    set_block(chunks, chunk_count, hx, hy, hz, block_type);
                }
            }
        }

        int sz = 0;
        int sx = 0;
        ortho = glfwGetKey(window, 'F');
        fov = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) ? 15.0 : 65.0;
        if (glfwGetKey(window, 'Q')) break;
        if (glfwGetKey(window, 'W')) sz--;
        if (glfwGetKey(window, 'S')) sz++;
        if (glfwGetKey(window, 'A')) sx--;
        if (glfwGetKey(window, 'D')) sx++;
        if (dy == 0 && glfwGetKey(window, GLFW_KEY_SPACE)) {
            dy = 8;
        }
        float vx, vy, vz;
        get_motion_vector(flying, sz, sx, rx, ry, &vx, &vy, &vz);
        if (glfwGetKey(window, 'Z')) {
            vx = -1; vy = 0; vz = 0;
        }
        if (glfwGetKey(window, 'X')) {
            vx = 1; vy = 0; vz = 0;
        }
        if (glfwGetKey(window, 'C')) {
            vx = 0; vy = -1; vz = 0;
        }
        if (glfwGetKey(window, 'V')) {
            vx = 0; vy = 1; vz = 0;
        }
        if (glfwGetKey(window, 'B')) {
            vx = 0; vy = 0; vz = -1;
        }
        if (glfwGetKey(window, 'N')) {
            vx = 0; vy = 0; vz = 1;
        }
        float speed = flying ? 20 : 5;
        int step = 8;
        float ut = dt / step;
        vx = vx * ut * speed;
        vy = vy * ut * speed;
        vz = vz * ut * speed;
        for (int i = 0; i < step; i++) {
            if (flying) {
                dy = 0;
            }
            else {
                dy -= ut * 25;
                dy = MAX(dy, -250);
            }
            x += vx;
            y += vy + dy * ut;
            z += vz;
            if (collide(chunks, chunk_count, 2, &x, &y, &z)) {
                dy = 0;
            }
        }

        int p = floorf(roundf(x) / CHUNK_SIZE);
        int q = floorf(roundf(z) / CHUNK_SIZE);
        ensure_chunks(chunks, &chunk_count, p, q, 0);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        update_matrix_3d(matrix, x, y, z, rx, ry);

        // render chunks
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, x, y, z);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            if (chunk_distance(chunk, p, q) > RENDER_CHUNK_RADIUS) {
                continue;
            }
            if (!chunk_visible(chunk, matrix)) {
                continue;
            }
            draw_chunk(chunk, position_loc, normal_loc, uv_loc);
        }

        // render focused block wireframe
        int hx, hy, hz;
        int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz);
        if (is_obstacle(hw)) {
            glUseProgram(line_program);
            glLineWidth(1);
            glEnable(GL_COLOR_LOGIC_OP);
            glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
            GLuint buffer = make_cube_buffer(hx, hy, hz, 0.51);
            draw_lines(buffer, line_position_loc, 3, 48);
            glDeleteBuffers(1, &buffer);
            glDisable(GL_COLOR_LOGIC_OP);
        }

        update_matrix_2d(matrix);

        // render crosshairs
        glUseProgram(line_program);
        glLineWidth(4);
        glEnable(GL_COLOR_LOGIC_OP);
        glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
        GLuint buffer = make_line_buffer();
        draw_lines(buffer, line_position_loc, 2, 4);
        glDeleteBuffers(1, &buffer);
        glDisable(GL_COLOR_LOGIC_OP);

        // render selected item
        update_matrix_item(matrix);
        if (block_type != previous_block_type) {
            previous_block_type = block_type;
            make_single_cube(
                &item_position_buffer, &item_normal_buffer, &item_uv_buffer,
                block_type);
        }
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, 0, 0, 5);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        glDisable(GL_DEPTH_TEST);
        draw_single_cube(
            item_position_buffer, item_normal_buffer, item_uv_buffer,
            position_loc, normal_loc, uv_loc);
        glEnable(GL_DEPTH_TEST);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    db_save_state(x, y, z, rx, ry);
    db_close();
    glfwTerminate();
    return 0;
}
Ejemplo n.º 15
0
Archivo: video.c Proyecto: xnoreq/mpv
int reinit_video_chain(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    assert(!mpctx->d_video);
    struct track *track = mpctx->current_track[0][STREAM_VIDEO];
    struct sh_stream *sh = track ? track->stream : NULL;
    if (!sh)
        goto no_video;

    MP_VERBOSE(mpctx, "[V] fourcc:0x%X  size:%dx%d  fps:%5.3f\n",
               sh->format,
               sh->video->disp_w, sh->video->disp_h,
               sh->video->fps);

    //================== Init VIDEO (codec & libvo) ==========================
    if (!opts->fixed_vo || !mpctx->video_out) {
        struct vo_extra ex = {
            .input_ctx = mpctx->input,
            .osd = mpctx->osd,
            .encode_lavc_ctx = mpctx->encode_lavc_ctx,
            .opengl_cb_context = mpctx->gl_cb_ctx,
        };
        mpctx->video_out = init_best_video_out(mpctx->global, &ex);
        if (!mpctx->video_out) {
            MP_FATAL(mpctx, "Error opening/initializing "
                    "the selected video_out (-vo) device.\n");
            mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
            goto err_out;
        }
        mpctx->mouse_cursor_visible = true;
    }

    update_window_title(mpctx, true);

    struct dec_video *d_video = talloc_zero(NULL, struct dec_video);
    mpctx->d_video = d_video;
    d_video->global = mpctx->global;
    d_video->log = mp_log_new(d_video, mpctx->log, "!vd");
    d_video->opts = mpctx->opts;
    d_video->header = sh;
    d_video->fps = sh->video->fps;
    d_video->vo = mpctx->video_out;

    if (opts->force_fps) {
        d_video->fps = opts->force_fps;
        MP_INFO(mpctx, "FPS forced to %5.3f.\n", d_video->fps);
        MP_INFO(mpctx, "Use --no-correct-pts to force FPS based timing.\n");
    }
    update_fps(mpctx);

    vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);

    recreate_video_filters(mpctx);

    if (!video_init_best_codec(d_video, opts->video_decoders))
        goto err_out;

    bool saver_state = opts->pause || !opts->stop_screensaver;
    vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
                                             : VOCTRL_KILL_SCREENSAVER, NULL);

    vo_set_paused(mpctx->video_out, mpctx->paused);

    mpctx->sync_audio_to_video = !sh->attached_picture;
    mpctx->vo_pts_history_seek_ts++;

    // If we switch on video again, ensure audio position matches up.
    if (mpctx->d_audio)
        mpctx->audio_status = STATUS_SYNCING;

    reset_video_state(mpctx);
    reset_subtitle_state(mpctx);

    return 1;

err_out:
no_video:
    uninit_video_chain(mpctx);
    if (track)
        error_on_track(mpctx, track);
    handle_force_window(mpctx, true);
    return 0;
}

// Try to refresh the video by doing a precise seek to the currently displayed
// frame. This can go wrong in all sorts of ways, so use sparingly.
void mp_force_video_refresh(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    struct dec_video *d_video = mpctx->d_video;

    if (!d_video || !d_video->decoder_output.imgfmt)
        return;

    // If not paused, the next frame should come soon enough.
    if (opts->pause && mpctx->last_vo_pts != MP_NOPTS_VALUE)
        queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->last_vo_pts, 2, true);
}

static int check_framedrop(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    // check for frame-drop:
    if (mpctx->video_status == STATUS_PLAYING && !mpctx->paused &&
        mpctx->audio_status == STATUS_PLAYING && !ao_untimed(mpctx->ao))
    {
        float fps = mpctx->d_video->fps;
        double frame_time = fps > 0 ? 1.0 / fps : 0;
        // we should avoid dropping too many frames in sequence unless we
        // are too late. and we allow 100ms A-V delay here:
        if (mpctx->last_av_difference - 0.100 > mpctx->dropped_frames * frame_time)
            return !!(opts->frame_dropping & 2);
    }
    return 0;
}

// Read a packet, store decoded image into d_video->waiting_decoded_mpi
// returns VD_* code
static int decode_image(struct MPContext *mpctx)
{
    struct dec_video *d_video = mpctx->d_video;

    if (d_video->header->attached_picture) {
        d_video->waiting_decoded_mpi =
                    video_decode(d_video, d_video->header->attached_picture, 0);
        return VD_EOF;
    }

    struct demux_packet *pkt;
    if (demux_read_packet_async(d_video->header, &pkt) == 0)
        return VD_WAIT;
    if (pkt && pkt->pts != MP_NOPTS_VALUE)
        pkt->pts += mpctx->video_offset;
    if ((pkt && pkt->pts >= mpctx->hrseek_pts - .005) ||
        d_video->has_broken_packet_pts ||
        !mpctx->opts->hr_seek_framedrop)
    {
        mpctx->hrseek_framedrop = false;
    }
    bool hrseek = mpctx->hrseek_active && mpctx->video_status == STATUS_SYNCING;
    int framedrop_type = hrseek && mpctx->hrseek_framedrop ?
                         2 : check_framedrop(mpctx);
    d_video->waiting_decoded_mpi =
        video_decode(d_video, pkt, framedrop_type);
    bool had_packet = !!pkt;
    talloc_free(pkt);

    if (had_packet && !d_video->waiting_decoded_mpi &&
        mpctx->video_status == STATUS_PLAYING)
    {
        mpctx->dropped_frames_total++;
        mpctx->dropped_frames++;
    }

    return had_packet ? VD_PROGRESS : VD_EOF;
}


// Called after video reinit. This can be generally used to try to insert more
// filters using the filter chain edit functionality in command.c.
static void init_filter_params(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;

    // Note that the filter chain is already initialized. This code might
    // recreate the chain a second time, which is not very elegant, but allows
    // us to test whether enabling deinterlacing works with the current video
    // format and other filters.
    if (opts->deinterlace >= 0)
        mp_property_do("deinterlace", M_PROPERTY_SET, &opts->deinterlace, mpctx);
}

// Feed newly decoded frames to the filter, take care of format changes.
// If eof=true, drain the filter chain, and return VD_EOF if empty.
static int video_filter(struct MPContext *mpctx, bool eof)
{
    struct dec_video *d_video = mpctx->d_video;
    struct vf_chain *vf = d_video->vfilter;

    if (vf->initialized < 0)
        return VD_ERROR;

    // There is already a filtered frame available.
    // If vf_needs_input() returns > 0, the filter wants input anyway.
    if (vf_output_frame(vf, eof) > 0 && vf_needs_input(vf) < 1)
        return VD_PROGRESS;

    // Decoder output is different from filter input?
    bool need_vf_reconfig = !vf->input_params.imgfmt || vf->initialized < 1 ||
        !mp_image_params_equal(&d_video->decoder_output, &vf->input_params);

    // (If imgfmt==0, nothing was decoded yet, and the format is unknown.)
    if (need_vf_reconfig && d_video->decoder_output.imgfmt) {
        // Drain the filter chain.
        if (vf_output_frame(vf, true) > 0)
            return VD_PROGRESS;

        // The filter chain is drained; execute the filter format change.
        filter_reconfig(mpctx, false);
        if (vf->initialized == 0)
            return VD_PROGRESS; // hw decoding fallback; try again
        if (vf->initialized < 1)
            return VD_ERROR;
        init_filter_params(mpctx);
        return VD_RECONFIG;
    }

    // If something was decoded, and the filter chain is ready, filter it.
    if (!need_vf_reconfig && d_video->waiting_decoded_mpi) {
        vf_filter_frame(vf, d_video->waiting_decoded_mpi);
        d_video->waiting_decoded_mpi = NULL;
        return VD_PROGRESS;
    }

    return eof ? VD_EOF : VD_PROGRESS;
}

// Make sure at least 1 filtered image is available, decode new video if needed.
// returns VD_* code
// A return value of VD_PROGRESS doesn't necessarily output a frame, but makes
// the promise that calling this function again will eventually do something.
static int video_decode_and_filter(struct MPContext *mpctx)
{
    struct dec_video *d_video = mpctx->d_video;

    int r = video_filter(mpctx, false);
    if (r < 0)
        return r;

    if (!d_video->waiting_decoded_mpi) {
        // Decode a new image, or at least feed the decoder a packet.
        r = decode_image(mpctx);
        if (r == VD_WAIT)
            return r;
        if (d_video->waiting_decoded_mpi)
            d_video->decoder_output = d_video->waiting_decoded_mpi->params;
    }

    bool eof = !d_video->waiting_decoded_mpi && (r == VD_EOF || r < 0);
    r = video_filter(mpctx, eof);
    if (r == VD_RECONFIG) // retry feeding decoded image
        r = video_filter(mpctx, eof);
    return r;
}

static int video_feed_async_filter(struct MPContext *mpctx)
{
    struct dec_video *d_video = mpctx->d_video;
    struct vf_chain *vf = d_video->vfilter;

    if (vf->initialized < 0)
        return VD_ERROR;

    if (vf_needs_input(vf) < 1)
        return 0;
    mpctx->sleeptime = 0; // retry until done
    return video_decode_and_filter(mpctx);
}

/* Modify video timing to match the audio timeline. There are two main
 * reasons this is needed. First, video and audio can start from different
 * positions at beginning of file or after a seek (MPlayer starts both
 * immediately even if they have different pts). Second, the file can have
 * audio timestamps that are inconsistent with the duration of the audio
 * packets, for example two consecutive timestamp values differing by
 * one second but only a packet with enough samples for half a second
 * of playback between them.
 */
static void adjust_sync(struct MPContext *mpctx, double v_pts, double frame_time)
{
    struct MPOpts *opts = mpctx->opts;

    if (mpctx->audio_status != STATUS_PLAYING)
        return;

    double a_pts = written_audio_pts(mpctx) + mpctx->audio_delay - mpctx->delay;
    double av_delay = a_pts - v_pts;

    double change = av_delay * 0.1;
    double max_change = opts->default_max_pts_correction >= 0 ?
                        opts->default_max_pts_correction : frame_time * 0.1;
    if (change < -max_change)
        change = -max_change;
    else if (change > max_change)
        change = max_change;
    mpctx->delay += change;
    mpctx->total_avsync_change += change;
}

// Enough video filtered already to push one frame to the VO?
static bool have_new_frame(struct MPContext *mpctx)
{
    bool need_2nd = !!(mpctx->opts->frame_dropping & 1) // we need the duration
        && mpctx->video_pts != MP_NOPTS_VALUE; // ...except for the 1st frame

    return mpctx->next_frame[0] && (!need_2nd || mpctx->next_frame[1]);
}
Ejemplo n.º 16
0
int main(int argc, char **argv) {
    srand(time(NULL));
    rand();
    if (argc == 2 || argc == 3) {
        char *hostname = argv[1];
        int port = DEFAULT_PORT;
        if (argc == 3) {
            port = atoi(argv[2]);
        }
        db_disable();
        client_enable();
        client_connect(hostname, port);
        client_start();
    }
    if (!glfwInit()) {
        return -1;
    }
    create_window();
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(VSYNC);
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    glfwSetKeyCallback(window, on_key);
    glfwSetCharCallback(window, on_char);
    glfwSetMouseButtonCallback(window, on_mouse_button);
    glfwSetScrollCallback(window, on_scroll);

    #ifndef __APPLE__
        if (glewInit() != GLEW_OK) {
            return -1;
        }
    #endif

    if (db_init()) {
        return -1;
    }

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LINE_SMOOTH);
    glLogicOp(GL_INVERT);
    glClearColor(0.53, 0.81, 0.92, 1.00);

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    load_png_texture("texture.png");

    GLuint font;
    glGenTextures(1, &font);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, font);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    load_png_texture("font.png");

    GLuint block_program = load_program(
        "shaders/block_vertex.glsl", "shaders/block_fragment.glsl");
    GLuint matrix_loc = glGetUniformLocation(block_program, "matrix");
    GLuint camera_loc = glGetUniformLocation(block_program, "camera");
    GLuint sampler_loc = glGetUniformLocation(block_program, "sampler");
    GLuint timer_loc = glGetUniformLocation(block_program, "timer");
    GLuint position_loc = glGetAttribLocation(block_program, "position");
    GLuint normal_loc = glGetAttribLocation(block_program, "normal");
    GLuint uv_loc = glGetAttribLocation(block_program, "uv");

    GLuint line_program = load_program(
        "shaders/line_vertex.glsl", "shaders/line_fragment.glsl");
    GLuint line_matrix_loc = glGetUniformLocation(line_program, "matrix");
    GLuint line_position_loc = glGetAttribLocation(line_program, "position");

    GLuint text_program = load_program(
        "shaders/text_vertex.glsl", "shaders/text_fragment.glsl");
    GLuint text_matrix_loc = glGetUniformLocation(text_program, "matrix");
    GLuint text_sampler_loc = glGetUniformLocation(text_program, "sampler");
    GLuint text_position_loc = glGetAttribLocation(text_program, "position");
    GLuint text_uv_loc = glGetAttribLocation(text_program, "uv");

    GLuint item_position_buffer = 0;
    GLuint item_normal_buffer = 0;
    GLuint item_uv_buffer = 0;
    int previous_block_type = 0;
    char messages[MAX_MESSAGES][TEXT_BUFFER_SIZE] = {0};
    int message_index = 0;

    Chunk chunks[MAX_CHUNKS];
    int chunk_count = 0;

    Player players[MAX_PLAYERS];
    int player_count = 0;

    FPS fps = {0, 0};
    float matrix[16];
    float x = (rand_double() - 0.5) * 10000;
    float z = (rand_double() - 0.5) * 10000;
    float y = 0;
    float dy = 0;
    float rx = 0;
    float ry = 0;
    double px = 0;
    double py = 0;

    int loaded = db_load_state(&x, &y, &z, &rx, &ry);
    ensure_chunks(chunks, &chunk_count, x, y, z, 1);
    if (!loaded) {
        y = highest_block(chunks, chunk_count, x, z) + 2;
    }

    glfwGetCursorPos(window, &px, &py);
    double previous = glfwGetTime();
    while (!glfwWindowShouldClose(window)) {
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);

        update_fps(&fps, SHOW_FPS);
        double now = glfwGetTime();
        double dt = MIN(now - previous, 0.2);
        previous = now;

        if (exclusive && (px || py)) {
            double mx, my;
            glfwGetCursorPos(window, &mx, &my);
            float m = 0.0025;
            rx += (mx - px) * m;
            ry -= (my - py) * m;
            if (rx < 0) {
                rx += RADIANS(360);
            }
            if (rx >= RADIANS(360)){
                rx -= RADIANS(360);
            }
            ry = MAX(ry, -RADIANS(90));
            ry = MIN(ry, RADIANS(90));
            px = mx;
            py = my;
        }
        else {
            glfwGetCursorPos(window, &px, &py);
        }

        int sz = 0;
        int sx = 0;
        if (!typing) {
            float m = dt * 1.0;
            ortho = glfwGetKey(window, CRAFT_KEY_ORTHO);
            fov = glfwGetKey(window, CRAFT_KEY_ZOOM) ? 15.0 : 65.0;
            if (glfwGetKey(window, CRAFT_KEY_QUIT)) break;
            if (glfwGetKey(window, CRAFT_KEY_FORWARD)) sz--;
            if (glfwGetKey(window, CRAFT_KEY_BACKWARD)) sz++;
            if (glfwGetKey(window, CRAFT_KEY_LEFT)) sx--;
            if (glfwGetKey(window, CRAFT_KEY_RIGHT)) sx++;
            if (glfwGetKey(window, GLFW_KEY_LEFT)) rx -= m;
            if (glfwGetKey(window, GLFW_KEY_RIGHT)) rx += m;
            if (glfwGetKey(window, GLFW_KEY_UP)) ry += m;
            if (glfwGetKey(window, GLFW_KEY_DOWN)) ry -= m;
        }
        float vx, vy, vz;
        get_motion_vector(flying, sz, sx, rx, ry, &vx, &vy, &vz);
        if (!typing) {
            if (glfwGetKey(window, CRAFT_KEY_JUMP)) {
                if (flying) {
                    vy = 1;
                }
                else if (dy == 0) {
                    dy = 8;
                }
            }
            if (glfwGetKey(window, CRAFT_KEY_XM)) {
                vx = -1; vy = 0; vz = 0;
            }
            if (glfwGetKey(window, CRAFT_KEY_XP)) {
                vx = 1; vy = 0; vz = 0;
            }
            if (glfwGetKey(window, CRAFT_KEY_YM)) {
                vx = 0; vy = -1; vz = 0;
            }
            if (glfwGetKey(window, CRAFT_KEY_YP)) {
                vx = 0; vy = 1; vz = 0;
            }
            if (glfwGetKey(window, CRAFT_KEY_ZM)) {
                vx = 0; vy = 0; vz = -1;
            }
            if (glfwGetKey(window, CRAFT_KEY_ZP)) {
                vx = 0; vy = 0; vz = 1;
            }
        }
        float speed = flying ? 20 : 5;
        int step = 8;
        float ut = dt / step;
        vx = vx * ut * speed;
        vy = vy * ut * speed;
        vz = vz * ut * speed;
        for (int i = 0; i < step; i++) {
            if (flying) {
                dy = 0;
            }
            else {
                dy -= ut * 25;
                dy = MAX(dy, -250);
            }
            x += vx;
            y += vy + dy * ut;
            z += vz;
            if (collide(chunks, chunk_count, 2, &x, &y, &z)) {
                dy = 0;
            }
        }
        if (y < 0) {
            y = highest_block(chunks, chunk_count, x, z) + 2;
        }

        if (left_click) {
            left_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (hy > 0 && is_destructable(hw)) {
                set_block(chunks, chunk_count, hx, hy, hz, 0);
                int above = get_block(chunks, chunk_count, hx, hy + 1, hz);
                if (is_plant(above)) {
                    set_block(chunks, chunk_count, hx, hy + 1, hz, 0);
                }
            }
        }

        if (right_click) {
            right_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 1, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (is_obstacle(hw)) {
                if (!player_intersects_block(2, x, y, z, hx, hy, hz)) {
                    set_block(chunks, chunk_count, hx, hy, hz, block_type);
                }
            }
        }

        if (middle_click) {
            middle_click = 0;
            int hx, hy, hz;
            int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry,
                &hx, &hy, &hz);
            if (is_selectable(hw)) {
                block_type = hw;
            }
        }

        if (teleport) {
            teleport = 0;
            if (player_count) {
                int index = rand_int(player_count);
                Player *player = players + index;
                x = player->x; y = player->y; z = player->z;
                rx = player->rx; ry = player->ry;
                ensure_chunks(chunks, &chunk_count, x, y, z, 1);
            }
        }

        client_position(x, y, z, rx, ry);
        char buffer[RECV_BUFFER_SIZE];
        while (client_recv(buffer, RECV_BUFFER_SIZE)) {
            float ux, uy, uz, urx, ury;
            if (sscanf(buffer, "U,%*d,%f,%f,%f,%f,%f",
                &ux, &uy, &uz, &urx, &ury) == 5)
            {
                x = ux; y = uy; z = uz; rx = urx; ry = ury;
                ensure_chunks(chunks, &chunk_count, x, y, z, 1);
                y = highest_block(chunks, chunk_count, x, z) + 2;
            }
            int bp, bq, bx, by, bz, bw;
            if (sscanf(buffer, "B,%d,%d,%d,%d,%d,%d",
                &bp, &bq, &bx, &by, &bz, &bw) == 6)
            {
                _set_block(chunks, chunk_count, bp, bq, bx, by, bz, bw);
                if (player_intersects_block(2, x, y, z, bx, by, bz)) {
                    y = highest_block(chunks, chunk_count, x, z) + 2;
                }
            }
            int pid;
            float px, py, pz, prx, pry;
            if (sscanf(buffer, "P,%d,%f,%f,%f,%f,%f",
                &pid, &px, &py, &pz, &prx, &pry) == 6)
            {
                Player *player = find_player(players, player_count, pid);
                if (!player && player_count < MAX_PLAYERS) {
                    player = players + player_count;
                    player_count++;
                    player->id = pid;
                    player->position_buffer = 0;
                    player->normal_buffer = 0;
                    player->uv_buffer = 0;
                }
                if (player) {
                    update_player(player, px, py, pz, prx, pry);
                }
            }
            if (sscanf(buffer, "D,%d", &pid) == 1) {
                delete_player(players, &player_count, pid);
            }
            if (buffer[0] == 'T' && buffer[1] == ',') {
                char *text = buffer + 2;
                printf("%s\n", text);
                snprintf(
                    messages[message_index], TEXT_BUFFER_SIZE, "%s", text);
                message_index = (message_index + 1) % MAX_MESSAGES;
            }
        }

        int p = chunked(x);
        int q = chunked(z);
        ensure_chunks(chunks, &chunk_count, x, y, z, 0);

        // RENDER 3-D SCENE //

        glClear(GL_COLOR_BUFFER_BIT);
        glClear(GL_DEPTH_BUFFER_BIT);
        set_matrix_3d(matrix, width, height, x, y, z, rx, ry, fov, ortho);

        // render chunks
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, x, y, z);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        for (int i = 0; i < chunk_count; i++) {
            Chunk *chunk = chunks + i;
            if (chunk_distance(chunk, p, q) > RENDER_CHUNK_RADIUS) {
                continue;
            }
            if (y < 100 && !chunk_visible(chunk, matrix)) {
                continue;
            }
            draw_chunk(chunk, position_loc, normal_loc, uv_loc);
        }

        // render players
        for (int i = 0; i < player_count; i++) {
            Player *player = players + i;
            draw_player(player, position_loc, normal_loc, uv_loc);
        }

        // render focused block wireframe
        int hx, hy, hz;
        int hw = hit_test(
            chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz);
        if (is_obstacle(hw)) {
            glUseProgram(line_program);
            glLineWidth(1);
            glEnable(GL_COLOR_LOGIC_OP);
            glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
            GLuint wireframe_buffer = gen_wireframe_buffer(hx, hy, hz, 0.51);
            draw_lines(wireframe_buffer, line_position_loc, 3, 48);
            glDeleteBuffers(1, &wireframe_buffer);
            glDisable(GL_COLOR_LOGIC_OP);
        }

        // RENDER 2-D HUD PARTS //

        glClear(GL_DEPTH_BUFFER_BIT);
        set_matrix_2d(matrix, width, height);

        // render crosshairs
        glUseProgram(line_program);
        glLineWidth(4);
        glEnable(GL_COLOR_LOGIC_OP);
        glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix);
        GLuint crosshair_buffer = gen_crosshair_buffer(width, height);
        draw_lines(crosshair_buffer, line_position_loc, 2, 4);
        glDeleteBuffers(1, &crosshair_buffer);
        glDisable(GL_COLOR_LOGIC_OP);

        // render text
        glUseProgram(text_program);
        glUniformMatrix4fv(text_matrix_loc, 1, GL_FALSE, matrix);
        glUniform1i(text_sampler_loc, 1);
        char text_buffer[1024];
        float ts = 12;
        float tx = ts / 2;
        float ty = height - ts;
        snprintf(
            text_buffer, 1024, "%d, %d, %.2f, %.2f, %.2f [%d, %d]",
            p, q, x, y, z, player_count, chunk_count);
        print(
            text_position_loc, text_uv_loc,
            tx, ty, ts, text_buffer);
        for (int i = 0; i < MAX_MESSAGES; i++) {
            int index = (message_index + i) % MAX_MESSAGES;
            if (strlen(messages[index])) {
                ty -= ts * 2;
                print(
                    text_position_loc, text_uv_loc,
                    tx, ty, ts, messages[index]);
            }
        }
        if (typing) {
            ty -= ts * 2;
            snprintf(text_buffer, 1024, "> %s", typing_buffer);
            print(
                text_position_loc, text_uv_loc,
                tx, ty, ts, text_buffer);
        }

        // RENDER 3-D HUD PARTS //

        set_matrix_item(matrix, width, height);

        // render selected item
        if (block_type != previous_block_type) {
            previous_block_type = block_type;
            if (is_plant(block_type)) {
                gen_plant_buffers(
                    &item_position_buffer, &item_normal_buffer, &item_uv_buffer,
                    0, 0, 0, 0.5, block_type);
            }
            else {
                gen_cube_buffers(
                    &item_position_buffer, &item_normal_buffer, &item_uv_buffer,
                    0, 0, 0, 0.5, block_type);
            }
        }
        glUseProgram(block_program);
        glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix);
        glUniform3f(camera_loc, 0, 0, 5);
        glUniform1i(sampler_loc, 0);
        glUniform1f(timer_loc, glfwGetTime());
        if (is_plant(block_type)) {
            draw_plant(
                item_position_buffer, item_normal_buffer, item_uv_buffer,
                position_loc, normal_loc, uv_loc);
        }
        else {
            draw_cube(
                item_position_buffer, item_normal_buffer, item_uv_buffer,
                position_loc, normal_loc, uv_loc);
        }

        // swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    client_stop();
    db_save_state(x, y, z, rx, ry);
    db_close();
    glfwTerminate();
    return 0;
}
Ejemplo n.º 17
0
int reinit_video_chain(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC));
    init_demux_stream(mpctx, STREAM_VIDEO);
    sh_video_t *sh_video = mpctx->sh_video;
    if (!sh_video)
        goto no_video;

    MP_VERBOSE(mpctx, "[V] fourcc:0x%X  size:%dx%d  fps:%5.3f\n",
               mpctx->sh_video->format,
               mpctx->sh_video->disp_w, mpctx->sh_video->disp_h,
               mpctx->sh_video->fps);
    if (opts->force_fps)
        mpctx->sh_video->fps = opts->force_fps;
    update_fps(mpctx);

    if (!mpctx->sh_video->fps && !opts->force_fps && !opts->correct_pts) {
        MP_ERR(mpctx, "FPS not specified in the "
               "header or invalid, use the -fps option.\n");
    }

    double ar = -1.0;
    //================== Init VIDEO (codec & libvo) ==========================
    if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) {
        mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input,
                                               mpctx->encode_lavc_ctx);
        if (!mpctx->video_out) {
            MP_FATAL(mpctx, "Error opening/initializing "
                    "the selected video_out (-vo) device.\n");
            goto err_out;
        }
        mpctx->mouse_cursor_visible = true;
        mpctx->initialized_flags |= INITIALIZED_VO;
    }

    // dynamic allocation only to make stheader.h lighter
    talloc_free(sh_video->hwdec_info);
    sh_video->hwdec_info = talloc_zero(sh_video, struct mp_hwdec_info);
    vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, sh_video->hwdec_info);

    update_window_title(mpctx, true);

    if (stream_control(mpctx->sh_video->gsh->demuxer->stream,
                       STREAM_CTRL_GET_ASPECT_RATIO, &ar) != STREAM_UNSUPPORTED)
        mpctx->sh_video->stream_aspect = ar;

    recreate_video_filters(mpctx);

    init_best_video_codec(sh_video, opts->video_decoders);

    if (!sh_video->initialized)
        goto err_out;

    mpctx->initialized_flags |= INITIALIZED_VCODEC;

    bool saver_state = opts->pause || !opts->stop_screensaver;
    vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
                                             : VOCTRL_KILL_SCREENSAVER, NULL);

    vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE
                                               : VOCTRL_RESUME, NULL);

    sh_video->last_pts = MP_NOPTS_VALUE;
    sh_video->num_buffered_pts = 0;
    sh_video->next_frame_time = 0;
    mpctx->last_vf_reconfig_count = 0;
    mpctx->restart_playback = true;
    mpctx->sync_audio_to_video = !sh_video->gsh->attached_picture;
    mpctx->delay = 0;
    mpctx->vo_pts_history_seek_ts++;

    vo_seek_reset(mpctx->video_out);
    reset_subtitles(mpctx);

    return 1;

err_out:
no_video:
    uninit_player(mpctx, INITIALIZED_VCODEC | (opts->force_vo ? 0 : INITIALIZED_VO));
    cleanup_demux_stream(mpctx, STREAM_VIDEO);
    mpctx->current_track[STREAM_VIDEO] = NULL;
    handle_force_window(mpctx, true);
    MP_INFO(mpctx, "Video: no video\n");
    return 0;
}
Ejemplo n.º 18
0
int reinit_video_chain(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC));
    assert(!mpctx->d_video);
    struct track *track = mpctx->current_track[0][STREAM_VIDEO];
    struct sh_stream *sh = init_demux_stream(mpctx, track);
    if (!sh)
        goto no_video;

    MP_VERBOSE(mpctx, "[V] fourcc:0x%X  size:%dx%d  fps:%5.3f\n",
               sh->format,
               sh->video->disp_w, sh->video->disp_h,
               sh->video->fps);

    double ar = -1.0;
    //================== Init VIDEO (codec & libvo) ==========================
    if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) {
        mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input,
                                               mpctx->encode_lavc_ctx);
        if (!mpctx->video_out) {
            MP_FATAL(mpctx, "Error opening/initializing "
                     "the selected video_out (-vo) device.\n");
            goto err_out;
        }
        mpctx->mouse_cursor_visible = true;
        mpctx->initialized_flags |= INITIALIZED_VO;
    }

    update_window_title(mpctx, true);

    struct dec_video *d_video = talloc_zero(NULL, struct dec_video);
    mpctx->d_video = d_video;
    d_video->global = mpctx->global;
    d_video->log = mp_log_new(d_video, mpctx->log, "!vd");
    d_video->opts = mpctx->opts;
    d_video->header = sh;
    d_video->fps = sh->video->fps;
    d_video->vo = mpctx->video_out;
    mpctx->initialized_flags |= INITIALIZED_VCODEC;

    vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);

    if (stream_control(sh->demuxer->stream, STREAM_CTRL_GET_ASPECT_RATIO, &ar)
            != STREAM_UNSUPPORTED)
        d_video->stream_aspect = ar;

    recreate_video_filters(mpctx);

    if (!video_init_best_codec(d_video, opts->video_decoders))
        goto err_out;

    bool saver_state = opts->pause || !opts->stop_screensaver;
    vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
               : VOCTRL_KILL_SCREENSAVER, NULL);

    vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE
               : VOCTRL_RESUME, NULL);

    mpctx->restart_playback = true;
    mpctx->sync_audio_to_video = !sh->attached_picture;
    mpctx->delay = 0;
    mpctx->video_next_pts = MP_NOPTS_VALUE;
    mpctx->playing_last_frame = false;
    mpctx->last_frame_duration = 0;
    mpctx->vo_pts_history_seek_ts++;

    vo_seek_reset(mpctx->video_out);
    reset_subtitles(mpctx, 0);
    reset_subtitles(mpctx, 1);

    if (opts->force_fps) {
        d_video->fps = opts->force_fps;
        MP_INFO(mpctx, "FPS forced to be %5.3f.\n", d_video->fps);
    }
    if (!sh->video->fps && !opts->force_fps && !opts->correct_pts) {
        MP_ERR(mpctx, "FPS not specified in the "
               "header or invalid, use the -fps option.\n");
    }
    update_fps(mpctx);

    return 1;

err_out:
no_video:
    uninit_player(mpctx, INITIALIZED_VCODEC | (opts->force_vo ? 0 : INITIALIZED_VO));
    mp_deselect_track(mpctx, track);
    handle_force_window(mpctx, true);
    MP_INFO(mpctx, "Video: no video\n");
    return 0;
}
Ejemplo n.º 19
0
int Game::on_frame(void) {
    // Handle OS events
    float delta_x = 0.0f;
    float delta_y = 0.0f;
    const SystemEvent* event = app_pop_event();
    while (event) {
        switch(event->type) {
            case kEventResize:
                _render->resize(event->data.resize.width, event->data.resize.height);
                printf("W: %d  H: %d\n", event->data.resize.width, event->data.resize.height);
                break;
            case kEventKeyDown:
                if(event->data.key == KEY_ESCAPE)
                    return 1;
                if(event->data.key == KEY_F1)
                    _render->toggle_debug_graphics();
                if(event->data.key == KEY_F2)
                    _render->toggle_deferred();
                break;
            case kEventMouseDown:
                if(event->data.mouse.button == MOUSE_LEFT)
                    app_lock_and_hide_cursor();
                debug_output("Mouse: %.0f %.0f\n", event->data.mouse.x, event->data.mouse.y);
                break;
            case kEventMouseUp:
                if(event->data.mouse.button == MOUSE_LEFT)
                    app_unlock_and_show_cursor();
                break;
            case kEventMouseMove:
                delta_x += event->data.mouse.x;
                delta_y += event->data.mouse.y;
                break;
            default:
                break;
        }
        event = app_pop_event();
    }

    // Beginning of frame stuff
    _delta_time = (float)timer_delta_time(&_timer);
    update_fps(&_fps, _delta_time);

    float3 xaxis = {1.0f, 0.0f, 0.0f};
    quaternion q = quaternionFromAxisAngle(&xaxis, _delta_time*0.15f);
    Transform t = _world.entity(_sun_id)->transform();
    t.orientation = quaternionMultiply(&q, &t.orientation);
    //_world.entity(_sun_id)->set_transform(t);
    if(quaternionGetZAxis(&t.orientation).y > 0.0f) {
        //_world.entity(_sun_id)->deactivate_component(kLightComponent);
    } else {
        //_world.entity(_sun_id)->activate_component(kLightComponent);
    }

    // Frame
    _control_camera(delta_x, delta_y);
    float4x4 view = TransformGetMatrix(&_camera);
    _render->set_3d_view_matrix(view);

    _world.update(_delta_time);

    _render->render();

    // End of frame stuff
    if(++_frame_count % 16 == 0) {
        debug_output("%.2fms (%.0f FPS)\n", get_frametime(&_fps), get_fps(&_fps));
    }
    return 0;
}
Ejemplo n.º 20
0
Archivo: video.c Proyecto: ponyo/mpv
int reinit_video_chain(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    assert(!mpctx->d_video);
    struct track *track = mpctx->current_track[0][STREAM_VIDEO];
    struct sh_stream *sh = track ? track->stream : NULL;
    if (!sh)
        goto no_video;

    MP_VERBOSE(mpctx, "[V] fourcc:0x%X  size:%dx%d  fps:%5.3f\n",
               sh->format,
               sh->video->disp_w, sh->video->disp_h,
               sh->video->fps);

    //================== Init VIDEO (codec & libvo) ==========================
    if (!opts->fixed_vo || !mpctx->video_out) {
        mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input,
                                               mpctx->osd,
                                               mpctx->encode_lavc_ctx);
        if (!mpctx->video_out) {
            MP_FATAL(mpctx, "Error opening/initializing "
                    "the selected video_out (-vo) device.\n");
            mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
            goto err_out;
        }
        mpctx->mouse_cursor_visible = true;
    }

    update_window_title(mpctx, true);

    struct dec_video *d_video = talloc_zero(NULL, struct dec_video);
    mpctx->d_video = d_video;
    d_video->global = mpctx->global;
    d_video->log = mp_log_new(d_video, mpctx->log, "!vd");
    d_video->opts = mpctx->opts;
    d_video->header = sh;
    d_video->fps = sh->video->fps;
    d_video->vo = mpctx->video_out;

    vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);

    recreate_video_filters(mpctx);

    if (!video_init_best_codec(d_video, opts->video_decoders))
        goto err_out;

    bool saver_state = opts->pause || !opts->stop_screensaver;
    vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
                                             : VOCTRL_KILL_SCREENSAVER, NULL);

    vo_set_paused(mpctx->video_out, mpctx->paused);

    mpctx->sync_audio_to_video = !sh->attached_picture;
    mpctx->vo_pts_history_seek_ts++;

    // If we switch on video again, ensure audio position matches up.
    if (mpctx->d_audio)
        mpctx->audio_status = STATUS_SYNCING;

    reset_video_state(mpctx);
    reset_subtitle_state(mpctx);

    if (opts->force_fps) {
        d_video->fps = opts->force_fps;
        MP_INFO(mpctx, "FPS forced to be %5.3f.\n", d_video->fps);
    }
    if (!sh->video->fps && !opts->force_fps && !opts->correct_pts) {
        MP_ERR(mpctx, "FPS not specified in the "
               "header or invalid, use the -fps option.\n");
    }
    update_fps(mpctx);

    return 1;

err_out:
no_video:
    uninit_video_chain(mpctx);
    if (track)
        error_on_track(mpctx, track);
    handle_force_window(mpctx, true);
    return 0;
}
Ejemplo n.º 21
0
/** Preview worker thread.
 * Ensures camera preview is supplied with buffers and sends preview frames to GL.
 * @param arg  Pointer to state.
 * @return NULL always.
 */
static void *preview_worker(void *arg)
{
	RASPITEX_STATE* state = arg;
	MMAL_PORT_T *preview_port = state->preview_port;
	MMAL_BUFFER_HEADER_T *buf;
	MMAL_STATUS_T st;
	int rc;

	vcos_log_trace("%s: port %p", VCOS_FUNCTION, preview_port);

	rc = state->ops.create_native_window(state);

	if (rc != 0)
		goto end;
	else
		vcos_log_info("%s: create_native_window=%d", VCOS_FUNCTION, rc);

	rc = state->ops.gl_init(state);
	
	if (rc != 0)
		goto end;
	else
		vcos_log_info("%s: gl_init=%d", VCOS_FUNCTION, rc);
	
	// -------------------------------------------------------------------------------------
	
	/* Send empty buffers to camera preview port */
	while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL)
		{
		st = mmal_port_send_buffer(preview_port, buf);
		if (st != MMAL_SUCCESS)
			{
			vcos_log_error("Failed to send buffer to %s", preview_port->name);
			}
		}
	
	// -------------------------------------------------------------------------------------
	
	//S_COPY_FRAME_DATA	rec_frame_data;

	while (state->preview_stop == 0)
		{
		/* Send empty buffers to camera preview port */
		/*while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL)
			{
			st = mmal_port_send_buffer(preview_port, buf);
			if (st != MMAL_SUCCESS)
				{
				vcos_log_info("Failed to send buffer to %s", preview_port->name);
				}
			}*/
		
		
		
		//int nLen = mmal_queue_length( state->preview_queue );
		//vcos_log_info("SHIT!!! - LEN=%d", nLen );
		
		//while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL)
		
		
		//if (buf)
		
		int nExistBufferInQueue = 0;
		
		while ((buf = mmal_queue_get(state->preview_queue)) != NULL)
			{
			nExistBufferInQueue = 1;
			
			//vcos_log_info("DATA READ!!!" );
			
			
			rc = raspitex_draw(state, buf);		// block complete chain!!!
			if (rc != 0)
				{
				vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION);
				state->preview_stop = 1;
				}
			
			
			
			st = mmal_port_send_buffer(preview_port, buf);
			if (st != MMAL_SUCCESS)
				{
				vcos_log_info("Failed to send buffer to %s", preview_port->name);
				}
			
			// -------------------------------------------------------------------------------------
			
			//vcos_sleep( 100 );
			
			// now is main chain already free - now can block this thread
			//
			rc = state->ops.safe_redraw(state);
			if (rc != 0)
				{
				vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION);
				state->preview_stop = 1;
				}
			else
				{
				update_fps( );
				}
			
			// -------------------------------------------------------------------------------------
			
			break;
			}
		
		if (!nExistBufferInQueue)	// slow down while cycle otherwise 100% CPU
			{
			vcos_sleep( 10 );
			}
		
		/*if (preview_process_returned_bufs(state) != 0)
			{
			vcos_log_info("SHIT!!!" );
			}
		else
			{
			vcos_log_info("DATA READ!!!" );
			}*/
		
		/*if (begin_read_frame( state->preview_pool->queue, &rec_frame_data ))
			{
			vcos_log_info("DATA READ!!!" );
			
			//if (state->m_nGetData)
				{
				rc = raspitex_draw(state, buf);		// block complete chain!!!
				if (rc != 0)
					{
					vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION);
					state->preview_stop = 1;
					}
				
				
				}
			
			end_read_frame( preview_port, state->preview_pool, &rec_frame_data );
			}
		else
			{
			vcos_log_info("SHIT!!!" );
			}*/
		
		//vcos_sleep( 500 );
		
		/* Process returned buffers */
		/*if (preview_process_returned_bufs(state) != 0)
			{
			vcos_log_error("Preview error. Exiting.");
			state->preview_stop = 1;
			}
		else
			{
			
			}*/
			
		
		}
	
	// -------------------------------------------------------------------------------------

end:
	/* Make sure all buffers are returned on exit */
	while ((buf = mmal_queue_get(state->preview_queue)) != NULL)
		mmal_buffer_header_release(buf);

	/* Tear down GL */
	state->ops.gl_term(state);
	vcos_log_trace("Exiting preview worker");
	
	return NULL;
}
Ejemplo n.º 22
0
/**
 * Draws the next preview frame. If a new preview buffer is available then the
 * preview texture is updated first.
 *
 * @param state RASPITEX STATE
 * @param video_frame MMAL buffer header containing the opaque buffer handle.
 * @return Zero if successful.
 */
static int raspitex_draw(RASPITEX_STATE *state, MMAL_BUFFER_HEADER_T *buf)
{
    int rc = 0;

    /* If buf is non-NULL then there is a new viewfinder frame available
     * from the camera so the texture should be updated.
     *
     * Although it's possible to have multiple textures mapped to different
     * viewfinder frames this can consume a lot of GPU memory for high-resolution
     * viewfinders.
     */
    if (buf)
    {
        /* Update the texture to the new viewfinder image which should */
        if (state->ops.update_texture)
        {
            rc = state->ops.update_texture(state, (EGLClientBuffer) buf->data);
            if (rc != 0)
            {
                vcos_log_error("%s: Failed to update RGBX texture %d",
                               VCOS_FUNCTION, rc);
                goto end;
            }
        }

        if (state->ops.update_y_texture)
        {
            rc = state->ops.update_y_texture(state, (EGLClientBuffer) buf->data);
            if (rc != 0)
            {
                vcos_log_error("%s: Failed to update Y' plane texture %d", VCOS_FUNCTION, rc);
                goto end;
            }
        }

        if (state->ops.update_u_texture)
        {
            rc = state->ops.update_u_texture(state, (EGLClientBuffer) buf->data);
            if (rc != 0)
            {
                vcos_log_error("%s: Failed to update U plane texture %d", VCOS_FUNCTION, rc);
                goto end;
            }
        }

        if (state->ops.update_v_texture)
        {
            rc = state->ops.update_v_texture(state, (EGLClientBuffer) buf->data);
            if (rc != 0)
            {
                vcos_log_error("%s: Failed to update V texture %d", VCOS_FUNCTION, rc);
                goto end;
            }
        }

        /* Now return the PREVIOUS MMAL buffer header back to the camera preview. */
        if (state->preview_buf)
            mmal_buffer_header_release(state->preview_buf);

        state->preview_buf = buf;
    }

    /*  Do the drawing */
    if (check_egl_image(state) == 0)
    {
        rc = state->ops.update_model(state);
        if (rc != 0)
            goto end;

        rc = state->ops.redraw(state);
        if (rc != 0)
            goto end;

        raspitex_do_capture(state);

        eglSwapBuffers(state->display, state->surface);
        update_fps();
    }
    else
    {
        // vcos_log_trace("%s: No preview image", VCOS_FUNCTION);
    }

end:
    return rc;
}