コード例 #1
0
void TUniform::Animate(int period)
{
    if (!duration)
        return;

    elapsed += period;
    while (elapsed > duration)
        elapsed -= duration;
    
    int total = 0;
    for (TMotionList::iterator i = motions.begin(); i != motions.end(); ++i) {
        if (elapsed < total + i->duration) {
            int numFloatComponents = 0;
            int numIntComponents = 0;

            if (IsInteger())
                numIntComponents = NumComponents();
            else
                numFloatComponents = NumComponents();

            //
            // All three progressions satisfy these conditions:
            //
            //   f(0) = start
            //   f(length) = stop
            //
            //      Linear: f(t) = start + t * (stop - start) / length;
            // Exponential: f(t) = TBD
            // Logarithmic: f(t) = TBD
            //

            if (i->type == Linear) {
                for (int c = 0; c < numFloatComponents; ++c) {
                    float start = i->start.f[c];
                    float stop = i->stop.f[c];
                    value.f[c] = start + (float) (elapsed - total) * (stop - start) / i->duration;
                }

                for (int c = 0; c < numIntComponents; ++c) {
                    int start = i->start.i[c];
                    int stop = i->stop.i[c];
                    float f = (float) (elapsed - total) * (float) (stop - start) / i->duration;
                    value.i[c] = start + (int) f;
                }
            } else if (i->type == Exponential) {
                wxGetApp().Errorf("Exponential motion is not yet implemented.");
            } else if (i->type == Logarithmic) {
                wxGetApp().Errorf("Logarthmic motion is not yet implemented.");
            } else {
                wxGetApp().Errorf("Unknown motion type.");
            }

            break;
        }
        total += i->duration;
    }
}
コード例 #2
0
void TUniform::UpdateSlider()
{
    if (!slider.IsValid())
        return;

    if (IsInteger()) {
        for (int c = 0; c < NumComponents(); ++c)
            value.i[c] = slider.current.i[c];
    } else {
        for (int c = 0; c < NumComponents(); ++c)
            value.f[c] = slider.current.f[c];
    }
}
コード例 #3
0
ファイル: reflection.cpp プロジェクト: tdapper/pbrt-v3
Spectrum BSDF::Sample_f(const Vector3f &woWorld, Vector3f *wiWorld,
                        const Point2f &u, Float *pdf, BxDFType type,
                        BxDFType *sampledType) const {
    ProfilePhase pp(Prof::BSDFEvaluation);
    // Choose which _BxDF_ to sample
    int matchingComps = NumComponents(type);
    if (matchingComps == 0) {
        *pdf = 0;
        if (sampledType) *sampledType = BxDFType(0);
        return Spectrum(0);
    }
    int comp =
        std::min((int)std::floor(u[0] * matchingComps), matchingComps - 1);

    // Get _BxDF_ pointer for chosen component
    BxDF *bxdf = nullptr;
    int count = comp;
    for (int i = 0; i < nBxDFs; ++i)
        if (bxdfs[i]->MatchesFlags(type) && count-- == 0) {
            bxdf = bxdfs[i];
            break;
        }
    Assert(bxdf);

    // Remap _BxDF_ sample _u_ to $[0,1)^2$
    Point2f uRemapped(u[0] * matchingComps - comp, u[1]);

    // Sample chosen _BxDF_
    Vector3f wi, wo = WorldToLocal(woWorld);
    *pdf = 0;
    if (sampledType) *sampledType = bxdf->type;
    Spectrum f = bxdf->Sample_f(wo, &wi, uRemapped, pdf, sampledType);
    if (*pdf == 0) {
        if (sampledType) *sampledType = BxDFType(0);
        return 0;
    }
    *wiWorld = LocalToWorld(wi);

    // Compute overall PDF with all matching _BxDF_s
    if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1)
        for (int i = 0; i < nBxDFs; ++i)
            if (bxdfs[i] != bxdf && bxdfs[i]->MatchesFlags(type))
                *pdf += bxdfs[i]->Pdf(wo, wi);
    if (matchingComps > 1) *pdf /= matchingComps;

    // Compute value of BSDF for sampled direction
    if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1) {
        bool reflect = Dot(*wiWorld, ng) * Dot(woWorld, ng) > 0;
        f = 0.;
        for (int i = 0; i < nBxDFs; ++i)
            if (bxdfs[i]->MatchesFlags(type) &&
                ((reflect && (bxdfs[i]->type & BSDF_REFLECTION)) ||
                 (!reflect && (bxdfs[i]->type & BSDF_TRANSMISSION))))
                f += bxdfs[i]->f(wo, wi);
    }
    return f;
}
コード例 #4
0
Spectrum BSDF::Sample_f(const Vector &woW, Vector *wiW,
		float u1, float u2, float u3, float *pdf,
		BxDFType flags, BxDFType *sampledType) const {
	// Choose which _BxDF_ to sample
	int matchingComps = NumComponents(flags);
	if (matchingComps == 0) {
		*pdf = 0.f;
		return Spectrum(0.f);
	}
	int which = min(Floor2Int(u3 * matchingComps),
		matchingComps-1);
	BxDF *bxdf = NULL;
	int count = which;
	for (int i = 0; i < nBxDFs; ++i)
		if (bxdfs[i]->MatchesFlags(flags))
			if (count-- == 0) {
				bxdf = bxdfs[i];
				break;
			}
	Assert(bxdf); // NOBOOK
	// Sample chosen _BxDF_
	Vector wi;
	Vector wo = WorldToLocal(woW);
	*pdf = 0.f;
	Spectrum f = bxdf->Sample_f(wo, &wi, u1, u2, pdf);
	if (*pdf == 0.f) return 0.f;
	if (sampledType) *sampledType = bxdf->type;
	*wiW = LocalToWorld(wi);
	// Compute overall PDF with all matching _BxDF_s
	if (!(bxdf->type & BSDF_SPECULAR) && matchingComps > 1) {
		for (int i = 0; i < nBxDFs; ++i) {
			if (bxdfs[i] != bxdf &&
			    bxdfs[i]->MatchesFlags(flags))
				*pdf += bxdfs[i]->Pdf(wo, wi);
		}
	}
	if (matchingComps > 1) *pdf /= matchingComps;
	// Compute value of BSDF for sampled direction
	if (!(bxdf->type & BSDF_SPECULAR)) {
		f = 0.;
		if (Dot(*wiW, ng) * Dot(woW, ng) > 0)
			// ignore BTDFs
			flags = BxDFType(flags & ~BSDF_TRANSMISSION);
		else
			// ignore BRDFs
			flags = BxDFType(flags & ~BSDF_REFLECTION);
		for (int i = 0; i < nBxDFs; ++i)
			if (bxdfs[i]->MatchesFlags(flags))
				f += bxdfs[i]->f(wo, wi);
	}
	return f;
}
コード例 #5
0
ファイル: texture.cpp プロジェクト: plainoldcj/nubuck
    void Texture::WriteTGA(const std::string& filename) {
        unsigned sz = NumComponents(_internalFormat) * _width * _height;
        COM::byte_t* pixels = new COM::byte_t[sz];

        glPixelStorei(GL_PACK_ALIGNMENT, 1);

        Bind(0);
        GL_CALL(glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, pixels));

        WriteTGA_BGR(filename, (unsigned short)_width, (unsigned short)_height, pixels);

        delete[] pixels;
    }
コード例 #6
0
	OGLESTextureCubeRenderView::OGLESTextureCubeRenderView(Texture& texture_cube, int array_index, Texture::CubeFaces face, int level)
		: texture_cube_(*checked_cast<OGLESTextureCube*>(&texture_cube)),
			face_(face), level_(level)
	{
		UNREF_PARAM(array_index);

		BOOST_ASSERT(Texture::TT_Cube == texture_cube.Type());
		BOOST_ASSERT(0 == array_index);

		uint32_t const channels = NumComponents(texture_cube.Format());
		if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg())))
		{
			THR(errc::function_not_supported);
		}

		tex_ = texture_cube_.GLTexture();

		width_ = texture_cube_.Width(level);
		height_ = texture_cube_.Height(level);
		pf_ = texture_cube_.Format();
	}
コード例 #7
0
	OGLESTexture3DRenderView::OGLESTexture3DRenderView(Texture& texture_3d, int array_index, uint32_t slice, int level)
		: texture_3d_(*checked_cast<OGLESTexture3D*>(&texture_3d)),
			slice_(slice), level_(level), copy_to_tex_(0)
	{
		UNREF_PARAM(array_index);

		BOOST_ASSERT(Texture::TT_3D == texture_3d.Type());
		BOOST_ASSERT(texture_3d_.Depth(level) > slice);
		BOOST_ASSERT(0 == array_index);

		uint32_t const channels = NumComponents(texture_3d.Format());
		if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg())))
		{
			THR(errc::function_not_supported);
		}

		tex_ = texture_3d_.GLTexture();

		width_ = texture_3d_.Width(level);
		height_ = texture_3d_.Height(level);
		pf_ = texture_3d_.Format();
	}
コード例 #8
0
	OGLESTexture2DRenderView::OGLESTexture2DRenderView(Texture& texture_2d, int array_index, int level)
		: texture_2d_(*checked_cast<OGLESTexture2D*>(&texture_2d)),
			array_index_(array_index), level_(level)
	{
		BOOST_ASSERT(Texture::TT_2D == texture_2d.Type());

		if (array_index > 0)
		{
			THR(errc::function_not_supported);
		}

		uint32_t const channels = NumComponents(texture_2d.Format());
		if (((1 == channels) || (2 == channels)) && (!(glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_texture_rg())))
		{
			THR(errc::function_not_supported);
		}

		tex_ = texture_2d_.GLTexture();

		width_ = texture_2d_.Width(level);
		height_ = texture_2d_.Height(level);
		pf_ = texture_2d_.Format();
	}
コード例 #9
0
ファイル: texture.cpp プロジェクト: plainoldcj/nubuck
	void Texture::Init(const COM::byte_t* pixelData) {
		COM_assert(0 < _width);
		COM_assert(0 < _height);

		GL_CALL(glGenTextures(1, &_id));
		GL_CALL(glBindTexture(GL_TEXTURE_2D, _id));

		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, _width, _height, 0, _format,
			GL_UNSIGNED_BYTE, pixelData));

        metrics.resources.totalTextureBufferSize += sizeof(char) * NumComponents(_internalFormat) * _width * _height;

		GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR));
		GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR));

		GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
		GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));

        if(GL_DEPTH_COMPONENT == _format) {
            // TODO: you probably don't want this for every depth texture...
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE));
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_ALPHA));
        }
	}
コード例 #10
0
void MotionPlannerInterface::GetStats(PropertyMap& stats) const
{
  stats.set("numIters",NumIterations());
  stats.set("numMilestones",NumMilestones());
  stats.set("numComponents",NumComponents());
}
コード例 #11
0
ファイル: OGLESTextureCube.cpp プロジェクト: BitYorkie/KlayGE
	void OGLESTextureCube::CopyToSubTextureCube(Texture& target,
			uint32_t dst_array_index, CubeFaces dst_face, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height,
			uint32_t src_array_index, CubeFaces src_face, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height)
	{
		BOOST_ASSERT(type_ == target.Type());

		OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		if (glloader_GLES_VERSION_3_0() && (!IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_)))))
		{
			GLuint fbo_src, fbo_dst;
			re.GetFBOForBlit(fbo_src, fbo_dst);

			GLuint old_fbo = re.BindFramebuffer();

			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index * 6 + src_face - CF_Positive_X);
			}
			else
			{
				glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + src_face - CF_Positive_X, texture_, src_level);
			}

			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
			if (target.ArraySize() > 1)
			{
				glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level, dst_array_index * 6 + dst_face - CF_Positive_X);
			}
			else
			{
				glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + dst_face - CF_Positive_X, checked_cast<OGLESTexture*>(&target)->GLTexture(), dst_level);
			}

			glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height,
							dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height,
							GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR);

			re.BindFramebuffer(old_fbo, true);
		}
		else
		{
			if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format()))
			{
				if (IsCompressedFormat(format_))
				{
					BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3)));
					BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3)));
					BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3)));
					BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3)));

					Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, 0, 0, this->Width(src_level), this->Height(src_level));
					Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, 0, 0, target.Width(dst_level), target.Height(dst_level));

					uint32_t const block_size = NumFormatBytes(format_) * 4;
					uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_y_offset / 4) * mapper_src.RowPitch() + (src_x_offset / 4 * block_size);
					uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_y_offset / 4) * mapper_dst.RowPitch() + (dst_x_offset / 4 * block_size);
					for (uint32_t y = 0; y < src_height; y += 4)
					{
						std::memcpy(d, s, src_width / 4 * block_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
				else
				{
					size_t const format_size = NumFormatBytes(format_);					

					Texture::Mapper mapper_src(*this, src_array_index, src_face, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
					Texture::Mapper mapper_dst(target, dst_array_index, dst_face, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);
					uint8_t const * s = mapper_src.Pointer<uint8_t>();
					uint8_t* d = mapper_dst.Pointer<uint8_t>();
					for (uint32_t y = 0; y < src_height; ++ y)
					{
						std::memcpy(d, s, src_width * format_size);

						s += mapper_src.RowPitch();
						d += mapper_dst.RowPitch();
					}
				}
			}
			else
			{
				this->ResizeTextureCube(target, dst_array_index, dst_face, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height,
						src_array_index, src_face, src_level, src_x_offset, src_y_offset, src_width, src_height, true);
			}
		}
	}
コード例 #12
0
ファイル: OGLRenderLayout.cpp プロジェクト: zsnake1209/KlayGE
	void OGLRenderLayout::BindVertexStreams(ShaderObjectPtr const & so, GLuint vao) const
	{
		OGLShaderObjectPtr const & ogl_so = checked_pointer_cast<OGLShaderObject>(so);

		RenderEngine& re = Context::Instance().RenderFactoryInstance().RenderEngineInstance();
		uint32_t max_vertex_streams = re.DeviceCaps().max_vertex_streams;

		std::vector<char> used_streams(max_vertex_streams, 0);
		for (uint32_t i = 0; i < this->NumVertexStreams(); ++ i)
		{
			OGLGraphicsBuffer& stream(*checked_pointer_cast<OGLGraphicsBuffer>(this->GetVertexStream(i)));
			uint32_t const size = this->VertexSize(i);
			auto const & vertex_stream_fmt = this->VertexStreamFormat(i);

			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glVertexArrayVertexBuffer(vao, i, stream.GLvbo(), this->StartVertexLocation() * size, size);
			}

			uint32_t elem_offset = 0;
			for (auto const & vs_elem : vertex_stream_fmt)
			{
				GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index);
				if (attr != -1)
				{
					GLintptr offset = elem_offset + this->StartVertexLocation() * size;
					GLint const num_components = static_cast<GLint>(NumComponents(vs_elem.format));
					GLenum type;
					GLboolean normalized;
					OGLMapping::MappingVertexFormat(type, normalized, vs_elem.format);
					normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized;

					BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType());
					stream.Active(true);
					if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
					{
						glVertexArrayAttribFormat(vao, attr, num_components, type, normalized, elem_offset);
						glVertexArrayAttribBinding(vao, attr, i);
						glEnableVertexArrayAttrib(vao, attr);
					}
					else if (glloader_GL_EXT_direct_state_access())
					{
						glVertexArrayVertexAttribOffsetEXT(vao, stream.GLvbo(), attr, num_components, type,
							normalized, size, offset);
						glEnableVertexArrayAttribEXT(vao, attr);
					}
					else
					{
						glVertexAttribPointer(attr, num_components, type, normalized, size, reinterpret_cast<GLvoid*>(offset));
						glEnableVertexAttribArray(attr);
					}

					used_streams[attr] = 1;
				}

				elem_offset += vs_elem.element_size();
			}
		}

		if (this->InstanceStream())
		{
			OGLGraphicsBuffer& stream(*checked_pointer_cast<OGLGraphicsBuffer>(this->InstanceStream()));

			uint32_t const instance_size = this->InstanceSize();
			BOOST_ASSERT(this->NumInstances() * instance_size <= stream.Size());

			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glVertexArrayVertexBuffer(vao, this->NumVertexStreams(), stream.GLvbo(),
					this->StartInstanceLocation() * instance_size, instance_size);
				glVertexArrayBindingDivisor(vao, this->NumVertexStreams(), 1);
			}

			size_t const inst_format_size = this->InstanceStreamFormat().size();
			uint32_t elem_offset = 0;
			for (size_t i = 0; i < inst_format_size; ++ i)
			{
				VertexElement const & vs_elem = this->InstanceStreamFormat()[i];

				GLint attr = ogl_so->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;
					OGLMapping::MappingVertexFormat(type, normalized, vs_elem.format);
					normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized;
					GLintptr offset = elem_offset + this->StartInstanceLocation() * instance_size;

					BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType());
					stream.Active(true);
					if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
					{
						glVertexArrayAttribFormat(vao, attr, num_components, type, normalized, elem_offset);
						glVertexArrayAttribBinding(vao, attr, this->NumVertexStreams());
						glEnableVertexArrayAttrib(vao, attr);
					}
					else if (glloader_GL_EXT_direct_state_access())
					{
						glVertexArrayVertexAttribOffsetEXT(vao, stream.GLvbo(), attr, num_components, type,
							normalized, instance_size, offset);
						glEnableVertexArrayAttribEXT(vao, attr);
						glVertexAttribDivisor(attr, 1);
					}
					else
					{
						glVertexAttribPointer(attr, num_components, type, normalized, instance_size,
							reinterpret_cast<GLvoid*>(offset));
						glEnableVertexAttribArray(attr);
						glVertexAttribDivisor(attr, 1);
					}

					used_streams[attr] = 1;
				}

				elem_offset += vs_elem.element_size();
			}
		}

		for (GLuint i = 0; i < max_vertex_streams; ++ i)
		{
			if (!used_streams[i])
			{
				if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
				{
					glDisableVertexArrayAttrib(vao, i);
				}
				else if (glloader_GL_EXT_direct_state_access())
				{
					glDisableVertexArrayAttribEXT(vao, i);
				}
				else
				{
					glDisableVertexAttribArray(i);
				}
			}
		}
	}
コード例 #13
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);
	}
コード例 #14
0
	void OGLESRenderLayout::BindVertexStreams(ShaderObjectPtr const & so) const
	{
		OGLESShaderObjectPtr const & ogl_so = checked_pointer_cast<OGLESShaderObject>(so);

		RenderEngine& re = Context::Instance().RenderFactoryInstance().RenderEngineInstance();
		uint32_t max_vertex_streams = re.DeviceCaps().max_vertex_streams;

		std::vector<char> used_streams(max_vertex_streams, 0);
		for (uint32_t i = 0; i < this->NumVertexStreams(); ++ i)
		{
			OGLESGraphicsBuffer& stream(*checked_pointer_cast<OGLESGraphicsBuffer>(this->GetVertexStream(i)));
			uint32_t const size = this->VertexSize(i);
			vertex_elements_type const & vertex_stream_fmt = this->VertexStreamFormat(i);

			uint8_t* elem_offset = nullptr;
			for (auto const & vs_elem : vertex_stream_fmt)
			{
				GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index);
				if (attr != -1)
				{
					GLvoid* offset = static_cast<GLvoid*>(elem_offset + this->StartVertexLocation() * size);
					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;

					BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType());
					stream.Active(use_vao_);
					glVertexAttribPointer(attr, num_components, type, normalized, size, offset);
					glEnableVertexAttribArray(attr);

					used_streams[attr] = 1;
				}

				elem_offset += vs_elem.element_size();
			}
		}

		if (this->InstanceStream() && (glloader_GLES_VERSION_3_0() || glloader_GLES_EXT_instanced_arrays()))
		{
			OGLESGraphicsBuffer& stream(*checked_pointer_cast<OGLESGraphicsBuffer>(this->InstanceStream()));

			uint32_t const instance_size = this->InstanceSize();
			BOOST_ASSERT(this->NumInstances() * instance_size <= stream.Size());

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

				GLint attr = ogl_so->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 + this->StartInstanceLocation() * instance_size);

					BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType());
					stream.Active(use_vao_);
					glVertexAttribPointer(attr, num_components, type, normalized, instance_size, offset);
					glEnableVertexAttribArray(attr);

					if (glloader_GLES_VERSION_3_0())
					{
						glVertexAttribDivisor(attr, 1);
					}
					else
					{
						glVertexAttribDivisorEXT(attr, 1);
					}

					used_streams[attr] = 1;
				}

				elem_offset += vs_elem.element_size();
			}
		}

		for (GLuint i = 0; i < max_vertex_streams; ++ i)
		{
			if (!used_streams[i])
			{
				glDisableVertexAttribArray(i);
			}
		}

		OGLESRenderEngine& ogl_re = *checked_cast<OGLESRenderEngine*>(&re);
		if (!(ogl_re.HackForMali() || ogl_re.HackForAdreno()) && this->UseIndices())
		{
			OGLESGraphicsBuffer& stream(*checked_pointer_cast<OGLESGraphicsBuffer>(this->GetIndexStream()));
			BOOST_ASSERT(GL_ELEMENT_ARRAY_BUFFER == stream.GLType());
			stream.Active(use_vao_);
		}
	}
コード例 #15
0
ファイル: OGLTexture1D.cpp プロジェクト: BitYorkie/KlayGE
	void OGLTexture1D::CopyToSubTexture1D(Texture& target,
			uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_width,
			uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_width)
	{
		BOOST_ASSERT(type_ == target.Type());
		
		if ((format_ == target.Format()) && !IsCompressedFormat(format_) && (glloader_GL_VERSION_4_3() || glloader_GL_ARB_copy_image())
			&& (src_width == dst_width) && (1 == sample_count_))
		{
			OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target);
			glCopyImageSubData(
				texture_, target_type_, src_level,
				src_x_offset, 0, src_array_index,
				ogl_target.GLTexture(), ogl_target.GLType(), dst_level,
				dst_x_offset, 0, dst_array_index, src_width, 1, 1);
		}
		else
		{
			OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
			if ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GL_ARB_texture_rg() || (4 == NumComponents(format_))))
			{
				GLuint fbo_src, fbo_dst;
				re.GetFBOForBlit(fbo_src, fbo_dst);

				GLuint old_fbo = re.BindFramebuffer();

				glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
				if (array_size_ > 1)
				{
					glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index);
				}
				else
				{
					if (sample_count_ <= 1)
					{
						glFramebufferTexture1D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level);
					}
					else
					{
						glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
											GL_COLOR_ATTACHMENT0,
											GL_RENDERBUFFER, texture_);
					}
				}

				OGLTexture& ogl_target = *checked_cast<OGLTexture*>(&target);
				glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
				if (array_size_ > 1)
				{
					glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index);
				}
				else
				{
					glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, ogl_target.GLTexture(), dst_level);
				}

				glBlitFramebuffer(src_x_offset, 0, src_x_offset + src_width, 1,
								dst_x_offset, 0, dst_x_offset + dst_width, 1,
								GL_COLOR_BUFFER_BIT, (src_width == dst_width) ? GL_NEAREST : GL_LINEAR);

				re.BindFramebuffer(old_fbo, true);
			}
			else
			{
				if ((src_width == dst_width) && (format_ == target.Format()))
				{
					if (IsCompressedFormat(format_))
					{
						BOOST_ASSERT(0 == (src_x_offset & 0x3));
						BOOST_ASSERT(0 == (dst_x_offset & 0x3));
						BOOST_ASSERT(0 == (src_width & 0x3));
						BOOST_ASSERT(0 == (dst_width & 0x3));

						Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, 0, this->Width(src_level));
						Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, 0, target.Width(dst_level));

						uint32_t const block_size = NumFormatBytes(format_) * 4;
						uint8_t const * s = mapper_src.Pointer<uint8_t>() + (src_x_offset / 4 * block_size);
						uint8_t* d = mapper_dst.Pointer<uint8_t>() + (dst_x_offset / 4 * block_size);
						std::memcpy(d, s, src_width / 4 * block_size);
					}
					else
					{
						size_t const format_size = NumFormatBytes(format_);

						Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_width);
						Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_width);
						uint8_t const * s = mapper_src.Pointer<uint8_t>();
						uint8_t* d = mapper_dst.Pointer<uint8_t>();

						std::memcpy(d, s, src_width * format_size);
					}
				}
				else
				{
					this->ResizeTexture1D(target, dst_array_index, dst_level, dst_x_offset, dst_width,
						src_array_index, src_level, src_x_offset, src_width, true);
				}
			}
		}
	}
コード例 #16
0
ファイル: reflection.cpp プロジェクト: mmoactrpg/RayTracer
RGB BSDF::Sample_f(const Vector &woWorld, Vector *wiWorld,
		const BSDFSample &bsdfSample, float *pdf, BxDFType flags,
		BxDFType *sampledType) const {
	int numComp = NumComponents(flags);
	if (numComp == 0) {
		*pdf = 0;
		if (sampledType)
			*sampledType = BxDFType(0);
		return 0;
	}

	int whichComp = min(Floor2Int(bsdfSample.uComponent * numComp),
			numComp - 1);
	int count = whichComp;
	BxDF *bxdf = nullptr; //被选中的Bxdf
	for (int i = 0; i < mNumBxdf; ++i) {
		if (mBxdfs[i]->MatchesFlag(flags) && count-- == 0) { //这技巧 GOOD
			bxdf = mBxdfs[i];
			break;
		}
	}

	Vector wo = WorldToLocal(woWorld); //获得局部坐标下的wo
	Vector wi;
	*pdf = 0.f;
	RGB f = bxdf->Sample_f(wo, &wi, bsdfSample.uDir[0], bsdfSample.uDir[1],
			pdf); //这里的主要作用是采样出射方向
	if (*pdf == 0) {
		if (sampledType)
			*sampledType = BxDFType(0);
		return 0;
	}
	if (sampledType)
		*sampledType = bxdf->type;
	*wiWorld = LocalToWorld(wi); //获得世界坐标系下的wi

	//计算pdf
	if (!(bxdf->type & BSDF_SPECULAR) && numComp > 1) {
		for (int i = 0; i < mNumBxdf; ++i) {
			if (bxdf != mBxdfs[i] && mBxdfs[i]->MatchesFlag(flags)) {
				*pdf += mBxdfs[i]->Pdf(wo, wi);
			}
		}
	}

	if (numComp > 1) {
		*pdf /= numComp;
	}

	//开始计算BRDF系数
	if (!(bxdf->type & BSDF_SPECULAR)) {
		f=0;//因为不是镜面反射 所以重新计算BRDF
		if (Dot(*wiWorld, mNG) * Dot(woWorld, mNG) > 0) //反射
			flags = BxDFType(flags & ~BSDF_TRANSMISSION);
		else//折射
			flags = BxDFType(flags & ~BSDF_REFLECTION);
		for (int i = 0; i < mNumBxdf; ++i)
			if (mBxdfs[i]->MatchesFlag(flags))
				f += mBxdfs[i]->f(wo, wi);
	}

	return f;
}
コード例 #17
0
ファイル: WebGLProgram.cpp プロジェクト: mephisto41/gecko-dev
bool
WebGLProgram::ValidateAfterTentativeLink(nsCString* const out_linkLog) const
{
    const auto& linkInfo = mMostRecentLinkInfo;
    const auto& gl = mContext->gl;

    // Check if the attrib name conflicting to uniform name
    for (const auto& attrib : linkInfo->attribs) {
        const auto& attribName = attrib.mActiveInfo->mBaseUserName;

        for (const auto& uniform : linkInfo->uniforms) {
            const auto& uniformName = uniform->mActiveInfo->mBaseUserName;
            if (attribName == uniformName) {
                *out_linkLog = nsPrintfCString("Attrib name conflicts with uniform name:"
                                               " %s",
                                               attribName.BeginReading());
                return false;
            }
        }
    }

    std::map<uint32_t, const webgl::AttribInfo*> attribsByLoc;
    for (const auto& attrib : linkInfo->attribs) {
        const auto& elemType = attrib.mActiveInfo->mElemType;
        const auto numUsedLocs = NumUsedLocationsByElemType(elemType);
        for (uint32_t i = 0; i < numUsedLocs; i++) {
            const uint32_t usedLoc = attrib.mLoc + i;

            const auto res = attribsByLoc.insert({usedLoc, &attrib});
            const bool& didInsert = res.second;
            if (!didInsert) {
                const auto& aliasingName = attrib.mActiveInfo->mBaseUserName;
                const auto& itrExisting = res.first;
                const auto& existingInfo = itrExisting->second;
                const auto& existingName = existingInfo->mActiveInfo->mBaseUserName;
                *out_linkLog = nsPrintfCString("Attrib \"%s\" aliases locations used by"
                                               " attrib \"%s\".",
                                               aliasingName.BeginReading(),
                                               existingName.BeginReading());
                return false;
            }
        }
    }

    // Forbid:
    // * Unrecognized varying name
    // * Duplicate varying name
    // * Too many components for specified buffer mode
    if (mNextLink_TransformFeedbackVaryings.size()) {
        GLuint maxComponentsPerIndex = 0;
        switch (mNextLink_TransformFeedbackBufferMode) {
        case LOCAL_GL_INTERLEAVED_ATTRIBS:
            gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
                             &maxComponentsPerIndex);
            break;

        case LOCAL_GL_SEPARATE_ATTRIBS:
            gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
                             &maxComponentsPerIndex);
            break;

        default:
            MOZ_CRASH("`bufferMode`");
        }

        std::vector<size_t> componentsPerVert;
        std::set<const WebGLActiveInfo*> alreadyUsed;
        for (const auto& wideUserName : mNextLink_TransformFeedbackVaryings) {
            if (!componentsPerVert.size() ||
                mNextLink_TransformFeedbackBufferMode == LOCAL_GL_SEPARATE_ATTRIBS)
            {
                componentsPerVert.push_back(0);
            }

            ////

            const WebGLActiveInfo* curInfo = nullptr;
            for (const auto& info : linkInfo->transformFeedbackVaryings) {
                const NS_ConvertASCIItoUTF16 info_wideUserName(info->mBaseUserName);
                if (info_wideUserName == wideUserName) {
                    curInfo = info.get();
                    break;
                }
            }

            if (!curInfo) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\" not"
                                               " found.",
                                               asciiUserName.BeginReading());
                return false;
            }

            const auto insertResPair = alreadyUsed.insert(curInfo);
            const auto& didInsert = insertResPair.second;
            if (!didInsert) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\""
                                               " specified twice.",
                                               asciiUserName.BeginReading());
                return false;
            }

            ////

            size_t varyingComponents = NumComponents(curInfo->mElemType);
            varyingComponents *= curInfo->mElemCount;

            auto& totalComponentsForIndex = *(componentsPerVert.rbegin());
            totalComponentsForIndex += varyingComponents;

            if (totalComponentsForIndex > maxComponentsPerIndex) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\""
                                               " pushed `componentsForIndex` over the"
                                               " limit of %u.",
                                               asciiUserName.BeginReading(),
                                               maxComponentsPerIndex);
                return false;
            }
        }

        linkInfo->componentsPerTFVert.swap(componentsPerVert);
    }

    return true;
}
コード例 #18
0
ファイル: texture.cpp プロジェクト: plainoldcj/nubuck
 Texture::~Texture() {
     GL_CALL(glDeleteTextures(1, &_id));
     metrics.resources.totalTextureBufferSize -= sizeof(char) * NumComponents(_internalFormat) * _width * _height;
 }
コード例 #19
0
ファイル: OGLESTexture2D.cpp プロジェクト: BitYorkie/KlayGE
	void OGLESTexture2D::CopyToSubTexture2D(Texture& target,
			uint32_t dst_array_index, uint32_t dst_level, uint32_t dst_x_offset, uint32_t dst_y_offset, uint32_t dst_width, uint32_t dst_height,
			uint32_t src_array_index, uint32_t src_level, uint32_t src_x_offset, uint32_t src_y_offset, uint32_t src_width, uint32_t src_height)
	{
		BOOST_ASSERT(type_ == target.Type());

		OGLESRenderEngine& re = *checked_cast<OGLESRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
		if (glloader_GLES_VERSION_3_0() && ((sample_count_ > 1) && !IsCompressedFormat(format_) && (glloader_GLES_EXT_texture_rg() || (4 == NumComponents(format_)))))
		{
			GLuint fbo_src, fbo_dst;
			re.GetFBOForBlit(fbo_src, fbo_dst);

			GLuint old_fbo = re.BindFramebuffer();

			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_src);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_, src_level, src_array_index);
			}
			else
			{
				if (sample_count_ <= 1)
				{
					glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_type_, texture_, src_level);
				}
				else
				{
					glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
										GL_COLOR_ATTACHMENT0,
										GL_RENDERBUFFER, texture_);
				}
			}

			OGLESTexture& ogl_target = *checked_cast<OGLESTexture*>(&target);
			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_dst);
			if (array_size_ > 1)
			{
				glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLTexture(), dst_level, dst_array_index);
			}
			else
			{
				glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ogl_target.GLType(), ogl_target.GLTexture(), dst_level);
			}

			glBlitFramebuffer(src_x_offset, src_y_offset, src_x_offset + src_width, src_y_offset + src_height,
							dst_x_offset, dst_y_offset, dst_x_offset + dst_width, dst_y_offset + dst_height,
							GL_COLOR_BUFFER_BIT, ((src_width == dst_width) && (src_height == dst_height)) ? GL_NEAREST : GL_LINEAR);

			re.BindFramebuffer(old_fbo, true);
		}
		else if ((src_width == dst_width) && (src_height == dst_height) && (format_ == target.Format()))
		{
			GLint gl_internalFormat;
			GLenum gl_format;
			GLenum gl_type;
			OGLESMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_);

			GLint gl_target_internal_format;
			GLenum gl_target_format;
			GLenum gl_target_type;
			OGLESMapping::MappingFormat(gl_target_internal_format, gl_target_format, gl_target_type, target.Format());

			if (IsCompressedFormat(format_))
			{
				BOOST_ASSERT((src_width == dst_width) && (src_height == dst_height));
				BOOST_ASSERT((0 == (src_x_offset & 0x3)) && (0 == (src_y_offset & 0x3)));
				BOOST_ASSERT((0 == (dst_x_offset & 0x3)) && (0 == (dst_y_offset & 0x3)));
				BOOST_ASSERT((0 == (src_width & 0x3)) && (0 == (src_height & 0x3)));
				BOOST_ASSERT((0 == (dst_width & 0x3)) && (0 == (dst_height & 0x3)));

				Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
				Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);

				uint32_t const block_size = NumFormatBytes(format_) * 4;
				uint8_t const * s = mapper_src.Pointer<uint8_t>();
				uint8_t* d = mapper_dst.Pointer<uint8_t>();
				for (uint32_t y = 0; y < src_height; y += 4)
				{
					std::memcpy(d, s, src_width / 4 * block_size);

					s += mapper_src.RowPitch();
					d += mapper_dst.RowPitch();
				}
			}
			else
			{
				size_t const format_size = NumFormatBytes(format_);

				Texture::Mapper mapper_src(*this, src_array_index, src_level, TMA_Read_Only, src_x_offset, src_y_offset, src_width, src_height);
				Texture::Mapper mapper_dst(target, dst_array_index, dst_level, TMA_Write_Only, dst_x_offset, dst_y_offset, dst_width, dst_height);
				uint8_t const * s = mapper_src.Pointer<uint8_t>();
				uint8_t* d = mapper_dst.Pointer<uint8_t>();
				for (uint32_t y = 0; y < src_height; ++ y)
				{
					std::memcpy(d, s, src_width * format_size);

					s += mapper_src.RowPitch();
					d += mapper_dst.RowPitch();
				}
			}
		}
		else
		{
			this->ResizeTexture2D(target, dst_array_index, dst_level, dst_x_offset, dst_y_offset, dst_width, dst_height,
					src_array_index, src_level, src_x_offset, src_y_offset, src_width, src_height, true);
		}
	}