Пример #1
0
static void a3d_sprite_draw(a3d_widget_t* widget)
{
	assert(widget);
	LOGD("debug");

	a3d_sprite_t* self   = (a3d_sprite_t*) widget;
	a3d_screen_t* screen = widget->screen;
	a3d_mat4f_t   mvp;

	// draw sprite
	a3d_vec4f_t* c     = &self->color;
	float        alpha = widget->fade*c->a;
	if(alpha > 0.0f)
	{
		float w  = 0.0f;
		float h  = 0.0f;
		float x  = widget->rect_draw.l;
		float y  = widget->rect_draw.t;
		float ww = widget->rect_draw.w;
		float hh = widget->rect_draw.h;
		a3d_screen_sizef(screen, &w, &h);
		a3d_mat4f_ortho(&mvp, 1, 0.0f, w, h, 0.0f, 0.0f, 2.0f);
		a3d_mat4f_translate(&mvp, 0, x + ww/2.0f, y + hh/2.0f, -1.0f);
		a3d_mat4f_scale(&mvp, 0, ww, hh, 1.0f);
		a3d_mat4f_rotate(&mvp, 0, self->theta, 0.0f, 0.0f, 1.0f);

		a3d_spriteShader_t* shader = a3d_screen_spriteShader(screen);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glUseProgram(shader->prog);
		glEnableVertexAttribArray(shader->attr_vertex);
		glEnableVertexAttribArray(shader->attr_coords);
		glBindTexture(GL_TEXTURE_2D, self->id_tex[self->index]);
		glBindBuffer(GL_ARRAY_BUFFER, self->id_vertex);
		glVertexAttribPointer(shader->attr_vertex, 4, GL_FLOAT, GL_FALSE, 0, 0);
		glBindBuffer(GL_ARRAY_BUFFER, self->id_coords);
		glVertexAttribPointer(shader->attr_coords, 2, GL_FLOAT, GL_FALSE, 0, 0);
		glUniform4f(shader->unif_color, c->r, c->g, c->b, alpha);
		glUniformMatrix4fv(shader->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp);
		glUniform1i(shader->unif_sampler, 0);
		glDrawArrays(GL_TRIANGLES, 0, 6);
		glBindTexture(GL_TEXTURE_2D, 0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glDisableVertexAttribArray(shader->attr_coords);
		glDisableVertexAttribArray(shader->attr_vertex);
		glUseProgram(0);
		glDisable(GL_BLEND);
	}
}
Пример #2
0
void a3d_mat4f_orthonormal_copy(const a3d_mat4f_t* self, a3d_mat4f_t* copy)
{
	assert(self);
	assert(copy);
	LOGD("debug");

	/*
	 * perform modified Gram-Schmitt ortho-normalization
	 */

	a3d_vec4f_t v0 = { .x = self->m00, .y = self->m01, .z = self->m02, .w = self->m03 };
	a3d_vec4f_t v1 = { .x = self->m10, .y = self->m11, .z = self->m12, .w = self->m13 };
	a3d_vec4f_t v2 = { .x = self->m20, .y = self->m21, .z = self->m22, .w = self->m23 };
	a3d_vec4f_t v3 = { .x = self->m30, .y = self->m31, .z = self->m32, .w = self->m33 };

	// normalize u0
	a3d_vec4f_t u0;
	a3d_vec4f_normalize_copy(&v0, &u0);

	// subtract the component of v1 in the direction of u0
	// normalize u1
	a3d_vec4f_t u1;
	a3d_vec4f_t projuv;
	a3d_mat4f_projuv(&u0, &v1, &projuv);
	a3d_vec4f_subv_copy(&v1, &projuv, &u1);
	a3d_vec4f_normalize(&u1);

	// subtract the component of v2 in the direction of u1
	// subtract the component of u2 in the direction of u0
	// normalize u2
	a3d_vec4f_t u2;
	a3d_mat4f_projuv(&u1, &v2, &projuv);
	a3d_vec4f_subv_copy(&v2, &projuv, &u2);
	a3d_mat4f_projuv(&u0, &u2, &projuv);
	a3d_vec4f_subv(&u2, &projuv);
	a3d_vec4f_normalize(&u2);

	// subtract the component of v3 in the direction of u2
	// subtract the component of u3 in the direction of u1
	// subtract the component of u3 in the direction of u0
	// normalize u3
	a3d_vec4f_t u3;
	a3d_mat4f_projuv(&u2, &v3, &projuv);
	a3d_vec4f_subv_copy(&v3, &projuv, &u3);
	a3d_mat4f_projuv(&u1, &u3, &projuv);
	a3d_vec4f_subv(&u3, &projuv);
	a3d_mat4f_projuv(&u0, &u3, &projuv);
	a3d_vec4f_subv(&u3, &projuv);
	a3d_vec4f_normalize(&u3);

	// copy the orthonormal vectors
	copy->m00 = u0.x;
	copy->m01 = u0.y;
	copy->m02 = u0.z;
	copy->m03 = u0.w;
	copy->m10 = u1.x;
	copy->m11 = u1.y;
	copy->m12 = u1.z;
	copy->m13 = u1.w;
	copy->m20 = u2.x;
	copy->m21 = u2.y;
	copy->m22 = u2.z;
	copy->m23 = u2.w;
	copy->m30 = u3.x;
	copy->m31 = u3.y;
	copy->m32 = u3.z;
	copy->m33 = u3.w;
}

/*
 * quaternion operations
 */

void a3d_mat4f_rotateq(a3d_mat4f_t* self, int load,
                       const a3d_quaternion_t* q)
{
	assert(self);
	assert(q);
	LOGD("debug load=%i", load);

	float x2 = q->v.x*q->v.x;
	float y2 = q->v.y*q->v.y;
	float z2 = q->v.z*q->v.z;
	float xy = q->v.x*q->v.y;
	float xz = q->v.x*q->v.z;
	float yz = q->v.y*q->v.z;
	float xw = q->v.x*q->s;
	float yw = q->v.y*q->s;
	float zw = q->v.z*q->s;

	// requires normalized quaternions
	a3d_mat4f_t m =
	{
		1.0f - 2.0f*(y2 + z2), 2.0f*(xy - zw), 2.0f*(xz + yw), 0.0f,
		2.0f*(xy + zw), 1.0f - 2.0f*(x2 + z2), 2.0f*(yz - xw), 0.0f,
		2.0f*(xz - yw), 2.0f*(yz + xw), 1.0f - 2.0f*(x2 + y2), 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f,
	};

	if(load)
		a3d_mat4f_copy(&m, self);
	else
		a3d_mat4f_mulm(self, &m);
}

/*
 * GL matrix operations
 */

void a3d_mat4f_lookat(a3d_mat4f_t* self, int load,
                      GLfloat eyex, GLfloat eyey, GLfloat eyez,
                      GLfloat centerx, GLfloat centery, GLfloat centerz,
                      GLfloat upx, GLfloat upy, GLfloat upz)
{
	assert(self);
	LOGD("debug load=%i, eye=(%f,%f,%f), center=(%f,%f,%f), up=(%f,%f,%f)",
	     load, eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);

	a3d_vec3f_t eye =
	{
		eyex, eyey, eyez
	};

	a3d_vec3f_t center =
	{
		centerx, centery, centerz
	};

	a3d_vec3f_t up =
	{
		upx, upy, upz
	};

	a3d_vec3f_t n;
	a3d_vec3f_subv_copy(&center, &eye, &n);
	a3d_vec3f_normalize(&n);
	a3d_vec3f_normalize(&up);

	a3d_vec3f_t u;
	a3d_vec3f_t v;
	a3d_vec3f_cross_copy(&n, &up, &u);
	a3d_vec3f_cross_copy(&u, &n, &v);
	a3d_vec3f_normalize(&u);
	a3d_vec3f_normalize(&v);

	a3d_mat4f_t m =
	{
		 u.x,  v.x, -n.x, 0.0f,
		 u.y,  v.y, -n.y, 0.0f,
		 u.z,  v.z, -n.z, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f,
	};
	a3d_mat4f_translate(&m, 0, -eye.x, -eye.y, -eye.z);

	if(load)
		a3d_mat4f_copy(&m, self);
	else
		a3d_mat4f_mulm(self, &m);
}

void a3d_mat4f_perspective(a3d_mat4f_t* self, int load,
                           GLfloat fovy, GLfloat aspect,
                           GLfloat znear, GLfloat zfar)
{
	assert(self);
	LOGD("debug load=%i, fovy=%f, aspect=%f, znear=%f, zfar=%f",
	     load, fovy, aspect, znear, zfar);

	GLfloat f   = 1.0f/tanf(fovy*(M_PI/180.0f)/2.0f);
	GLfloat m00 = f/aspect;
	GLfloat m11 = f;
	GLfloat m22 = (zfar + znear)/(znear - zfar);
	GLfloat m23 = (2.0f*zfar*znear)/(znear - zfar);

	a3d_mat4f_t m =
	{
		 m00, 0.0f, 0.0f,  0.0f,
		0.0f,  m11, 0.0f,  0.0f,
		0.0f, 0.0f,  m22, -1.0f,
		0.0f, 0.0f,  m23,  0.0f,
	};

	if(load)
		a3d_mat4f_copy(&m, self);
	else
		a3d_mat4f_mulm(self, &m);
}

void a3d_mat4f_perspectiveStereo(a3d_mat4f_t* pmL,
                                 a3d_mat4f_t* pmR,
                                 int load,
                                 GLfloat fovy, GLfloat aspect,
                                 GLfloat znear, GLfloat zfar,
                                 GLfloat convergence,
                                 GLfloat eye_separation)
{
	assert(pmL);
	assert(pmR);

	// http://www.animesh.me/2011/05/rendering-3d-anaglyph-in-opengl.html

	GLfloat tan_fovy2 = tanf(fovy*(M_PI/180.0f)/2.0f);
	GLfloat es2       = eye_separation/2.0f;
	GLfloat top       = znear*tan_fovy2;
	GLfloat bottom    = -top;
	GLfloat a         = aspect*tan_fovy2*convergence;
	GLfloat b         = a - es2;
	GLfloat c         = a + es2;
	GLfloat d         = znear/convergence;
	GLfloat left      = -b*d;
	GLfloat right     =  c*d;

	// left perspective matrix
	a3d_mat4f_frustum(pmL, load,
	                  left, right,
	                  bottom, top,
	                  znear, zfar);

	// right perspective matrix
	left  = -c*d;
	right =  b*d;
	a3d_mat4f_frustum(pmR, load,
	                  left, right,
	                  bottom, top,
	                  znear, zfar);
}