Показать сообщение отдельно
Старый 08.12.2009, 20:38   #3
Igor'
ПроЭктировщик
 
Аватар для Igor'
 
Регистрация: 15.10.2009
Сообщений: 190
Написано 47 полезных сообщений
(для 142 пользователей)
Ответ: Software Rasterizer

Сообщение от Samodelkin Посмотреть сообщение
Интересная вещь, но:
- Текстура не отображается (она должна быть на чайнике?)
- Хотелось бы посмотреть зависимость производительности от полигонажа сцены и разрешения текстур.
- Vertex\Pixel Shader's это как я понимаю софтварный аналог шейдеров, но он ничем не ограничен? Будет стандартный базовый набор?
- Смысл написания такого рендера не совсем ясен. Сейчас наоборот стараются делать более программируемый процесс рендера (теже вычислительные шейдеры dx11) чтобы для каждого приложения можно было делать оригинальные варианты, а в этой демке как бы даже не API а сам рендер...
- Есть возможность посмотреть коды?
- Нет
- Зависит не от полигонажа а от растояние,тоесть если даже взять тупо один триугольник подлететь к нему чтобы он отображался во весь экран,то фпс будет равен 0.0005 .
-
class TestVertexShader : public VertexShader
{
public:

	TestVertexShader() : VertexShader(){}


	VertexOutput shader_main( const VertexInput& input ){
		VertexOutput output = VertexOutput();
		Vertex* vertex = (Vertex*)input.getInput();

		float4 pos = float4(vertex->xyz , 1.0f);
		
		VertexOutput::Element* st = output.createElement(VertexOutput::FLOAT2);
		st->data = float4(vertex->texcoord.x,vertex->texcoord.y,0,0);
		
		float NdL = dot(vertex->normal,float3(0,1.0f,0));
		float3 diffuse = NdL > 0 ? NdL : 0;

		VertexOutput::Element* normal = output.createElement(VertexOutput::FLOAT3);
		normal->data = float4(diffuse,0);

		float4x4 w = getFloat4x4("world");
		float4x4 vp = getFloat4x4("viewProj");

		float4 res = mul(pos,w);
		res = mul(vp,res);

		output.setOutput( res );
		return output;
	}
};

static bool texturing = false;


class TestPixelShader : public PixelShader
{
public:

	PixelOutput shader_main( const VertexOutput& input ){
		PixelOutput output = PixelOutput();
		float3 diffuse = input.getElement(1)->data.xyz();
		float4 pixel = texturing ? texture2D(getSampler(0),input.getElement(0)->data.xy()) : float4(1,1,1,1);
		float3 base = texturing ? pixel.xyz() : float3(1,1,1);
		float alpha = texturing ? pixel.w : 1.0f;
		output.setOutput( float4(base * diffuse,alpha));
		return output;
	} 
};
- Ну я не пишу мега растеризатор,пишу просто ради скила,да и просто интерестно.
- Пока проект не опенсурсный,но как надоест,выложу сурсы

Сурс демки(программы)
static Texture2D* diffuseMap = 0;
static Texture2D* back_buffer = 0;
static Texture2D* depth_buffer = 0;
static Texture2D* stencil_buffer = 0;




int main(int argc,char*argv[]){

	bool fullscreen = true;
	int width = 1024,height = 768;

	SDL_Init(SDL_INIT_VIDEO);

	SDL_Surface*    buffer = SDL_SetVideoMode(width,height,24,SDL_HWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0));
	SDL_Event       event;



	Raster* raster = new Raster();
    raster->setViewport(0,0,width,height);


	back_buffer = raster->createTexture2D(Surface::RGB,1);
	back_buffer->getLevel(0)->initialize(width,height);
	depth_buffer = raster->createTexture2D(Surface::R_F,1);
	depth_buffer->getLevel(0)->initialize(width,height);
	stencil_buffer = raster->createTexture2D(Surface::R,1);
	stencil_buffer->getLevel(0)->initialize(width,height);
	RenderTarget* rt = raster->createRenderTarget(back_buffer->getLevel(0),depth_buffer->getLevel(0),stencil_buffer->getLevel(0));

	diffuseMap = raster->createTexture2D(Surface::RGBA,1);
	int dm_w,dm_h;
	unsigned char* dm = load_tga("02.tga",dm_w,dm_h);
	diffuseMap->getLevel(0)->initialize(dm_w,dm_h);
	diffuseMap->getLevel(0)->setData(dm);

	Sampler* diffuseSampler = raster->createSampler();
	diffuseSampler->setMipFiltration(Sampler::FLT_NONE);
	diffuseSampler->setFiltration(Sampler::FLT_NONE);
	diffuseSampler->setAddressing(Sampler::ADRS_CLAMP);
	diffuseSampler->setTexture(diffuseMap);

	unsigned int num_vertex =  0;
	unsigned int num_indices = 0;
	unsigned int num_triangle = 0;

	FILE* file = fopen("teapot.bin","rb");
    fread(&num_vertex,sizeof(unsigned int),1,file);
    fread(&num_indices,sizeof(unsigned int),1,file);
	num_triangle = num_indices / 3;
	Vertex* vertices = new Vertex[num_vertex];
    fread(vertices,sizeof(Vertex),num_vertex,file);
    unsigned short* indices = new unsigned short[num_indices];
    fread(indices,sizeof(unsigned short),num_indices,file);
	fclose(file);

	Buffer* vb = raster->createBuffer(sizeof(Vertex)*num_vertex);
	void* data = 0;
	vb->map((void**)&data,0);
	memcpy(data,vertices,sizeof(Vertex)*num_vertex);
	vb->unmap();

	Buffer* ib = raster->createBuffer(sizeof(unsigned short)*num_indices);
	void* ib_data = 0;
	ib->map((void**)&ib_data,0);
	memcpy(ib_data,indices,sizeof(unsigned short)*num_indices);
	ib->unmap();


	raster->setVertexBuffer(vb,sizeof(Vertex));
	raster->setIndexBuffer(ib,false);
	raster->setCullMode(Raster::CULL_CCW);
	raster->setDepthTest(true,true);
	raster->setDepthWrite(true);
	raster->setDepthFunc(Raster::CMP_LESS);
	raster->setColorWrite(true);
	raster->setAlphaBlend(false);
	raster->setAlphaTest(true);
	raster->setFillMode(Raster::FILL_SOLID);
	raster->setStencilTest(false);
	raster->setStencilWrite(false);


	raster->setRenderTarget(rt);

	VertexShader* vs = new TestVertexShader();
	PixelShader* ps = new TestPixelShader();
	ps->setSampler(0,diffuseSampler);


	

			
	float4x4 proj = float4x4::perspectiveMatrix(PI/2,(float)width/height,1.0f,1024.0f);
	//float4x4 view = float4x4::translationMatrix(float3(0,2,-5.8f)) * float4x4::rotationMatrixYawPitchRoll(0,0,0);
	//view = -view;
	
	float3 cam_pos = float3(0,2,-5.8f);
	quatf cam_rot = quatf::yawPitchRollQuat(float3(0,0,0));
	float3 pos = float3(0,0,.0f);
	float3 pos1 = float3(0,-2.,0.0f);
	float3 pos2 = float3(0,2.,0.0f);



	quatf rot = quatf::yawPitchRollQuat(float3(0,0,0));
	float3 scl = float3(1,1,1);


	int frames = 0, ticks = SDL_GetTicks(); 
	bool running = true;
	float4 color = float4(0,0,0,1);

	float yaw = 0;
    while (running) {
		while (SDL_PollEvent(&event)){
            if ((event.type == SDL_QUIT) || ((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_ESCAPE)) )
                running = false;

           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_SPACE)) )
                texturing = !texturing;
           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_q)) )
			   raster->setAlphaTest(!raster->getAlphaTest());
           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_w)) )
			   cam_pos += cam_rot * float3(0,0,1);
           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_s)) )
			   cam_pos -= cam_rot * float3(0,0,1);
           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_a)) )
			   cam_pos -= cam_rot * float3(1,0,0);
           if (((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_d)) )
			   cam_pos += cam_rot * float3(1,0,0);

		}


		rot = quatf::yawPitchRollQuat(float3(0,yaw,0)*DEG2RAD);

		if(yaw > 360.0f)
			yaw = 0.0f;

		const float4x4 view = -(float4x4::translationMatrix(cam_pos) * float4x4::rotationMatrix(cam_rot));
	  
		const float4x4 world = float4x4::translationMatrix(float3(pos)) * float4x4::rotationMatrix(rot) * float4x4::scaleMatrix(scl);
		const float4x4 world1 = float4x4::translationMatrix(float3(pos1)) * float4x4::rotationMatrix(rot) * float4x4::scaleMatrix(scl);
		const float4x4 world2 = float4x4::translationMatrix(float3(pos2)) * float4x4::rotationMatrix(rot) * float4x4::scaleMatrix(scl);
						
		const float4x4 matrix = view * proj;

		rt->clear(RenderTarget::COLOR|RenderTarget::DEPTH,color,1.0f,255);


		// draw scene
		raster->setVertexShader(vs);
		raster->setPixelShader(ps);

		vs->setFloat4x4("viewProj",matrix);
		vs->setFloat4x4("world",world);
		raster->drawIndexedPrimitive(0,num_triangle);

		vs->setFloat4x4("world",world1);
		raster->drawIndexedPrimitive(0,num_triangle);

		vs->setFloat4x4("world",world2);
		raster->drawIndexedPrimitive(0,num_triangle);



		// fill sdl surface
		unsigned char* b_data = (unsigned char*)back_buffer->getLevel(0)->getData();
		memcpy(buffer->pixels,b_data,width*height*3);

		//save_tga("backbuffer.tga",b_data,width,height);
		//break;
		
		SDL_UpdateRect(buffer, 0, 0,width,height);

        frames++;
        int cur_ticks = SDL_GetTicks();
        if ((cur_ticks - ticks) > 1000) {
 
			const int fps = (1000.0f / (float(cur_ticks - ticks) / frames));
			const float ifps = 1.0f / fps;
			std::cout << "FPS: " << fps << std::endl;
		
			yaw += 100.5f * ifps;

		    frames = 0; ticks = cur_ticks;      
        }
		
		const float fps = (1000.0f / (float(cur_ticks - ticks) / frames));
		const float ifps = fps > 0 ? 1.0f / fps : 0;
		yaw += 100.5f * ifps;

    }

	return 0;
}
(Offline)
 
Ответить с цитированием