コード例 #1
0
ファイル: gear.c プロジェクト: OCForks/gears2
static int gear_load_shaders(gear_t* self)
{
	assert(self);
	LOGD("debug");

	// face shaders
	self->face_program = a3d_shader_make_source(FACE_VSHADER, FACE_FSHADER);
	if(self->face_program == 0)
		return 0;

	self->face_attribute_vertex = glGetAttribLocation(self->face_program, "vertex");
	self->face_uniform_color    = glGetUniformLocation(self->face_program, "color");
	self->face_uniform_mvp      = glGetUniformLocation(self->face_program, "mvp");

	// outward teeth shaders
	self->outward_program = a3d_shader_make_source(OUTWARD_VSHADER, OUTWARD_FSHADER);
	if(self->outward_program == 0)
		goto fail_outward_program;

	self->outward_attribute_vertex = glGetAttribLocation(self->outward_program, "vertex");
	self->outward_attribute_normal = glGetAttribLocation(self->outward_program, "normal");
	self->outward_uniform_color    = glGetUniformLocation(self->outward_program, "color");
	self->outward_uniform_nm       = glGetUniformLocation(self->outward_program, "nm");
	self->outward_uniform_mvp      = glGetUniformLocation(self->outward_program, "mvp");

	// cylinder shaders
	self->cylinder_program = a3d_shader_make_source(CYLINDER_VSHADER, CYLINDER_FSHADER);
	if(self->cylinder_program == 0)
		goto fail_cylinder_program;

	self->cylinder_attribute_vertex = glGetAttribLocation(self->cylinder_program, "vertex");
	self->cylinder_attribute_normal = glGetAttribLocation(self->cylinder_program, "normal");
	self->cylinder_uniform_color    = glGetUniformLocation(self->cylinder_program, "color");
	self->cylinder_uniform_nm       = glGetUniformLocation(self->cylinder_program, "nm");
	self->cylinder_uniform_mvp      = glGetUniformLocation(self->cylinder_program, "mvp");

	GLenum e = A3D_GL_GETERROR();
	if(e != GL_NO_ERROR)
		goto fail_error;

	// success
	return 1;

	// failure
	fail_error:
		glDeleteProgram(self->cylinder_program);
	fail_cylinder_program:
		glDeleteProgram(self->outward_program);
	fail_outward_program:
		glDeleteProgram(self->face_program);
	return 0;
}
コード例 #2
0
ファイル: lzs_renderer.c プロジェクト: jeffboody/LaserShark
void lzs_renderer_draw(lzs_renderer_t* self)
{
    assert(self);
    LOGD("debug");

    double t0 = a3d_utime();

    // stretch screen to 800x480
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0.0f, SCREEN_W, SCREEN_H, 0.0f, 0.0f, 2.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // draw camera
    glEnable(GL_TEXTURE_EXTERNAL_OES);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, self->texid);
    glVertexPointer(3, GL_FLOAT, 0, VERTEX);
    glTexCoordPointer(2, GL_FLOAT, 0, COORDS);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_EXTERNAL_OES);
    utime_update("setup", &t0);

    // capture buffers
    GLint format = TEXGZ_BGRA;
    GLint type   = GL_UNSIGNED_BYTE;
    glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &format);
    glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &type);
    if((format == TEXGZ_BGRA) && (type == GL_UNSIGNED_BYTE))
    {
        LOGD("readpixels format=0x%X, type=0x%X", format, type);

        // TODO - check for texgz errors

        // process buffers
        texgz_tex_t* bc  = self->buffer_color;
        texgz_tex_t* bg  = self->buffer_gray;
        texgz_tex_t* bsx = self->buffer_sx;
        texgz_tex_t* bsy = self->buffer_sy;
        glReadPixels(self->sphero_x - RADIUS_BALL, (SCREEN_H - self->sphero_y - 1) - RADIUS_BALL,
                     bc->width, bc->height, bc->format, bc->type, (void*) bc->pixels);
#ifdef DEBUG_BUFFERS
        texgz_tex_export(bc, "/sdcard/laser-shark/color.texgz");
#endif
        utime_update("readpixels", &t0);

        texgz_tex_computegray(bc, bg);
        utime_update("computegray", &t0);

        texgz_tex_computeedges3x3(bg, bsx, bsy);
        utime_update("computeedges", &t0);

        // compute peak
        {
            int    x;
            int    y;
            int    peak_x  = 0;
            int    peak_y  = 0;
            float  peak    = 0.0f;
            float* gpixels = (float*) bg->pixels;
            float* xpixels = (float*) bsx->pixels;
            float* ypixels = (float*) bsy->pixels;
            for(x = 0; x < bg->width; ++x)
            {
                for(y = 0; y < bg->height; ++y)
                {
                    int idx      = bg->width*y + x;
                    // compute magnitude squared
                    float magsq = xpixels[idx]*xpixels[idx] + ypixels[idx]*ypixels[idx];
                    gpixels[idx] = magsq;
                    if(magsq > peak)
                    {
                        peak_x = x;
                        peak_y = y;
                        peak   = magsq;
                    }
                }
            }
            LOGD("peak=%f, peak_x=%i, peak_y=%i", peak, peak_x, peak_y);
            utime_update("computepeak", &t0);
#ifdef DEBUG_BUFFERS
            texgz_tex_export(bg, "/sdcard/laser-shark/peak.texgz");
#endif

            // move sphero center to match peak
            self->sphero_x += (float) peak_x - (float) bg->width / 2.0f;
            self->sphero_y -= (float) peak_y - (float) bg->height / 2.0f;
        }
    }
    else
    {
        LOGE("unsupported format=0x%X, type=0x%X", format, type);
    }

    // compute phone X, Y center
    compute_position(self, SCREEN_CX, SCREEN_CY, &self->phone_X, &self->phone_Y);

    // compute sphero X, Y
    compute_position(self, self->sphero_x, self->sphero_y, &self->sphero_X, &self->sphero_Y);
    utime_update("computeposition", &t0);

    // compute goal
    float dx           = self->phone_X - self->sphero_X;
    float dy           = self->phone_Y - self->sphero_Y;
    float a            = fix_angle(atan2f(dx, dy) * 180.0f / M_PI);
    self->sphero_goal  = a - self->sphero_heading_offset;

    // compute speed
    float dotp = cosf((a - self->sphero_heading) * M_PI / 180.0f);
    if(dotp > 0.0f)
    {
        // linearly interpolate speed based on the turning angle
        self->sphero_speed = SPEED_MAX*dotp + SPEED_MIN*(1.0f - dotp);
    }
    else
    {
        // go slow to turn around
        self->sphero_speed = SPEED_MIN;
    }

    // draw camera cross-hair
    {
        float x = SCREEN_CX;
        float y = SCREEN_CY;
        float r = RADIUS_CROSS;
        limit_position(r, &x, &y);
        lzs_renderer_crosshair(y - r, x - r, y + r, x + r, 1.0f, 0.0f, 0.0f);
    }

    // draw sphero search box
    {
        float r = RADIUS_BALL;
        limit_position(r, &self->sphero_x, &self->sphero_y);
        float x = self->sphero_x;
        float y = self->sphero_y;
        lzs_renderer_drawbox(y - r, x - r, y + r, x + r, 0.0f, 1.0f, 0.0f, 0);
    }

    lzs_renderer_step(self);

    // draw string
    a3d_texstring_printf(self->string_sphero, "sphero: head=%i, x=%0.1f, y=%0.1f, spd=%0.2f, goal=%i", (int) fix_angle(self->sphero_heading + self->sphero_heading_offset), self->sphero_X, self->sphero_Y, self->sphero_speed, (int) fix_angle(self->sphero_goal));
    a3d_texstring_printf(self->string_phone, "phone: heading=%i, slope=%i, x=%0.1f, y=%0.1f", (int) fix_angle(self->phone_heading), (int) fix_angle(self->phone_slope), self->phone_X, self->phone_Y);
    a3d_texstring_draw(self->string_sphero, 400.0f, 16.0f, 800, 480);
    a3d_texstring_draw(self->string_phone,  400.0f, 16.0f + self->string_sphero->size, 800, 480);
    a3d_texstring_draw(self->string_fps, (float) SCREEN_W - 16.0f, (float) SCREEN_H - 16.0f, SCREEN_W, SCREEN_H);
    utime_update("draw", &t0);

    //texgz_tex_t* screen = texgz_tex_new(SCREEN_W, SCREEN_H, SCREEN_W, SCREEN_H, TEXGZ_UNSIGNED_BYTE, TEXGZ_BGRA, NULL);
    //glReadPixels(0, 0, screen->width, screen->height, screen->format, screen->type, (void*) screen->pixels);
    //texgz_tex_export(screen, "/sdcard/laser-shark/screen.texgz");
    //texgz_tex_delete(&screen);

    A3D_GL_GETERROR();
}
コード例 #3
0
ファイル: gear.c プロジェクト: OCForks/gears2
/***********************************************************
*  Generate a gear wheel.                                  *
*                                                          *
*  Input:  inner_radius - radius of hole at center         *
*          outer_radius - radius at center of teeth        *
*          width - width of gear                           *
*          teeth - number of teeth                         *
*          tooth_depth - depth of tooth                    *
***********************************************************/
static int gear_generate(gear_t* self,
                         float inner_radius, float outer_radius, float width,
                         int teeth, float tooth_depth)
{
	assert(self);
	LOGD("debug");

	a3d_glsm_t* glsm = a3d_glsm_new();
	if(glsm == NULL)
	{
		return 0;
	}

	int i;
	float r0, r1, r2, dz;
	float a0, a1, a2, a3;
	float u, v, len;
	
	r0 = inner_radius;
	r1 = outer_radius - tooth_depth / 2.0f;
	r2 = outer_radius + tooth_depth / 2.0f;
	dz = 0.5f * width;

	// TODO - generate texture coordinates for "shinny"

	// draw front face
	// GL_TRIANGLE_STRIP
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), dz);
		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), dz);
	}
	a3d_glsm_vertex3f(glsm, r0 * cosf(0.0f), r0 * sinf(0.0f), dz);
	a3d_glsm_vertex3f(glsm, r1 * cosf(0.0f), r1 * sinf(0.0f), dz);
	a3d_glsm_end(glsm);

	// buffer front face
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->front_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->front_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);

	// draw front sides of teeth
	// GL_TRIANGLES
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), dz);   // 0
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), dz);   // 1
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), dz);   // 2

		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), dz);   // 0
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), dz);   // 2
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), dz);   // 3
	}
	a3d_glsm_end(glsm);

	// buffer front sides of teeth
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->front_teeth_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->front_teeth_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);

	// draw back face
	// GL_TRIANGLE_STRIP
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), -dz);
		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), -dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), -dz);
		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), -dz);
	}
	a3d_glsm_vertex3f(glsm, r1 * cosf(0.0f), r1 * sinf(0.0f), -dz);
	a3d_glsm_vertex3f(glsm, r0 * cosf(0.0f), r0 * sinf(0.0f), -dz);
	a3d_glsm_end(glsm);

	// buffer back face
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->back_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->back_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);

	// draw back sides of teeth
	// GL_TRIANGLES
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), -dz);   // 0
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), -dz);   // 1
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), -dz);   // 2

		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), -dz);   // 0
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), -dz);   // 2
		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), -dz);   // 3
	}
	a3d_glsm_end(glsm);

	// buffer back sides of teeth
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->back_teeth_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->back_teeth_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);

	// draw outward faces of teeth
	// GL_TRIANGLE_STRIP
	// repeated vertices are necessary to achieve flat shading in ES2
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		if(i > 0)
		{
			a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), dz);
			a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), -dz);
		}

		u = r2 * cosf(a1) - r1 * cosf(a0);
		v = r2 * sinf(a1) - r1 * sinf(a0);
		len = sqrtf(u * u + v * v);
		u /= len;
		v /= len;

		a3d_glsm_normal3f(glsm, v, -u, 0.0f);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a0), r1 * sinf(a0), -dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), -dz);

		a3d_glsm_normal3f(glsm, cosf(a0), sinf(a0), 0.0f);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a1), r2 * sinf(a1), -dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), -dz);

		u = r1 * cosf(a3) - r2 * cosf(a2);
		v = r1 * sinf(a3) - r2 * sinf(a2);

		a3d_glsm_normal3f(glsm, v, -u, 0.0f);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), dz);
		a3d_glsm_vertex3f(glsm, r2 * cosf(a2), r2 * sinf(a2), -dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), -dz);

		a3d_glsm_normal3f(glsm, cosf(a0), sinf(a0), 0.0f);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), dz);
		a3d_glsm_vertex3f(glsm, r1 * cosf(a3), r1 * sinf(a3), -dz);
	}
	a3d_glsm_vertex3f(glsm, r1 * cosf(0.0f), r1 * sinf(0.0f), dz);
	a3d_glsm_vertex3f(glsm, r1 * cosf(0.0f), r1 * sinf(0.0f), -dz);
	a3d_glsm_end(glsm);

	// buffer outward faces of teeth
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->outward_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->outward_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, self->outward_nid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->nb, GL_STATIC_DRAW);

	// draw inside radius cylinder
	// GL_TRIANGLE_STRIP
	a3d_glsm_begin(glsm);
	for(i = 0; i < teeth; i++)
	{
		gear_angle(i, teeth, &a0, &a1, &a2, &a3);

		a3d_glsm_normal3f(glsm, -cosf(a0), -sinf(a0), 0.0f);
		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), -dz);
		a3d_glsm_vertex3f(glsm, r0 * cosf(a0), r0 * sinf(a0), dz);
	}
	a3d_glsm_normal3f(glsm, -cosf(0.0f), -sinf(0.0f), 0.0f);
	a3d_glsm_vertex3f(glsm, r0 * cosf(0.0f), r0 * sinf(0.0f), -dz);
	a3d_glsm_vertex3f(glsm, r0 * cosf(0.0f), r0 * sinf(0.0f), dz);
	a3d_glsm_end(glsm);

	// buffer inside radius cylinder
	if(a3d_glsm_status(glsm) != A3D_GLSM_COMPLETE) goto fail;
	self->cylinder_ec = glsm->ec;
	glBindBuffer(GL_ARRAY_BUFFER, self->cylinder_vid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->vb, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, self->cylinder_nid);
	glBufferData(GL_ARRAY_BUFFER, 3 * glsm->ec * sizeof(GLfloat), glsm->nb, GL_STATIC_DRAW);

	GLenum e = A3D_GL_GETERROR();
	if(e != GL_NO_ERROR)
		goto fail;

	// success
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	a3d_glsm_delete(&glsm);
	return 1;

	// failure
	fail:
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		a3d_glsm_delete(&glsm);
	return 0;
}