Beispiel #1
0
static void ddRenderVecs(const mat4& projview)
{
	const ShaderInfo* shader = g_dbgdrawShader.get();
	GLint posLoc = shader->m_attrs[GEOM_Pos];
	GLint colorLoc = shader->m_attrs[GEOM_Color];
	GLint mvpLoc = shader->m_uniforms[BIND_Mvp];
	glUniformMatrix4fv(mvpLoc, 1, 0, projview.m);

	const ddVec* cur = g_lists.m_vecs;
	if(cur) 
	{	
		glBegin(GL_LINES);
		while(cur)
		{
			vec3 from = TransformPoint(cur->m_xfm, cur->m_from);
			vec3 to = TransformPoint(cur->m_xfm, cur->m_from + cur->m_vec);

			glVertexAttrib3fv(colorLoc, &cur->m_color.r);
			glVertexAttrib3fv(posLoc, &from.x);
			glVertexAttrib3fv(posLoc, &to.x);
			cur = cur->m_next;
		}
		glEnd();
	}
}
Beispiel #2
0
void Shader::use(bool forceReload) {
	static Shader *previousShader = NULL;
	if (this == previousShader && !forceReload)
		return;
	previousShader = this;

	glUseProgram(*_shaderNo);
	for (uint32 i = 0; i < _attributes.size(); ++i) {
		Graphics::VertexAttrib &attrib = _attributes[i];
		if (attrib._enabled) {
			glEnableVertexAttribArray(i);
			glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo);
			glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, (const GLvoid *)attrib._offset);
		} else {
			glDisableVertexAttribArray(i);
			switch (attrib._size) {
			case 2:
				glVertexAttrib2fv(i, attrib._const);
				break;
			case 3:
				glVertexAttrib3fv(i, attrib._const);
				break;
			case 4:
				glVertexAttrib4fv(i, attrib._const);
				break;
			}
		}
	}
}
Beispiel #3
0
void drawBumpPlate(float size, int nRepeatS, int nRepeatT)
{//x-y平面
	float tnt[3];
	float s, t;
	float sz = 0.5 * size;
	static float p[4][3] = //z:上方向
	{ 
		{ sz, sz, 0.0}, {-sz, sz, 0.0}, 
		{-sz,-sz, 0.0}, { sz,-sz, 0.0}
	};

	s = (float)nRepeatS;
	t = (float)nRepeatT;
  GLuint tangentLoc = glGetAttribLocation(shaderProg, "tangent");
  glEnable(GL_TEXTURE_2D);
	glBegin(GL_QUADS);
		tnt[0] = 1.0; tnt[1] = 0.0; tnt[2] = 0.0;
		glVertexAttrib3fv(tangentLoc, tnt);
		glNormal3f(0.0, 0.0, 1.0); //z方向の法線
		//テクスチャー座標と頂点番号との対応付け
		glTexCoord2f(0.0, 0.0); glVertex3fv(p[2]);
		glTexCoord2f( s , 0.0); glVertex3fv(p[3]);
		glTexCoord2f( s ,  t ); glVertex3fv(p[0]);
		glTexCoord2f(0.0,  t ); glVertex3fv(p[1]);
	glEnd();
	glDisable(GL_TEXTURE_2D);
}
Beispiel #4
0
void draw_trinagle_face(const float A[], const float B[], const float C[], float normal[3], float r = 1.0f, float g = 1.0f, float b = 1.0f) {
   glBegin(GL_TRIANGLES);
      glVertexAttrib3f(GLT_ATTRIBUTE_COLOR, r, g, b);
      glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normal);
      glVertex3fv(A);
      glVertex3fv(B);
      glVertex3fv(C);
   glEnd();
}
Beispiel #5
0
void floor_tr_normal(const float A[], const float B[], const float C[], float normalVector[3], float r = 1.0f, float g = 1.0f, float b = 1.0f) {
   glBegin(GL_TRIANGLES);
  	glVertexAttrib3f(GLT_ATTRIBUTE_COLOR, r, g, b);
  	glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normalVector);
  	glVertex3fv(A);
  	glVertex3fv(B);
  	glVertex3fv(C);
   glEnd();
}
void
GLSLProgram::SetAttributeVariable(char* name, float vals[3])
{
	int loc;
	if ((loc = GetAttributeLocation(name)) >= 0)
	{
		this->Use();
		glVertexAttrib3fv(loc, vals);
	}
};
Beispiel #7
0
	bool ShaderManager :: SetAttributeVector ( const char * name, const Vector3D& value )
	{
		int location = glGetAttribLocation ( Program, name );

		if ( location < 0 )
			return false;

		glVertexAttrib3fv ( location, value );

		return true;
	}
Beispiel #8
0
//----------------------------------------------------
void TriangleFace(M3DVector3f a, M3DVector3f b, M3DVector3f c) {
   M3DVector3f normal, bMa, cMa;
   m3dSubtractVectors3(bMa, b, a);
   m3dSubtractVectors3(cMa, c, a);
   m3dCrossProduct3(normal, bMa, cMa);
   m3dNormalizeVector3(normal);
   glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normal);
   glVertex3fv(a);
   glVertex3fv(b);
   glVertex3fv(c);
}
Beispiel #9
0
void Shader::SetAttribute(const char* var, float* v, int size)
{
	int id = GetAttributeId(var);
	if(id >= 0)
	{
		if(size == 2)
			glVertexAttrib2fv(id, v);
		else if(size == 3)
			glVertexAttrib3fv(id, v);
		else if(size == 4)
			glVertexAttrib4fv(id, v);
	}
}
void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count)
{
    // this will only get called if we can't acquire a persistently mapped buffer.
#ifndef CORE_PROFILE
    glBegin(primtype);
    for (unsigned int i = 0; i < count; i++)
    {
        glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u);
        glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x);
    }
    glEnd();
#endif
}
Beispiel #11
0
//----------------------------------------------------
void drawSmoothTriangles(int n_faces, float *vertices, int *faces) {
    M3DVector3f normal;
    for (int i = 0; i < n_faces; i++) {
		glBegin(GL_TRIANGLES);
    	for(int j=0;j<3;++j) {
			m3dCopyVector3(normal,vertices+3*faces[i*3+j]);
			m3dNormalizeVector3(normal);
    		glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normal);
    		glVertex3fv(vertices+3*faces[i*3+j]);
		}
    glEnd();
    }
}
Beispiel #12
0
/*
 * Specify a vertex to opengl with texCoords, tangent, normal and position
 */
void Sphere::drawVertex(int i, int j, GLuint tgLoc, GLuint tcoordsLoc) const
{
    if (tgLoc != 0) {
        glVertexAttrib3fv(tgLoc, &_tangents[ 3*(j*(_vDivs+1) + i) ]);
    }

    if (tcoordsLoc != 0) {
        glVertexAttrib2fv(tcoordsLoc, &_texcoords[2*(j*(_vDivs+1) + i) ]);
    }

    glNormal3fv(&_normals[ 3*(j*(_vDivs+1) + i) ]);
    glVertex3fv(&_vertexs[ 3*(j*(_vDivs+1) + i) ]);
}
Beispiel #13
0
static void ddRenderPoints(const mat4& projview)
{
	const ShaderInfo* shader = g_dbgdrawShader.get();
	GLint posLoc = shader->m_attrs[GEOM_Pos];
	GLint colorLoc = shader->m_attrs[GEOM_Color];
	GLint mvpLoc = shader->m_uniforms[BIND_Mvp];
	glUniformMatrix4fv(mvpLoc, 1, 0, projview.m);

	const ddPoint* cur = g_lists.m_points;
	if(cur) 
	{	
		glPointSize(4.f);
		glBegin(GL_POINTS);
		while(cur)
		{
			vec3 pt = TransformPoint(cur->m_xfm, cur->m_point);
			glVertexAttrib3fv(colorLoc, &cur->m_color.r);
			glVertexAttrib3fv(posLoc, &pt.x);
			cur = cur->m_next;
		}
		glEnd();
	}
}
Beispiel #14
0
enum piglit_result
piglit_display(void)
{
    float color[4][4] = {
        {1, 0, 0, 1},
        {0, 1, 0, 1},
        {0, 0, 1, 1},
        {1, 1, 1, 1},
    };
    bool pass = true;

    glViewport(0, 0, piglit_width, piglit_height);
    glClearColor(0.5, 0.5, 0.5, 0.5);
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexAttrib1fv(attr, color[0]);
    glViewport(0, 0, piglit_width/2, piglit_height/2);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glVertexAttrib2fv(attr, color[1]);
    glViewport(0, piglit_height/2, piglit_width/2, piglit_height/2);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glVertexAttrib3fv(attr, color[2]);
    glViewport(piglit_width/2, 0, piglit_width/2, piglit_height/2);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glVertexAttrib4fv(attr, color[3]);
    glViewport(piglit_width/2, piglit_height/2,
               piglit_width/2, piglit_height/2);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    pass &= piglit_probe_rect_rgba(0, 0,
                                   piglit_width / 2, piglit_height / 2,
                                   color[0]);
    pass &= piglit_probe_rect_rgba(0, piglit_height / 2,
                                   piglit_width / 2, piglit_height / 2,
                                   color[1]);
    pass &= piglit_probe_rect_rgba(piglit_width / 2, 0,
                                   piglit_width / 2, piglit_height / 2,
                                   color[2]);
    pass &= piglit_probe_rect_rgba(piglit_width / 2, piglit_height / 2,
                                   piglit_width / 2, piglit_height / 2,
                                   color[3]);

    piglit_present_results();

    return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
	void AttributeVariable::set(GLfloat * fv_, int param_, int count_)
	{
		switch(param_)
		{
		case 1: { glVertexAttrib1fv(_location, fv_); }
						break;
		case 2: { glVertexAttrib2fv(_location, fv_); }
						break;
		case 3: { glVertexAttrib3fv(_location, fv_); }
						break;
		case 4: { glVertexAttrib4fv(_location, fv_); }
						break;
		default:
			break;
		}
	}
static void
setup_generic_const_attribute (CoglContext *context,
                               CoglPipeline *pipeline,
                               CoglAttribute *attribute)
{
  int name_index = attribute->name_state->name_index;
  int attrib_location =
    _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index);
  int columns;
  int i;

  if (attrib_location == -1)
    return;

  if (attribute->d.constant.boxed.type == COGL_BOXED_MATRIX)
    columns = attribute->d.constant.boxed.size;
  else
    columns = 1;

  /* Note: it's ok to access a COGL_BOXED_FLOAT as a matrix with only
   * one column... */

  switch (attribute->d.constant.boxed.size)
    {
    case 1:
      GE( context, glVertexAttrib1fv (attrib_location,
                                      attribute->d.constant.boxed.v.matrix));
      break;
    case 2:
      for (i = 0; i < columns; i++)
        GE( context, glVertexAttrib2fv (attrib_location + i,
                                        attribute->d.constant.boxed.v.matrix));
      break;
    case 3:
      for (i = 0; i < columns; i++)
        GE( context, glVertexAttrib3fv (attrib_location + i,
                                        attribute->d.constant.boxed.v.matrix));
      break;
    case 4:
      for (i = 0; i < columns; i++)
        GE( context, glVertexAttrib4fv (attrib_location + i,
                                        attribute->d.constant.boxed.v.matrix));
      break;
    default:
      g_warn_if_reached ();
    }
}
Beispiel #17
0
void Shader::use(bool forceReload) {
	static Shader *previousShader = nullptr;
	static uint32 previousNumAttributes = 0;
	if (this == previousShader && !forceReload)
		return;

	// The previous shader might have had more attributes. Disable any extra ones.
	if (_attributes.size() < previousNumAttributes) {
		for (uint32 i = _attributes.size(); i < previousNumAttributes; ++i) {
			glDisableVertexAttribArray(i);
		}
	}

	previousShader = this;
	previousNumAttributes = _attributes.size();

	glUseProgram(*_shaderNo);
	for (uint32 i = 0; i < _attributes.size(); ++i) {
		Graphics::VertexAttrib &attrib = _attributes[i];
		if (attrib._enabled) {
			glEnableVertexAttribArray(i);
			glBindBuffer(GL_ARRAY_BUFFER, attrib._vbo);
			glVertexAttribPointer(i, attrib._size, attrib._type, attrib._normalized, attrib._stride, (const GLvoid *)attrib._offset);
		} else {
			glDisableVertexAttribArray(i);
			switch (attrib._size) {
			case 2:
				glVertexAttrib2fv(i, attrib._const);
				break;
			case 3:
				glVertexAttrib3fv(i, attrib._const);
				break;
			case 4:
				glVertexAttrib4fv(i, attrib._const);
				break;
			}
		}
	}
}
Beispiel #18
0
static void ddRenderSpheres(const mat4& projview)
{
	const ShaderInfo* shader = g_dbgdrawShader.get();
	GLint colorLoc = shader->m_attrs[GEOM_Color];
	GLint mvpLoc = shader->m_uniforms[BIND_Mvp];

	const ddSphere* cur = g_lists.m_spheres;
	while(cur)
	{
		// ignore scale -- debug spheres have to be spheres
		vec3 center = TransformPoint(cur->m_xfm, cur->m_center);

		mat4 model = 
			MakeTranslation(center.x, center.y, center.z) * 
			MakeScale(cur->m_radius, cur->m_radius, cur->m_radius);
		mat4 mvp = projview * model;

		glVertexAttrib3fv(colorLoc, &cur->m_color.r);
		glUniformMatrix4fv(mvpLoc, 1, 0, mvp.m);
		g_dbgSphereGeom->Render(*shader);
		
		cur = cur->m_next;
	}
}
Beispiel #19
0
void       Mesh::bindNormalObject(int _loc)
{
	glDisableVertexAttribArray(_loc);
	glVertexAttrib3fv(_loc, &_normal.x);
}
Beispiel #20
0
	// 渲染
	/////////////////////////////////////////////////////////////////////////////////
	void OGLESRenderEngine::DoRender(RenderTechnique const & tech, RenderLayout const & rl)
	{
		uint32_t const num_instance = rl.NumInstances();
		BOOST_ASSERT(num_instance != 0);

		OGLESShaderObjectPtr cur_shader = checked_pointer_cast<OGLESShaderObject>(tech.Pass(0)->GetShaderObject());
		checked_cast<OGLESRenderLayout const *>(&rl)->Active(cur_shader);

		size_t const vertexCount = rl.UseIndices() ? rl.NumIndices() : rl.NumVertices();
		GLenum mode;
		uint32_t primCount;
		OGLESMapping::Mapping(mode, primCount, rl);

		numPrimitivesJustRendered_ += num_instance * primCount;
		numVerticesJustRendered_ += num_instance * vertexCount;

		GLenum index_type = GL_UNSIGNED_SHORT;
		uint8_t* index_offset = nullptr;
		if (rl.UseIndices())
		{
			if (EF_R16UI == rl.IndexStreamFormat())
			{
				index_type = GL_UNSIGNED_SHORT;
				index_offset += rl.StartIndexLocation() * 2;
			}
			else
			{
				index_type = GL_UNSIGNED_INT;
				index_offset += rl.StartIndexLocation() * 4;
			}
		}

		uint32_t const num_passes = tech.NumPasses();
		size_t const inst_format_size = rl.InstanceStreamFormat().size();

		if (glloader_GLES_VERSION_3_0() && rl.InstanceStream())
		{
			OGLESGraphicsBuffer& stream(*checked_pointer_cast<OGLESGraphicsBuffer>(rl.InstanceStream()));

			uint32_t const instance_size = rl.InstanceSize();
			BOOST_ASSERT(num_instance * instance_size <= stream.Size());

			uint8_t* elem_offset = nullptr;
			for (size_t i = 0; i < inst_format_size; ++ i)
			{
				vertex_element const & vs_elem = rl.InstanceStreamFormat()[i];

				GLint attr = cur_shader->GetAttribLocation(vs_elem.usage, vs_elem.usage_index);
				if (attr != -1)
				{
					GLint const num_components = static_cast<GLint>(NumComponents(vs_elem.format));
					GLenum type;
					GLboolean normalized;
					OGLESMapping::MappingVertexFormat(type, normalized, vs_elem.format);
					normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized;
					GLvoid* offset = static_cast<GLvoid*>(elem_offset + rl.StartInstanceLocation() * instance_size);

					stream.Active(false);
					glVertexAttribPointer(attr, num_components, type, normalized, instance_size, offset);
					glEnableVertexAttribArray(attr);

					glVertexAttribDivisor(attr, 1);
				}

				elem_offset += vs_elem.element_size();
			}

			if (so_rl_)
			{
				glBeginTransformFeedback(so_primitive_mode_);
			}

			if (rl.UseIndices())
			{
				for (uint32_t i = 0; i < num_passes; ++ i)
				{
					RenderPassPtr const & pass = tech.Pass(i);

					pass->Bind();

					if (so_rl_)
					{
						OGLESShaderObjectPtr shader = checked_pointer_cast<OGLESShaderObject>(pass->GetShaderObject());
						glTransformFeedbackVaryings(shader->GLSLProgram(), static_cast<GLsizei>(so_vars_ptrs_.size()), &so_vars_ptrs_[0], GL_SEPARATE_ATTRIBS);
						for (uint32_t j = 0; j < so_buffs_.size(); ++ j)
						{
							glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, j, so_buffs_[j]);
						}
					}

					glDrawElementsInstanced(mode, static_cast<GLsizei>(rl.NumIndices()),
						index_type, index_offset, num_instance);
					pass->Unbind();
				}
			}
			else
			{
				for (uint32_t i = 0; i < num_passes; ++ i)
				{
					RenderPassPtr const & pass = tech.Pass(i);

					pass->Bind();

					if (so_rl_)
					{
						OGLESShaderObjectPtr shader = checked_pointer_cast<OGLESShaderObject>(pass->GetShaderObject());
						glTransformFeedbackVaryings(shader->GLSLProgram(), static_cast<GLsizei>(so_vars_ptrs_.size()), &so_vars_ptrs_[0], GL_SEPARATE_ATTRIBS);							for (uint32_t j = 0; j < so_buffs_.size(); ++ j)
						{
							glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, j, so_buffs_[j]);
						}
					}

					glDrawArraysInstanced(mode, rl.StartVertexLocation(), static_cast<GLsizei>(rl.NumVertices()), num_instance);
					pass->Unbind();
				}
			}

			if (so_rl_)
			{
				glEndTransformFeedback();
			}

			for (size_t i = 0; i < inst_format_size; ++ i)
			{
				vertex_element const & vs_elem = rl.InstanceStreamFormat()[i];
				GLint attr = cur_shader->GetAttribLocation(vs_elem.usage, vs_elem.usage_index);
				if (attr != -1)
				{
					glDisableVertexAttribArray(attr);
					glVertexAttribDivisor(attr, 0);
				}
			}
		}
		else
		{
			for (uint32_t instance = rl.StartInstanceLocation(); instance < rl.StartInstanceLocation() + num_instance; ++ instance)
			{
				if (rl.InstanceStream())
				{
					GraphicsBuffer& stream = *rl.InstanceStream();

					uint32_t const instance_size = rl.InstanceSize();
					BOOST_ASSERT(num_instance * instance_size <= stream.Size());
					GraphicsBuffer::Mapper mapper(stream, BA_Read_Only);
					uint8_t const * buffer = mapper.Pointer<uint8_t>();

					uint32_t elem_offset = 0;
					for (size_t i = 0; i < inst_format_size; ++ i)
					{
						BOOST_ASSERT(elem_offset < instance_size);

						vertex_element const & vs_elem = rl.InstanceStreamFormat()[i];

						GLint attr = cur_shader->GetAttribLocation(vs_elem.usage, vs_elem.usage_index);
						if (attr != -1)
						{
							void const * addr = &buffer[instance * instance_size + elem_offset];
							GLfloat const * float_addr = static_cast<GLfloat const *>(addr);
							GLint const num_components = static_cast<GLint>(NumComponents(vs_elem.format));
							GLenum type;
							GLboolean normalized;
							OGLESMapping::MappingVertexFormat(type, normalized, vs_elem.format);
							normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized;

							switch (num_components)
							{
							case 1:
								BOOST_ASSERT(IsFloatFormat(vs_elem.format));
								glVertexAttrib1fv(attr, float_addr);
								break;

							case 2:
								BOOST_ASSERT(IsFloatFormat(vs_elem.format));
								glVertexAttrib2fv(attr, float_addr);
								break;

							case 3:
								BOOST_ASSERT(IsFloatFormat(vs_elem.format));
								glVertexAttrib3fv(attr, float_addr);
								break;

							case 4:
								if (IsFloatFormat(vs_elem.format))
								{
									glVertexAttrib4fv(attr, float_addr);
								}
								else
								{
									GLubyte const * byte_addr = static_cast<GLubyte const *>(addr);
									if (normalized)
									{
										glVertexAttrib4f(attr, byte_addr[0] / 255.0f, byte_addr[1] / 255.0f, byte_addr[2] / 255.0f, byte_addr[3] / 255.0f);
									}
									else
									{
										glVertexAttrib4f(attr, byte_addr[0], byte_addr[1], byte_addr[2], byte_addr[3]);
									}
								}
								break;

							default:
								BOOST_ASSERT(false);
								break;
							}
						}

						elem_offset += vs_elem.element_size();
					}
				}

				if (so_rl_)
				{
					glBeginTransformFeedback(so_primitive_mode_);
				}

				if (rl.UseIndices())
				{
					for (uint32_t i = 0; i < num_passes; ++ i)
					{
						RenderPassPtr const & pass = tech.Pass(i);

						pass->Bind();

						if (so_rl_)
						{
							OGLESShaderObjectPtr shader = checked_pointer_cast<OGLESShaderObject>(pass->GetShaderObject());
							glTransformFeedbackVaryings(shader->GLSLProgram(), static_cast<GLsizei>(so_vars_ptrs_.size()), &so_vars_ptrs_[0], GL_SEPARATE_ATTRIBS);
							for (uint32_t j = 0; j < so_buffs_.size(); ++ j)
							{
								glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, j, so_buffs_[j]);
							}
						}

						glDrawElements(mode, static_cast<GLsizei>(rl.NumIndices()),
							index_type, index_offset);
						pass->Unbind();
					}
				}
				else
				{
					for (uint32_t i = 0; i < num_passes; ++ i)
					{
						RenderPassPtr const & pass = tech.Pass(i);

						pass->Bind();

						if (so_rl_)
						{
							OGLESShaderObjectPtr shader = checked_pointer_cast<OGLESShaderObject>(pass->GetShaderObject());
							glTransformFeedbackVaryings(shader->GLSLProgram(), static_cast<GLsizei>(so_vars_ptrs_.size()), &so_vars_ptrs_[0], GL_SEPARATE_ATTRIBS);
							for (uint32_t j = 0; j < so_buffs_.size(); ++ j)
							{
								glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, j, so_buffs_[j]);
							}
						}

						glDrawArrays(mode, rl.StartVertexLocation(), static_cast<GLsizei>(rl.NumVertices()));
						pass->Unbind();
					}
				}

				if (so_rl_)
				{
					glEndTransformFeedback();
				}
			}
		}

		checked_cast<OGLESRenderLayout const *>(&rl)->Deactive(cur_shader);
	}
Beispiel #21
0
void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* array)
{
    makeContextCurrent();
    glVertexAttrib3fv(index, array);
}
Beispiel #22
0
void render(void)
{
static GLint iFrames = 0;
static GLfloat fps = 0.0f, DeltaT;
static char cBuffer[64];
struct timeval tv;
GLuint model_id;

	// Update timer
	gettimeofday(&tv, NULL);
	etime = (double)tv.tv_sec + tv.tv_usec / 1000000.0f;

	dt = etime - t0;
	t0 = etime;

	/*
	 * Make the shadow pass
	 *
	 */

	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, FBO );

	glPushMatrix();

		//Compute light position
		sinE = sinf(eLit);
		cosE = cosf(eLit);
		sinA = sinf(aLit);
		cosA = cosf(aLit);

		lightPos[0] = lightRadius * cosE * sinA;
		lightPos[1] = lightRadius * sinE;
		lightPos[2] = lightRadius * cosE * cosA;
		lightPos[3] = 1.0f;

		//Set light position
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

		//Set up camera to light location
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective( 70.0f, 1.0f, 75.0f, 350.0f );
		glGetDoublev(GL_PROJECTION_MATRIX, lightProjection );
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt( lightPos[0], lightPos[1], lightPos[2],
			0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f );
		glGetDoublev(GL_MODELVIEW_MATRIX, lightModelview );
		glViewport( 0, 0, shadow_sz, shadow_sz );

		glClear(GL_DEPTH_BUFFER_BIT);

		glEnable(GL_POLYGON_OFFSET_FILL);
		glShadeModel(GL_FLAT);

		//Rotate scene, if required
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		glRotatef(yRot, 0.0f, 1.0f, 0.0f);

		//Disable shaders
		glUseProgramObjectARB(0);
		glDisable(GL_VERTEX_PROGRAM_ARB);
		glDisable(GL_FRAGMENT_PROGRAM_ARB);

		// Draw dynamic objects
		for (model_id = 0; model_id < NUM_MODELS; model_id++ )
		{
			//Update the kinematic's state
			UpdateMD2(md2_model[model_id], dt);
	
			//Animate the MD2 models
			AnimateMD2(md2_model[model_id], dt);
			
			//Draw the geometry
			glPushMatrix();
				glTranslatef(	md2_model[model_id]->position.x,
						md2_model[model_id]->position.y,
						md2_model[model_id]->position.z );
				glRotatef( md2_model[model_id]->rotation, 0.0f, 1.0f, 0.0f );
				DrawMD2(md2_model[model_id]);
			glPopMatrix();
		}

	glPopMatrix();

	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

	/*
	 * And now the normal pass
	 *
	 */

	//Back to normal settings
	glDisable(GL_POLYGON_OFFSET_FILL);
	glShadeModel(GL_SMOOTH);
	change_size( width, height );

	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();

		//Set up camera location and parameters
		setup_camera((float)dt);

		//Retrieve modelview matrix and invert it
		glGetDoublev(GL_MODELVIEW_MATRIX, cameraModelview );
		FastInvert4( cameraModelview, cameraModelviewInverse );

		//Set up depth texture
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, shadow_tx);

		//Set up texture matrix for shadow map projection
		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
		glTranslatef(0.5f, 0.5f, 0.5f);
		glScalef(0.5f, 0.5f, 0.5f);
		glMultMatrixd(lightProjection);
		glMultMatrixd(lightModelview);
		glMultMatrixd(cameraModelviewInverse);
		glMatrixMode(GL_MODELVIEW);

		//Rotate scene
		glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		glRotatef(yRot, 0.0f, 1.0f, 0.0f);

		//Re-enable shaders
		glEnable(GL_VERTEX_PROGRAM_ARB);
		glEnable(GL_FRAGMENT_PROGRAM_ARB);

		if (GLSLshader)
			glUseProgramObjectARB(progObj);
		else
			glUseProgramObjectARB(0);

		//Floor

		//Color
		glColor3f(0.64f, 0.63f, 0.65f);

		//Set textures
		glActiveTexture(GL_TEXTURE0);	//Diffuse map
		glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-2]);

		glActiveTexture(GL_TEXTURE1);	//Normal map
		glBindTexture(GL_TEXTURE_2D, texture_id[NUM_TEXTURES-1]);

		//Set Tangent vector
		glVertexAttrib3fv( tangent, floorT );

		//Set Binormal vector
		glVertexAttrib3fv( binormal, floorB );

		//Set Normal vector
		glNormal3fv( floorN );

		//Call Display List to draw
		glCallList(FList);

		// Draw dynamic objects
		for (model_id = 0; model_id < NUM_MODELS; model_id++ )
		{
			//Set color
			glColor3f(	md2_model[model_id]->color.x,
					md2_model[model_id]->color.y,
					md2_model[model_id]->color.z );
	
			//Set texture
			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id]);
			glActiveTexture(GL_TEXTURE1);
			glBindTexture(GL_TEXTURE_2D, texture_id[2*model_id+1]);
	
			//Draw the geometry
			glPushMatrix();
				glTranslatef(	md2_model[model_id]->position.x,
						md2_model[model_id]->position.y,
						md2_model[model_id]->position.z );
				glRotatef( md2_model[model_id]->rotation, 0.0f, 1.0f, 0.0f );
				DrawMD2(md2_model[model_id]);
			glPopMatrix();
		}

	glPopMatrix();

	iFrames++;
	DeltaT = (GLfloat)(etime-t1);
	if( DeltaT >= Timed )
	{
		fps = (GLfloat)(iFrames)/DeltaT;
		fps_count++;
		fps_mean = ((fps_count - 1.0f) * fps_mean + fps ) / fps_count;

		iFrames = 0;
		t1 = etime;

		sprintf(cBuffer,"FPS: %.1f Mean FPS: %.1f Poly Scale: %.1f Bias: %.1f", fps, fps_mean, scalePoly, biasPoly);
	}
	if (print_fps)
	{
		if (windowpos)
		{
			glColor3f(1.0f, 1.0f, 1.0f);
			glPushAttrib(GL_LIST_BIT);
				glListBase(fps_font - ' ');
				glWindowPos2i(0,2);
				glCallLists(strlen(cBuffer), GL_UNSIGNED_BYTE, cBuffer);
			glPopAttrib();
		}
		if( iFrames == 0 )
			printf("FPS: %.1f Mean FPS: %.1f\n", fps, fps_mean);
	}
	lCam = 0.0f;
	vCam = 0.0f;
	dCam = 0.0f;
}
Beispiel #23
0
	bool ShaderManager :: SetAttributeVector ( int location, const Vector3D& value )
	{
		glVertexAttrib3fv ( location, value );

		return true;
	}
Beispiel #24
0
void GLGSRender::EnableVertexData(bool indexed_draw)
{
	static u32 offset_list[m_vertex_count];
	u32 cur_offset = 0;

	const u32 data_offset = indexed_draw ? 0 : m_draw_array_first;

	for(u32 i=0; i<m_vertex_count; ++i)
	{
		offset_list[i] = cur_offset;

		if(!m_vertex_data[i].IsEnabled() || !m_vertex_data[i].addr) continue;

		const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size;
		const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size;
		const u32 pos = m_vdata.size();

		cur_offset += data_size;
		m_vdata.resize(m_vdata.size() + data_size);
		memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size);
	}

	m_vao.Create();
	m_vao.Bind();
	checkForGlError("initializing vao");

	m_vbo.Create(indexed_draw ? 2 : 1);
	m_vbo.Bind(0);
	m_vbo.SetData(&m_vdata[0], m_vdata.size());

	if(indexed_draw)
	{
		m_vbo.Bind(GL_ELEMENT_ARRAY_BUFFER, 1);
		m_vbo.SetData(GL_ELEMENT_ARRAY_BUFFER, &m_indexed_array.m_data[0], m_indexed_array.m_data.size());
	}

	checkForGlError("initializing vbo");

#if	DUMP_VERTEX_DATA
	rFile dump("VertexDataArray.dump", rFile::write);
#endif

	for(u32 i=0; i<m_vertex_count; ++i)
	{
		if(!m_vertex_data[i].IsEnabled()) continue;

#if	DUMP_VERTEX_DATA
		dump.Write(wxString::Format("VertexData[%d]:\n", i));
		switch(m_vertex_data[i].type)
		{
		case CELL_GCM_VERTEX_S1:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
			{
				dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
				if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;

		case CELL_GCM_VERTEX_F:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=4)
			{
				dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
				if(!(((j+4) / 4) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;

		case CELL_GCM_VERTEX_SF:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
			{
				dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j]));
				if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;

		case CELL_GCM_VERTEX_UB:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); ++j)
			{
				dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
				if(!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;

		case CELL_GCM_VERTEX_S32K:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); j+=2)
			{
				dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j]));
				if(!(((j+2) / 2) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;
		
		// case CELL_GCM_VERTEX_CMP:
		
		case CELL_GCM_VERTEX_UB256:
			for(u32 j = 0; j<m_vertex_data[i].data.size(); ++j)
			{
				dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j]));
				if(!((j+1) % m_vertex_data[i].size)) dump.Write("\n");
			}
		break;

		default:
			ConLog.Error("Bad cv type! %d", m_vertex_data[i].type);
		return;
		}

		dump.Write("\n");
#endif

		static const u32 gl_types[] =
		{
			GL_SHORT,
			GL_FLOAT,
			GL_HALF_FLOAT,
			GL_UNSIGNED_BYTE,
			GL_SHORT,
			GL_UNSIGNED_BYTE,
		};

		static const bool gl_normalized[] =
		{
			true,
			false,
			false,
			true,
			false,
			false,
		};

		if(m_vertex_data[i].type >= 1 && m_vertex_data[i].type <= 7)
		{
			if(!m_vertex_data[i].addr)
			{
				switch(m_vertex_data[i].type)
				{
				case CELL_GCM_VERTEX_S32K:
				case CELL_GCM_VERTEX_S1:
					switch(m_vertex_data[i].size)
					{
					case 1: glVertexAttrib1s(i, (GLshort&)m_vertex_data[i].data[0]); break;
					case 2: glVertexAttrib2sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
					case 3: glVertexAttrib3sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
					case 4: glVertexAttrib4sv(i, (GLshort*)&m_vertex_data[i].data[0]); break;
					}
				break;

				case CELL_GCM_VERTEX_F:
					switch(m_vertex_data[i].size)
					{
					case 1: glVertexAttrib1f(i, (GLfloat&)m_vertex_data[i].data[0]); break;
					case 2: glVertexAttrib2fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
					case 3: glVertexAttrib3fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
					case 4: glVertexAttrib4fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break;
					}
				break;

				case CELL_GCM_VERTEX_CMP:
				case CELL_GCM_VERTEX_UB:
					glVertexAttrib4ubv(i, (GLubyte*)&m_vertex_data[i].data[0]);
				break;
				}

				checkForGlError("glVertexAttrib");
			}
			else
			{
				u32 gltype = gl_types[m_vertex_data[i].type - 1];
				bool normalized = gl_normalized[m_vertex_data[i].type - 1];

				glEnableVertexAttribArray(i);
				checkForGlError("glEnableVertexAttribArray");
				glVertexAttribPointer(i, m_vertex_data[i].size, gltype, normalized, 0, (void*)offset_list[i]);
				checkForGlError("glVertexAttribPointer");
			}
		}
	}
}
Beispiel #25
0
// shade a mesh
void shade_mesh(Mesh* mesh, int time, bool wireframe, bool skinning_gpu, bool draw_normals, ShadeState* state) {
    // bind material kd, ks, n
    glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_kd"),
                 1,&mesh->mat->kd.x);
    glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_ks"),
                 1,&mesh->mat->ks.x);
    glUniform1f(glGetUniformLocation(state->gl_program_id,"material_n"),
                mesh->mat->n);
    glUniform1i(glGetUniformLocation(state->gl_program_id,"material_is_lines"),
                GL_FALSE);
    glUniform1i(glGetUniformLocation(state->gl_program_id,"material_double_sided"),
                (mesh->mat->double_sided)?GL_TRUE:GL_FALSE);
    // bind texture params (txt_on, sampler)
    _bind_texture("material_kd_txt", "material_kd_txt_on", mesh->mat->kd_txt, 0, state);
    _bind_texture("material_ks_txt", "material_ks_txt_on", mesh->mat->ks_txt, 1, state);
    _bind_texture("material_norm_txt", "material_norm_txt_on", mesh->mat->norm_txt, 2, state);
    
    // bind mesh frame - use frame_to_matrix
    glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id,"mesh_frame"),
                       1,true,&frame_to_matrix(mesh->frame)[0][0]);
    
    // enable vertex attributes arrays and set up pointers to the mesh data
    auto vertex_pos_location = glGetAttribLocation(state->gl_program_id, "vertex_pos");
    auto vertex_norm_location = glGetAttribLocation(state->gl_program_id, "vertex_norm");
    auto vertex_texcoord_location = glGetAttribLocation(state->gl_program_id, "vertex_texcoord");
    // YOUR CODE GOES HERE ---------------------
    // (only for extra credit)
    auto vertex_skin_bone_ids_location = glGetAttribLocation(state->gl_program_id, "vertex_skin_bone_ids");
    auto vertex_skin_bone_weights_location = glGetAttribLocation(state->gl_program_id, "vertex_skin_bone_weights");
    
    glEnableVertexAttribArray(vertex_pos_location);
    glVertexAttribPointer(vertex_pos_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->pos[0].x);
    glEnableVertexAttribArray(vertex_norm_location);
    glVertexAttribPointer(vertex_norm_location, 3, GL_FLOAT, GL_FALSE, 0, &mesh->norm[0].x);
    if(not mesh->texcoord.empty()) {
        glEnableVertexAttribArray(vertex_texcoord_location);
        glVertexAttribPointer(vertex_texcoord_location, 2, GL_FLOAT, GL_FALSE, 0, &mesh->texcoord[0].x);
    }
    else glVertexAttrib2f(vertex_texcoord_location, 0, 0);
    
    if (mesh->skinning and skinning_gpu) {
        // YOUR CODE GOES HERE ---------------------
        // (only for extra credit)
        glUniform1i(glGetUniformLocation(state->gl_program_id, "skin_enabled"), true);

        glEnableVertexAttribArray(vertex_skin_bone_ids_location);
        glVertexAttribPointer(vertex_skin_bone_ids_location, 4, GL_INT, GL_FALSE, 0, &mesh->skinning->bone_ids[0].x);
        
        glEnableVertexAttribArray(vertex_skin_bone_weights_location);
        glVertexAttribPointer(vertex_skin_bone_weights_location, 4, GL_FLOAT, GL_FALSE, 0, &mesh->skinning->bone_weights[0].x);

        for (int i = 0; i < 48; i++) {
            string name = "skin_bone_xforms["+std::to_string(i)+"]";
            glUniformMatrix4fv(glGetUniformLocation(state->gl_program_id, name.c_str()), 1, GL_TRUE, &mesh->skinning->bone_xforms[time][i][0].x);
        }
        
    } else {
        glUniform1i(glGetUniformLocation(state->gl_program_id,"skin_enabled"),GL_FALSE);
    }
    
    // draw triangles and quads
    if(not wireframe) {
        if(mesh->triangle.size()) glDrawElements(GL_TRIANGLES, mesh->triangle.size()*3, GL_UNSIGNED_INT, &mesh->triangle[0].x);
        if(mesh->quad.size()) glDrawElements(GL_QUADS, mesh->quad.size()*4, GL_UNSIGNED_INT, &mesh->quad[0].x);
        if(mesh->point.size()) glDrawElements(GL_POINTS, mesh->point.size(), GL_UNSIGNED_INT, &mesh->point[0]);
        if(mesh->line.size()) glDrawElements(GL_LINES, mesh->line.size(), GL_UNSIGNED_INT, &mesh->line[0].x);
        for(auto segment : mesh->spline) glDrawElements(GL_LINE_STRIP, 4, GL_UNSIGNED_INT, &segment);
    } else {
        auto edges = EdgeMap(mesh->triangle, mesh->quad).edges();
        glDrawElements(GL_LINES, edges.size()*2, GL_UNSIGNED_INT, &edges[0].x);
    }
    
    // disable vertex attribute arrays
    glDisableVertexAttribArray(vertex_pos_location);
    glDisableVertexAttribArray(vertex_norm_location);
    if(not mesh->texcoord.empty()) glDisableVertexAttribArray(vertex_texcoord_location);
    if(mesh->skinning) {
        // YOUR CODE GOES HERE ---------------------
        // (only for extra credit)
        glDisableVertexAttribArray(vertex_skin_bone_ids_location);
        glDisableVertexAttribArray(vertex_skin_bone_weights_location);
    }
    
    // draw normals if needed
    if(draw_normals) {
        glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_kd"),
                     1,&zero3f.x);
        glUniform3fv(glGetUniformLocation(state->gl_program_id,"material_ks"),
                     1,&zero3f.x);
        glBegin(GL_LINES);
        for(auto i : range(mesh->pos.size())) {
            auto p0 = mesh->pos[i];
            auto p1 = mesh->pos[i] + mesh->norm[i]*0.1;
            glVertexAttrib3fv(0,&p0.x);
            glVertexAttrib3fv(0,&p1.x);
            if(mesh->mat->double_sided) {
                auto p2 = mesh->pos[i] - mesh->norm[i]*0.1;
                glVertexAttrib3fv(0,&p0.x);
                glVertexAttrib3fv(0,&p2.x);
            }
        }
        glEnd();
    }
}
	void LightShader::setNormal(const vector3f &normal)
	{
		glVertexAttrib3fv(normalLocation, (float *)&normal);
	}
enum piglit_result piglit_display(void)
{
	GLvoid *datap;
	GLint intv[] = { 1, 1, 1, 1 };
	GLfloat floatv[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat quad[] = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };

	GLsizei length;
	GLint size;
	GLenum type;
	GLchar buffer[64];

	GLuint program, vShader, fShader;
	int maxAttribCount;

	/* --- valid program needed for some of the functions --- */

	fShader = glCreateShader(GL_FRAGMENT_SHADER);
	vShader = glCreateShader(GL_VERTEX_SHADER);

	glShaderSource(fShader, 1, &fShaderString, NULL);
	glShaderSource(vShader, 1, &vShaderString, NULL);

	glCompileShader(vShader);
	glCompileShader(fShader);

	program = glCreateProgram();

	glAttachShader(program, vShader);
	glAttachShader(program, fShader);

	glLinkProgram(program);

	glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribCount);

	/* --- tests begin here --- */

	glVertexAttrib1f(maxAttribCount, floatv[0]);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib2f(maxAttribCount, floatv[0], floatv[1]);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib3f(maxAttribCount, floatv[0], floatv[1], floatv[2]);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib4f(maxAttribCount, floatv[0], floatv[1], floatv[2],
			 floatv[3]);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib1fv(maxAttribCount, floatv);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib2fv(maxAttribCount, floatv);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib3fv(maxAttribCount, floatv);
	CHECK_GL_INVALID_VALUE;

	glVertexAttrib4fv(maxAttribCount, floatv);
	CHECK_GL_INVALID_VALUE;

	glVertexAttribPointer(maxAttribCount, 2, GL_FLOAT, GL_FALSE, 0, quad);
	CHECK_GL_INVALID_VALUE;

	glBindAttribLocation(program, maxAttribCount, "pos");
	CHECK_GL_INVALID_VALUE;

	glEnableVertexAttribArray(maxAttribCount);
	CHECK_GL_INVALID_VALUE;

	glDisableVertexAttribArray(maxAttribCount);
	CHECK_GL_INVALID_VALUE;

	glGetVertexAttribfv(maxAttribCount, GL_CURRENT_VERTEX_ATTRIB, floatv);
	CHECK_GL_INVALID_VALUE;

	glGetVertexAttribiv(maxAttribCount, GL_CURRENT_VERTEX_ATTRIB, intv);
	CHECK_GL_INVALID_VALUE;

	glGetVertexAttribPointerv(maxAttribCount, GL_VERTEX_ATTRIB_ARRAY_POINTER, &datap);
	CHECK_GL_INVALID_VALUE;

	glGetActiveAttrib(program, maxAttribCount, 64, &length, &size, &type, buffer);
	CHECK_GL_INVALID_VALUE;

	return PIGLIT_PASS;
}
Beispiel #28
0
void     Ground::bindTangentObject(int _loc)
{
	glDisableVertexAttribArray(_loc);
	glVertexAttrib3fv(_loc,(float *)&GLVector3(1.0f,0.0f,0.0f));
}
Beispiel #29
0
 void vertex_attrib_3fv(gl::uint_t index, const  gl::float_t * v) {
   glVertexAttrib3fv(index, v);
 }
Beispiel #30
0
void Mesh::bindTangentObject(int _loc)
{
	glDisableVertexAttribArray(_loc);
	glVertexAttrib3fv(_loc,&_tangent.x);
}