display.h
来自「一个纹理地形渲染器」· C头文件 代码 · 共 1,043 行 · 第 1/2 页
H
1,043 行
return (int) _lights.size();
}
virtual int numberOfTextureStages() const
{
// note: we currently only support a single texture stage
return 1;
}
virtual void world(const Matrix &matrix)
{
D3DXMATRIX d3d_matrix = ConvertMatrix(matrix);
if (_device->SetTransform(D3DTS_WORLD, &d3d_matrix) != D3D_OK) throw Error("set world transform failed");
}
virtual void view(const Matrix &matrix)
{
D3DXMATRIX d3d_matrix = ConvertMatrix(matrix);
if (_device->SetTransform(D3DTS_VIEW, &d3d_matrix) != D3D_OK) throw Error("set view transform failed");
}
virtual void projection(const Matrix &matrix)
{
D3DXMATRIX d3d_matrix = ConvertMatrix(matrix);
if (_device->SetTransform(D3DTS_PROJECTION, &d3d_matrix) != D3D_OK) throw Error("set projection transform failed");
}
virtual Matrix world() const
{
D3DXMATRIX matrix;
if (_device->GetTransform(D3DTS_WORLD, &matrix) != D3D_OK) throw Error("get world transform failed");
return ConvertMatrix(matrix);
}
virtual Matrix view() const
{
D3DXMATRIX matrix;
if (_device->GetTransform(D3DTS_VIEW, &matrix) != D3D_OK) throw Error("get view transform failed");
return ConvertMatrix(matrix);
}
virtual Matrix projection() const
{
D3DXMATRIX matrix;
if (_device->GetTransform(D3DTS_PROJECTION, &matrix) != D3D_OK) throw Error("get projection transform failed");
return ConvertMatrix(matrix);
}
virtual System::Texture* createTexture(const char name[])
{
Texture *texture = new Texture(_device, name);
addObject(texture);
return texture;
}
virtual System::Mesh* createMesh(const std::vector<System::Vertex> &vertex, const std::vector<int> &index)
{
Mesh *mesh = new Mesh(_device, vertex, index);
addObject(mesh);
return mesh;
}
virtual System::Light* createLight()
{
Light *light = new Light();
addObject(light);
return light;
}
virtual System::Material* createMaterial()
{
Material *material = new Material();
addObject(material);
return material;
}
virtual System::Timer* createTimer()
{
Timer *timer = new Timer();
addObject(timer);
return timer;
}
virtual void selectTexture(System::Texture *texture, int stage)
{
if (texture)
{
// select texture
assert(!_texture);
_texture = (Texture*) texture;
_texture->reference();
if (_device->SetTexture(stage, _texture->handle()) != D3D_OK) throw Error("set texture failed");
}
else
{
// unselect texture
assert(_texture);
if (_device->SetTexture(stage, 0) != D3D_OK) throw Error("disable texture failed");
_texture->release();
_texture = 0;
}
}
virtual void selectLight(System::Light *light, int index)
{
if (_wireframe)
return;
assert(index>=0);
assert(index<numberOfLights());
if (light)
{
// setup light
assert(!_lights[index]);
_lights[index] = (Light*) light;
_lights[index]->reference();
D3DLIGHT9 d3d_light = _lights[index]->light();
if (_device->SetLight(index, &d3d_light) != D3D_OK) throw Error("set light failed");
if (_device->LightEnable(index, TRUE) != D3D_OK) throw Error("enable light failed");
}
else
{
// disable light
assert(_lights[index]);
if (_device->LightEnable(index, FALSE) != D3D_OK) throw Error("disable light failed");
_lights[index]->release();
_lights[index] = 0;
}
}
virtual void selectMaterial(System::Material *material)
{
if (material)
{
// setup material
assert(!_material);
_material = (Material*) material;
_material->reference();
D3DMATERIAL9 d3d_material = _material->material();
if (_wireframe)
{
d3d_material.Ambient.r = 0.7f;
d3d_material.Ambient.g = 0.7f;
d3d_material.Ambient.b = 0.7f;
d3d_material.Ambient.a = 1;
}
if (_device->SetMaterial(&d3d_material) != D3D_OK)
throw Error("set material failed");
}
else
{
// unselect material
assert(_material);
_material->release();
_material = 0;
}
}
virtual void selectMesh(System::Mesh *mesh)
{
if (mesh)
{
// select mesh
assert(!_mesh);
_mesh = (Mesh*) mesh;
_mesh->reference();
if (_device->SetStreamSource(0, _mesh->vertex_buffer(), 0, sizeof(Vertex)) != D3D_OK) throw Error("set stream source failed");
if (_device->SetIndices(_mesh->index_buffer()) != D3D_OK) throw Error("set indices failed");
}
else
{
// clear mesh
assert(_mesh);
if (_device->SetStreamSource(0, 0, 0, 0) != D3D_OK) throw Error("set stream source failed");
if (_device->SetIndices(0) != D3D_OK) throw Error("set indices failed");
_mesh->release();
_mesh = 0;
}
}
virtual void renderMesh()
{
assert(_mesh);
// draw indexed primitive
Mesh *directx_mesh = (Mesh*) _mesh;
if (_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, directx_mesh->vertex_count(), 0, directx_mesh->triangle_count()) != D3D_OK) throw Error("draw indexed primitive failed");
}
virtual void blendMode(Blend::Mode mode)
{
switch (mode)
{
case Blend::NONE:
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
break;
case Blend::MULTIPLY:
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
break;
case Blend::ADD:
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
break;
case Blend::ALPHA:
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
break;
}
}
virtual void cullMode(Cull::Mode mode)
{
switch (mode)
{
case Cull::NONE:
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
break;
case Cull::CLOCKWISE:
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
break;
case Cull::COUNTERCLOCKWISE:
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
break;
}
}
virtual void depthTest(bool enabled)
{
if (enabled)
{
_device->SetRenderState(D3DRS_ZENABLE, TRUE);
_device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
}
else
{
_device->SetRenderState(D3DRS_ZENABLE, FALSE);
_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
}
}
void beginQuadStream()
{
_quadEmitter.begin();
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
void renderQuad(const Vector vertex[])
{
Vector *quad = _quadEmitter.quad();
quad[0] = vertex[0];
quad[1] = vertex[1];
quad[2] = vertex[2];
quad[3] = vertex[3];
}
void endQuadStream()
{
_quadEmitter.end();
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}
void beginLineStream()
{
_lineEmitter.begin();
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
void renderLine(const Vector &a, const Vector &b)
{
Vector *line = _lineEmitter.line();
line[0] = a;
line[1] = b;
}
void endLineStream()
{
_lineEmitter.end();
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}
bool loadHeightfield(const char filename[], std::vector<float> &data, int &width, int &height)
{
// get image info
D3DXIMAGE_INFO info;
if (FAILED(D3DXGetImageInfoFromFile(filename, &info)))
return false;
width = info.Width;
height = info.Height;
// validate image format is acceptable
int bits = 0;
switch (info.Format)
{
case D3DFMT_A8R8G8B8:
System::log("ARBG8888");
bits = 32;
break;
case D3DFMT_X8R8G8B8:
System::log("XRGB8888");
bits = 32;
break;
case D3DFMT_R8G8B8:
System::log("RGB888");
bits = 24;
break;
case D3DFMT_R5G6B5:
System::log("RGB565");
bits = 16;
break;
case D3DFMT_X1R5G5B5:
System::log("RGB555");
bits = 16;
break;
case D3DFMT_A8:
System::log("A8");
bits = 8;
break;
case D3DFMT_P8:
System::log("P8");
bits = 8;
break;
case D3DFMT_L8:
System::log("L8");
bits = 8;
break;
// unsupported pixel format!
default:
System::log("unsupport format!");
return false;
}
// i *hate* manipulating 24bit image data...
if (bits==24)
info.Format = D3DFMT_A8R8G8B8;
// create surface
LPDIRECT3DSURFACE9 surface = 0;
if (FAILED(_device->CreateOffscreenPlainSurface(width, height, info.Format, D3DPOOL_SCRATCH, &surface, 0)))
return false;
// load heightfield image to surface
HRESULT result = D3DXLoadSurfaceFromFile(surface, 0, 0, filename, 0, D3DX_FILTER_NONE, 0, &info);
if (result==D3DERR_INVALIDCALL) printf("invalid call\n");
else if (result==D3DXERR_INVALIDDATA) printf("invalid data\n");
if (FAILED(result))
{
surface->Release();
return false;
}
// process surface into heightfield float samples
D3DLOCKED_RECT rect;
if (FAILED(surface->LockRect(&rect, 0, D3DLOCK_READONLY)))
{
surface->Release();
return false;
}
data.resize(width*height);
const void *image = rect.pBits;
unsigned int pitch = rect.Pitch;
if (bits==32)
{
System::log("32 bpp");
for (int y=0; y<height; y++)
{
const unsigned int *src = (const unsigned int*) (((const unsigned char*)image) + y*pitch);
float *dst = &data[0] + width*y;
for (int x=0; x<width; x++)
{
dst[x] = ((float)(src[x]&0x00FFFFFF)) * (1.0f / 16777215);
assert(dst[x]>=0);
assert(dst[x]<=1);
}
}
}
else if (bits==24)
{
// we actually load it into 32 bit for ease of manipulation, but the actual data is still 24 bit
System::log("24 bpp");
for (int y=0; y<height; y++)
{
const unsigned int *src = (const unsigned int*) (((const unsigned char*)image) + y*pitch);
float *dst = &data[0] + width*y;
for (int x=0; x<width; x++)
{
dst[x] = ((float)(src[x]&0x00FFFFFF)) * (1.0f / 16777215);
assert(dst[x]>=0);
assert(dst[x]<=1);
}
}
}
else if (bits==16)
{
System::log("16 bpp");
for (int y=0; y<height; y++)
{
const unsigned short *src = (const unsigned short*) (((const unsigned char*)image) + y*pitch);
float *dst = &data[0] + width*y;
for (int x=0; x<width; x++)
{
dst[x] = ((float)src[x]) * (1.0f / 65535);
assert(dst[x]>=0);
assert(dst[x]<=1);
}
}
}
else if (bits==8)
{
System::log("8 bpp");
for (int y=0; y<height; y++)
{
const unsigned char *src = ((const unsigned char*)image) + y*pitch;
float *dst = &data[0] + width*y;
for (int x=0; x<width; x++)
{
dst[x] = ((float)src[x]) * (1.0f / 255);
assert(dst[x]>=0);
assert(dst[x]<=1);
}
}
}
else
{
System::log("unknown bpp");
for (unsigned int i=0; i<data.size(); i++)
data[i] = 0.5f;
}
surface->UnlockRect();
// release surface
surface->Release();
// success
return true;
}
};
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?