Initial commit
20
vendor/librw/tools/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
if(LIBRW_TOOLS AND NOT LIBRW_PLATFORM_PS2)
|
||||
add_subdirectory(dumprwtree)
|
||||
add_subdirectory(ska2anm)
|
||||
endif()
|
||||
|
||||
if(LIBRW_EXAMPLES)
|
||||
if(TARGET librw::skeleton)
|
||||
add_subdirectory(imguitest)
|
||||
add_subdirectory(playground)
|
||||
add_subdirectory(lights)
|
||||
add_subdirectory(subrast)
|
||||
add_subdirectory(camera)
|
||||
add_subdirectory(im2d)
|
||||
add_subdirectory(im3d)
|
||||
endif()
|
||||
|
||||
if(LIBRW_PLATFORM_PS2)
|
||||
add_subdirectory(ps2test)
|
||||
endif()
|
||||
endif()
|
||||
19
vendor/librw/tools/camera/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
add_executable(camera WIN32
|
||||
main.cpp
|
||||
camexamp.cpp
|
||||
viewer.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(camera
|
||||
PRIVATE
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET camera POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:camera>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/files" "$<TARGET_FILE_DIR:camera>/files"
|
||||
)
|
||||
|
||||
librw_platform_target(camera)
|
||||
395
vendor/librw/tools/camera/camexamp.cpp
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "viewer.h"
|
||||
#include "camexamp.h"
|
||||
|
||||
#define TEXSIZE 256
|
||||
|
||||
rw::Camera *MainCamera;
|
||||
rw::Camera *SubCamera;
|
||||
|
||||
rw::Raster *SubCameraRaster;
|
||||
rw::Raster *SubCameraZRaster;
|
||||
rw::Raster *SubCameraMainCameraSubRaster;
|
||||
rw::Raster *SubCameraMainCameraSubZRaster;
|
||||
|
||||
TextureCamera CameraTexture;
|
||||
|
||||
rw::int32 CameraSelected = 0;
|
||||
rw::int32 ProjectionIndex = 0;
|
||||
bool SubCameraMiniView = true;
|
||||
|
||||
CameraData SubCameraData;
|
||||
|
||||
void
|
||||
CameraQueryData(CameraData *data, CameraDataType type, rw::Camera *camera)
|
||||
{
|
||||
data->camera = camera;
|
||||
if(type & FARCLIPPLANE) data->farClipPlane = camera->farPlane;
|
||||
if(type & NEARCLIPPLANE) data->nearClipPlane = camera->nearPlane;
|
||||
if(type & PROJECTION) data->projection = camera->projection;
|
||||
if(type & OFFSET) data->offset = camera->viewOffset;
|
||||
if(type & VIEWWINDOW) data->viewWindow = camera->viewWindow;
|
||||
if(type & MATRIX) data->matrix = &camera->getFrame()->matrix;
|
||||
}
|
||||
|
||||
void
|
||||
CameraSetData(CameraData *data, CameraDataType type)
|
||||
{
|
||||
if(type & FARCLIPPLANE) data->camera->setFarPlane(data->farClipPlane);
|
||||
if(type & NEARCLIPPLANE) data->camera->setNearPlane(data->nearClipPlane);
|
||||
if(type & PROJECTION) data->camera->setProjection(data->projection);
|
||||
if(type & OFFSET) data->camera->setViewOffset(&data->offset);
|
||||
if(type & VIEWWINDOW) data->camera->setViewWindow(&data->viewWindow);
|
||||
}
|
||||
|
||||
void
|
||||
ProjectionCallback(void)
|
||||
{
|
||||
if(ProjectionIndex == 0)
|
||||
SubCameraData.projection = rw::Camera::PERSPECTIVE;
|
||||
else
|
||||
SubCameraData.projection = rw::Camera::PARALLEL;
|
||||
CameraSetData(&SubCameraData, PROJECTION);
|
||||
}
|
||||
|
||||
void
|
||||
ClipPlaneCallback(void)
|
||||
{
|
||||
CameraSetData(&SubCameraData, (CameraDataType)(NEARCLIPPLANE | FARCLIPPLANE));
|
||||
}
|
||||
|
||||
void
|
||||
ChangeViewOffset(float deltaX, float deltaY)
|
||||
{
|
||||
SubCameraData.offset.x += deltaX;
|
||||
SubCameraData.offset.y += deltaY;
|
||||
if(SubCameraData.offset.x > 5.0f)
|
||||
SubCameraData.offset.x = 5.0f;
|
||||
if(SubCameraData.offset.x < -5.0f)
|
||||
SubCameraData.offset.x = -5.0f;
|
||||
if(SubCameraData.offset.y > 5.0f)
|
||||
SubCameraData.offset.y = 5.0f;
|
||||
if(SubCameraData.offset.y < -5.0f)
|
||||
SubCameraData.offset.y = -5.0f;
|
||||
CameraSetData(&SubCameraData, OFFSET);
|
||||
}
|
||||
|
||||
void
|
||||
ChangeViewWindow(float deltaX, float deltaY)
|
||||
{
|
||||
SubCameraData.viewWindow.x += deltaX;
|
||||
SubCameraData.viewWindow.y += deltaY;
|
||||
if(SubCameraData.viewWindow.x > 5.0f)
|
||||
SubCameraData.viewWindow.x = 5.0f;
|
||||
if(SubCameraData.viewWindow.x < 0.01f)
|
||||
SubCameraData.viewWindow.x = 0.01f;
|
||||
if(SubCameraData.viewWindow.y > 5.0f)
|
||||
SubCameraData.viewWindow.y = 5.0f;
|
||||
if(SubCameraData.viewWindow.y < 0.01f)
|
||||
SubCameraData.viewWindow.y = 0.01f;
|
||||
CameraSetData(&SubCameraData, VIEWWINDOW);
|
||||
}
|
||||
|
||||
void
|
||||
CamerasCreate(rw::World *world)
|
||||
{
|
||||
rw::V3d offset = { 3.0f, 0.0f, 8.0f };
|
||||
float rotate = -90.0f;
|
||||
|
||||
SubCamera = ViewerCreate(world);
|
||||
ViewerMove(SubCamera, &offset);
|
||||
ViewerRotate(SubCamera, rotate, 0.0f);
|
||||
|
||||
MainCamera = ViewerCreate(world);
|
||||
|
||||
CameraQueryData(&SubCameraData, ALL, SubCamera);
|
||||
|
||||
SubCameraData.nearClipPlane = 0.3f;
|
||||
CameraSetData(&SubCameraData, NEARCLIPPLANE);
|
||||
|
||||
SubCameraData.farClipPlane = 5.0f;
|
||||
CameraSetData(&SubCameraData, FARCLIPPLANE);
|
||||
|
||||
CameraTexture.camera = SubCamera;
|
||||
CameraTextureInit(&CameraTexture);
|
||||
|
||||
SubCameraData.cameraTexture = &CameraTexture;
|
||||
|
||||
|
||||
SubCameraMainCameraSubRaster = rw::Raster::create(0, 0, 0, rw::Raster::CAMERA);
|
||||
SubCameraMainCameraSubZRaster = rw::Raster::create(0, 0, 0, rw::Raster::ZBUFFER);
|
||||
}
|
||||
|
||||
void
|
||||
CamerasDestroy(rw::World *world)
|
||||
{
|
||||
SubCameraMiniViewSelect(false);
|
||||
|
||||
if(MainCamera){
|
||||
ViewerDestroy(MainCamera, world);
|
||||
MainCamera = nil;
|
||||
}
|
||||
|
||||
if(SubCamera){
|
||||
ViewerDestroy(SubCamera, world);
|
||||
SubCamera = nil;
|
||||
}
|
||||
|
||||
CameraTextureTerm(&CameraTexture);
|
||||
|
||||
if(SubCameraMainCameraSubRaster){
|
||||
SubCameraMainCameraSubRaster->destroy();
|
||||
SubCameraMainCameraSubRaster = nil;
|
||||
}
|
||||
|
||||
if(SubCameraMainCameraSubZRaster){
|
||||
SubCameraMainCameraSubZRaster->destroy();
|
||||
SubCameraMainCameraSubZRaster = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdateSubRaster(rw::Camera *camera, rw::Rect *rect)
|
||||
{
|
||||
rw::Rect subRect;
|
||||
|
||||
subRect.x = rect->w * 0.75f;
|
||||
subRect.y = 0;
|
||||
|
||||
subRect.w = rect->w * 0.25f;
|
||||
subRect.h = rect->h * 0.25f;
|
||||
|
||||
SubCameraMainCameraSubRaster->subRaster(camera->frameBuffer, &subRect);
|
||||
SubCameraMainCameraSubZRaster->subRaster(camera->zBuffer, &subRect);
|
||||
}
|
||||
|
||||
void
|
||||
CameraSizeUpdate(rw::Rect *rect, float viewWindow, float aspectRatio)
|
||||
{
|
||||
static bool RasterInit;
|
||||
|
||||
if(MainCamera == nil)
|
||||
return;
|
||||
|
||||
sk::CameraSize(MainCamera, rect, viewWindow, aspectRatio);
|
||||
|
||||
UpdateSubRaster(MainCamera, rect);
|
||||
|
||||
if(RasterInit)
|
||||
SubCameraMiniViewSelect(false);
|
||||
|
||||
sk::CameraSize(SubCamera, rect, viewWindow, aspectRatio);
|
||||
|
||||
SubCameraRaster = SubCamera->frameBuffer;
|
||||
SubCameraZRaster = SubCamera->zBuffer;
|
||||
|
||||
RasterInit = true;
|
||||
SubCameraMiniViewSelect(CameraSelected == 0);
|
||||
|
||||
CameraQueryData(&SubCameraData, VIEWWINDOW, SubCamera);
|
||||
}
|
||||
|
||||
void
|
||||
RenderSubCamera(rw::RGBA *backgroundColor, rw::int32 clearMode, rw::World *world)
|
||||
{
|
||||
SubCamera->clear(backgroundColor, clearMode);
|
||||
SubCamera->beginUpdate();
|
||||
world->render();
|
||||
SubCamera->endUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
RenderTextureCamera(rw::RGBA *foregroundColor, rw::int32 clearMode, rw::World *world)
|
||||
{
|
||||
rw::Raster *saveRaster, *saveZRaster;
|
||||
|
||||
saveRaster = CameraTexture.camera->frameBuffer;
|
||||
saveZRaster = CameraTexture.camera->zBuffer;
|
||||
CameraTexture.camera->frameBuffer = CameraTexture.raster;
|
||||
CameraTexture.camera->zBuffer = CameraTexture.zRaster;
|
||||
|
||||
CameraTexture.camera->clear(foregroundColor, clearMode);
|
||||
CameraTexture.camera->beginUpdate();
|
||||
world->render();
|
||||
CameraTexture.camera->endUpdate();
|
||||
|
||||
|
||||
CameraTexture.camera->frameBuffer = saveRaster;
|
||||
CameraTexture.camera->zBuffer = saveZRaster;
|
||||
}
|
||||
|
||||
void
|
||||
SubCameraMiniViewSelect(bool select)
|
||||
{
|
||||
if(select){
|
||||
SubCamera->frameBuffer = SubCameraMainCameraSubRaster;
|
||||
SubCamera->zBuffer = SubCameraMainCameraSubZRaster;
|
||||
}else{
|
||||
SubCamera->frameBuffer = SubCameraRaster;
|
||||
SubCamera->zBuffer = SubCameraZRaster;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
CameraTextureInit(TextureCamera *ct)
|
||||
{
|
||||
ct->raster = rw::Raster::create(TEXSIZE, TEXSIZE, 0, rw::Raster::CAMERATEXTURE);
|
||||
assert(ct->raster);
|
||||
ct->zRaster = rw::Raster::create(TEXSIZE, TEXSIZE, 0, rw::Raster::ZBUFFER);
|
||||
assert(ct->zRaster);
|
||||
|
||||
ct->texture = rw::Texture::create(ct->raster);
|
||||
ct->texture->setFilter(rw::Texture::FilterMode::LINEAR);
|
||||
}
|
||||
|
||||
void
|
||||
CameraTextureTerm(TextureCamera *ct)
|
||||
{
|
||||
if(ct->raster){
|
||||
ct->raster->destroy();
|
||||
ct->raster = nil;
|
||||
}
|
||||
|
||||
if(ct->zRaster){
|
||||
ct->zRaster->destroy();
|
||||
ct->zRaster = nil;
|
||||
}
|
||||
|
||||
if(ct->texture){
|
||||
ct->texture->raster = nil;
|
||||
ct->texture->destroy();
|
||||
ct->texture = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DrawCameraFrustum(CameraData *c)
|
||||
{
|
||||
rw::RGBA yellow = { 255, 255, 0, 64 };
|
||||
rw::RGBA red = { 255, 0, 0, 255 };
|
||||
rw::RWDEVICE::Im3DVertex frustum[13];
|
||||
// lines
|
||||
rw::uint16 indicesL[] = {
|
||||
1, 2, 2, 3, 3, 4, 4, 1,
|
||||
5, 6, 6, 7, 7, 8, 8, 5,
|
||||
9, 10, 10, 11, 11, 12, 12, 9,
|
||||
5, 9, 6, 10, 7, 11, 8, 12,
|
||||
0, 0
|
||||
};
|
||||
// triangles
|
||||
rw::uint16 indicesT[] = {
|
||||
5, 6, 10,
|
||||
10, 9, 5,
|
||||
6, 7, 11,
|
||||
11, 10, 6,
|
||||
7, 8, 12,
|
||||
12, 11, 7,
|
||||
8, 5, 9,
|
||||
9, 12, 8,
|
||||
|
||||
7, 6, 5,
|
||||
5, 8, 7,
|
||||
9, 10, 11,
|
||||
11, 12, 9
|
||||
};
|
||||
float signs[4][2] = {
|
||||
{ 1, 1 },
|
||||
{ -1, 1 },
|
||||
{ -1, -1 },
|
||||
{ 1, -1 }
|
||||
};
|
||||
|
||||
float depth[3];
|
||||
depth[0] = 1.0f; // view window
|
||||
depth[1] = c->nearClipPlane;
|
||||
depth[2] = c->farClipPlane;
|
||||
|
||||
int k = 0;
|
||||
frustum[k].setX(c->offset.x);
|
||||
frustum[k].setY(c->offset.y);
|
||||
frustum[k].setZ(0.0f);
|
||||
k++;
|
||||
|
||||
for(int i = 0; i < 3; i++) // depths
|
||||
for(int j = 0; j < 4; j++){ // planes
|
||||
if(c->projection == rw::Camera::PERSPECTIVE){
|
||||
frustum[k].setX(-c->offset.x + depth[i]*(signs[j][0]*c->viewWindow.x + c->offset.x));
|
||||
frustum[k].setY(c->offset.y + depth[i]*(signs[j][1]*c->viewWindow.y - c->offset.y));
|
||||
frustum[k].setZ(depth[i]);
|
||||
}else{
|
||||
frustum[k].setX(-c->offset.x + signs[j][0]*c->viewWindow.x + depth[i]*c->offset.x);
|
||||
frustum[k].setY(c->offset.y + signs[j][1]*c->viewWindow.y - depth[i]*c->offset.y);
|
||||
frustum[k].setZ(depth[i]);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 5; i++)
|
||||
frustum[i].setColor(red.red, red.green, red.blue, red.alpha);
|
||||
for(int i = 5; i < 13; i++)
|
||||
frustum[i].setColor(yellow.red, yellow.green, yellow.blue, 255);
|
||||
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||
|
||||
rw::im3d::Transform(frustum, 13, c->camera->getFrame()->getLTM(), rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPELINELIST, indicesL, 34);
|
||||
rw::im3d::End();
|
||||
|
||||
for(int i = 5; i < 13; i++)
|
||||
frustum[i].setColor(yellow.red, yellow.green, yellow.blue, yellow.alpha);
|
||||
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
|
||||
rw::im3d::Transform(frustum, 13, c->camera->getFrame()->getLTM(), rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indicesT, 36);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
DrawCameraViewplaneTexture(CameraData *c)
|
||||
{
|
||||
rw::RGBA white = { 255, 255, 255, 255 };
|
||||
rw::RWDEVICE::Im3DVertex frustum[4];
|
||||
rw::uint16 indicesV[] = {
|
||||
2, 1, 0,
|
||||
0, 3, 2,
|
||||
0, 1, 2,
|
||||
2, 3, 0
|
||||
};
|
||||
float uvValues[4][2] = {
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f },
|
||||
{ 0.0f, 1.0f }
|
||||
};
|
||||
float signs[4][2] = {
|
||||
{ 1, 1 },
|
||||
{ -1, 1 },
|
||||
{ -1, -1 },
|
||||
{ 1, -1 }
|
||||
};
|
||||
|
||||
for(int j = 0; j < 4; j++){
|
||||
frustum[j].setX(signs[j][0]*c->viewWindow.x);
|
||||
frustum[j].setY(signs[j][1]*c->viewWindow.y);
|
||||
frustum[j].setZ(1.0f);
|
||||
}
|
||||
for(int i = 0; i < 4; i++){
|
||||
frustum[i].setColor(white.red, white.green, white.blue, white.alpha);
|
||||
frustum[i].setU(uvValues[i][0]);
|
||||
frustum[i].setV(uvValues[i][1]);
|
||||
}
|
||||
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, c->cameraTexture->texture->raster);
|
||||
|
||||
rw::im3d::Transform(frustum, 4, c->camera->getFrame()->getLTM(), rw::im3d::VERTEXUV);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indicesV, 12);
|
||||
rw::im3d::End();
|
||||
}
|
||||
62
vendor/librw/tools/camera/camexamp.h
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
struct TextureCamera
|
||||
{
|
||||
rw::Raster *raster;
|
||||
rw::Raster *zRaster;
|
||||
rw::Camera *camera;
|
||||
rw::Texture *texture;
|
||||
};
|
||||
|
||||
struct CameraData
|
||||
{
|
||||
float farClipPlane;
|
||||
float nearClipPlane;
|
||||
rw::uint32 projection;
|
||||
rw::V2d offset;
|
||||
rw::V2d viewWindow;
|
||||
rw::Camera *camera;
|
||||
TextureCamera *cameraTexture;
|
||||
rw::Matrix *matrix;
|
||||
};
|
||||
|
||||
enum CameraDataType
|
||||
{
|
||||
NONE = 0x00,
|
||||
FARCLIPPLANE = 0x01,
|
||||
NEARCLIPPLANE = 0x02,
|
||||
PROJECTION = 0x04,
|
||||
OFFSET = 0x08,
|
||||
VIEWWINDOW = 0x10,
|
||||
MATRIX = 0x20,
|
||||
ALL = 0xFF
|
||||
};
|
||||
|
||||
extern rw::Camera *MainCamera;
|
||||
extern rw::Camera *SubCamera;
|
||||
|
||||
extern rw::int32 CameraSelected;
|
||||
extern rw::int32 ProjectionIndex;
|
||||
|
||||
extern CameraData SubCameraData;
|
||||
|
||||
void CameraQueryData(CameraData *data, CameraDataType type, rw::Camera *camera);
|
||||
void CameraSetData(CameraData *data, CameraDataType type);
|
||||
|
||||
void ChangeViewOffset(float deltaX, float deltaY);
|
||||
void ChangeViewWindow(float deltaX, float deltaY);
|
||||
void ProjectionCallback(void);
|
||||
void ClipPlaneCallback(void);
|
||||
|
||||
void CamerasCreate(rw::World *world);
|
||||
void CamerasDestroy(rw::World *world);
|
||||
void CameraSizeUpdate(rw::Rect *rect, float viewWindow, float aspectRatio);
|
||||
void RenderSubCamera(rw::RGBA *foregroundColor, rw::int32 clearMode, rw::World *world);
|
||||
void RenderTextureCamera(rw::RGBA *foregroundColor, rw::int32 clearMode, rw::World *world);
|
||||
void SubCameraMiniViewSelect(bool select);
|
||||
|
||||
void CameraTextureInit(TextureCamera *ct);
|
||||
void CameraTextureTerm(TextureCamera *ct);
|
||||
void DrawCameraFrustum(CameraData *c);
|
||||
void DrawCameraViewplaneTexture(CameraData *c);
|
||||
|
||||
void ViewerRotate(rw::Camera *camera, float deltaX, float deltaY);
|
||||
void ViewerTranslate(rw::Camera *camera, float deltaX, float deltaY);
|
||||
BIN
vendor/librw/tools/camera/files/clump.dff
vendored
Normal file
BIN
vendor/librw/tools/camera/files/clump/shinarm.png
vendored
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
vendor/librw/tools/camera/files/clump/shinbody.png
vendored
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
vendor/librw/tools/camera/files/clump/shinface.png
vendored
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
vendor/librw/tools/camera/files/clump/shinleg.png
vendored
Normal file
|
After Width: | Height: | Size: 88 KiB |
508
vendor/librw/tools/camera/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,508 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "viewer.h"
|
||||
#include "camexamp.h"
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
float FOV = 70.0f;
|
||||
|
||||
rw::RGBA ForegroundColor = { 200, 200, 200, 255 };
|
||||
rw::RGBA BackgroundColor = { 64, 64, 64, 0 };
|
||||
rw::RGBA BackgroundColorSub = { 74, 74, 74, 0 };
|
||||
|
||||
rw::World *World;
|
||||
rw::Charset *Charset;
|
||||
|
||||
rw::V3d Xaxis = { 1.0f, 0.0, 0.0f };
|
||||
rw::V3d Yaxis = { 0.0f, 1.0, 0.0f };
|
||||
rw::V3d Zaxis = { 0.0f, 0.0, 1.0f };
|
||||
|
||||
float TimeDelta;
|
||||
|
||||
rw::Clump *Clump;
|
||||
|
||||
rw::World*
|
||||
CreateWorld(void)
|
||||
{
|
||||
rw::BBox bb;
|
||||
|
||||
bb.inf.x = bb.inf.y = bb.inf.z = -100.0f;
|
||||
bb.sup.x = bb.sup.y = bb.sup.z = 100.0f;
|
||||
|
||||
return rw::World::create(&bb);
|
||||
}
|
||||
|
||||
void
|
||||
LightsCreate(rw::World *world)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::AMBIENT);
|
||||
assert(light);
|
||||
World->addLight(light);
|
||||
|
||||
light = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
assert(light);
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
frame->rotate(&Xaxis, 30.0f, rw::COMBINEREPLACE);
|
||||
frame->rotate(&Yaxis, 30.0f, rw::COMBINEPOSTCONCAT);
|
||||
light->setFrame(frame);
|
||||
World->addLight(light);
|
||||
}
|
||||
|
||||
rw::Clump*
|
||||
ClumpCreate(rw::World *world)
|
||||
{
|
||||
rw::Clump *clump;
|
||||
rw::StreamFile in;
|
||||
|
||||
rw::Image::setSearchPath("files/clump/");
|
||||
const char *filename = "files/clump.dff";
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return nil;
|
||||
}
|
||||
if(!rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL))
|
||||
return nil;
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
in.close();
|
||||
if(clump == nil)
|
||||
return nil;
|
||||
|
||||
rw::Frame *frame = clump->getFrame();
|
||||
rw::V3d pos = { 0.0f, 0.0f, 8.0f };
|
||||
frame->translate(&pos, rw::COMBINEREPLACE);
|
||||
World->addClump(clump);
|
||||
return clump;
|
||||
}
|
||||
|
||||
void
|
||||
ClumpRotate(rw::Clump *clump, rw::Camera *camera, float xAngle, float yAngle)
|
||||
{
|
||||
rw::Matrix *cameraMatrix = &camera->getFrame()->matrix;
|
||||
rw::Frame *clumpFrame = clump->getFrame();
|
||||
rw::V3d pos = clumpFrame->matrix.pos;
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
clumpFrame->rotate(&cameraMatrix->up, xAngle, rw::COMBINEPOSTCONCAT);
|
||||
clumpFrame->rotate(&cameraMatrix->right, yAngle, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
ClumpTranslate(rw::Clump *clump, rw::Camera *camera, float xDelta, float yDelta)
|
||||
{
|
||||
rw::Matrix *cameraMatrix = &camera->getFrame()->matrix;
|
||||
rw::Frame *clumpFrame = clump->getFrame();
|
||||
|
||||
rw::V3d deltaX = rw::scale(cameraMatrix->right, xDelta);
|
||||
rw::V3d deltaZ = rw::scale(cameraMatrix->at, yDelta);
|
||||
rw::V3d delta = rw::add(deltaX, deltaZ);
|
||||
|
||||
clumpFrame->translate(&delta, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
ClumpSetPosition(rw::Clump *clump, rw::V3d *position)
|
||||
{
|
||||
clump->getFrame()->translate(position, rw::COMBINEREPLACE);
|
||||
}
|
||||
|
||||
void
|
||||
Initialize(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Camera example";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Initialize3D(void)
|
||||
{
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
Charset = rw::Charset::create(&ForegroundColor, &BackgroundColor);
|
||||
|
||||
World = CreateWorld();
|
||||
|
||||
CamerasCreate(World);
|
||||
LightsCreate(World);
|
||||
|
||||
Clump = ClumpCreate(World);
|
||||
|
||||
rw::SetRenderState(rw::CULLMODE, rw::CULLBACK);
|
||||
rw::SetRenderState(rw::ZTESTENABLE, 1);
|
||||
rw::SetRenderState(rw::ZWRITEENABLE, 1);
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
rw::Rect r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.w = sk::globals.width;
|
||||
r.h = sk::globals.height;
|
||||
CameraSizeUpdate(&r, 0.5f, 4.0f/3.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DestroyLight(rw::Light *light, rw::World *world)
|
||||
{
|
||||
world->removeLight(light);
|
||||
rw::Frame *frame = light->getFrame();
|
||||
if(frame){
|
||||
light->setFrame(nil);
|
||||
frame->destroy();
|
||||
}
|
||||
light->destroy();
|
||||
}
|
||||
|
||||
void
|
||||
Terminate3D(void)
|
||||
{
|
||||
if(Clump){
|
||||
World->removeClump(Clump);
|
||||
Clump->destroy();
|
||||
Clump = nil;
|
||||
}
|
||||
|
||||
FORLIST(lnk, World->globalLights){
|
||||
rw::Light *light = rw::Light::fromWorld(lnk);
|
||||
DestroyLight(light, World);
|
||||
}
|
||||
FORLIST(lnk, World->localLights){
|
||||
rw::Light *light = rw::Light::fromWorld(lnk);
|
||||
DestroyLight(light, World);
|
||||
}
|
||||
|
||||
CamerasDestroy(World);
|
||||
|
||||
if(World){
|
||||
World->destroy();
|
||||
World = nil;
|
||||
}
|
||||
|
||||
if(Charset){
|
||||
Charset->destroy();
|
||||
Charset = nil;
|
||||
}
|
||||
|
||||
sk::TerminateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DisplayOnScreenInfo(void)
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, "View window (%.2f, %.2f)", SubCameraData.viewWindow.x, SubCameraData.viewWindow.y);
|
||||
Charset->print(str, 100, 100, 0);
|
||||
sprintf(str, "View offset (%.2f, %.2f)", SubCameraData.offset.x, SubCameraData.offset.y);
|
||||
Charset->print(str, 100, 120, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ResetCameraAndClump(void)
|
||||
{
|
||||
SubCameraData.nearClipPlane = 0.3f;
|
||||
SubCameraData.farClipPlane = 5.0f;
|
||||
SubCameraData.projection = rw::Camera::PERSPECTIVE;
|
||||
SubCameraData.offset.x = 0.0f;
|
||||
SubCameraData.offset.y = 0.0f;
|
||||
SubCameraData.viewWindow.x = 0.5f;
|
||||
SubCameraData.viewWindow.y = 0.38f;
|
||||
CameraSetData(&SubCameraData, ALL);
|
||||
ProjectionIndex = 0;
|
||||
|
||||
rw::V3d position = { 3.0f, 0.0f, 8.0f };
|
||||
rw::V3d point = { 0.0f, 0.0f, 8.0f };
|
||||
ViewerSetPosition(SubCameraData.camera, &position);
|
||||
ViewerRotate(SubCamera, -90.0f, 0.0f);
|
||||
|
||||
ClumpSetPosition(Clump, &point);
|
||||
}
|
||||
|
||||
void
|
||||
Gui(void)
|
||||
{
|
||||
static bool showCameraWindow = true;
|
||||
ImGui::Begin("Camera", &showCameraWindow);
|
||||
|
||||
ImGui::RadioButton("Main camera", &CameraSelected, 0);
|
||||
ImGui::RadioButton("Sub camera", &CameraSelected, 1);
|
||||
|
||||
if(ImGui::RadioButton("Perspective", &ProjectionIndex, 0))
|
||||
ProjectionCallback();
|
||||
if(ImGui::RadioButton("Parallel", &ProjectionIndex, 1))
|
||||
ProjectionCallback();
|
||||
|
||||
if(ImGui::SliderFloat("Near clip-plane", &SubCameraData.nearClipPlane, 0.1f, SubCameraData.farClipPlane-0.1f))
|
||||
ClipPlaneCallback();
|
||||
if(ImGui::SliderFloat("Far clip-plane", &SubCameraData.farClipPlane, SubCameraData.nearClipPlane+0.1f, 20.0f))
|
||||
ClipPlaneCallback();
|
||||
|
||||
if(ImGui::Button("Reset"))
|
||||
ResetCameraAndClump();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
MainCameraRender(rw::Camera *camera)
|
||||
{
|
||||
RenderTextureCamera(&BackgroundColorSub, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ, World);
|
||||
|
||||
camera->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
|
||||
camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(TimeDelta);
|
||||
|
||||
World->render();
|
||||
|
||||
DrawCameraViewplaneTexture(&SubCameraData);
|
||||
DrawCameraFrustum(&SubCameraData);
|
||||
|
||||
DisplayOnScreenInfo();
|
||||
|
||||
Gui();
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
camera->endUpdate();
|
||||
|
||||
|
||||
RenderSubCamera(&BackgroundColorSub, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ, World);
|
||||
}
|
||||
|
||||
void
|
||||
SubCameraRender(rw::Camera *camera)
|
||||
{
|
||||
camera->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
|
||||
camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(TimeDelta);
|
||||
|
||||
World->render();
|
||||
|
||||
DisplayOnScreenInfo();
|
||||
|
||||
Gui();
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
camera->endUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
Render(void)
|
||||
{
|
||||
rw::Camera *camera;
|
||||
|
||||
SubCameraMiniViewSelect(CameraSelected == 0);
|
||||
|
||||
switch(CameraSelected){
|
||||
default:
|
||||
case 0:
|
||||
camera = MainCamera;
|
||||
MainCameraRender(camera);
|
||||
break;
|
||||
case 1:
|
||||
camera = SubCamera;
|
||||
SubCameraRender(camera);
|
||||
break;
|
||||
}
|
||||
camera->showRaster(0);
|
||||
}
|
||||
|
||||
void
|
||||
Idle(float timeDelta)
|
||||
{
|
||||
TimeDelta = timeDelta;
|
||||
Render();
|
||||
}
|
||||
|
||||
int MouseX, MouseY;
|
||||
int MouseDeltaX, MouseDeltaY;
|
||||
int MouseButtons;
|
||||
|
||||
bool RotateClump;
|
||||
bool TranslateClump;
|
||||
bool RotateCamera;
|
||||
bool TranslateCamera;
|
||||
bool ViewXWindow;
|
||||
bool ViewYWindow;
|
||||
bool ViewXOffset;
|
||||
bool ViewYOffset;
|
||||
|
||||
bool Ctrl, Alt, Shift;
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_LCTRL:
|
||||
case sk::KEY_RCTRL:
|
||||
Ctrl = false;
|
||||
break;
|
||||
case sk::KEY_LALT:
|
||||
case sk::KEY_RALT:
|
||||
Alt = false;
|
||||
break;
|
||||
case sk::KEY_LSHIFT:
|
||||
case sk::KEY_RSHIFT:
|
||||
Shift = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_LCTRL:
|
||||
case sk::KEY_RCTRL:
|
||||
Ctrl = true;
|
||||
break;
|
||||
case sk::KEY_LALT:
|
||||
case sk::KEY_RALT:
|
||||
Alt = true;
|
||||
break;
|
||||
case sk::KEY_LSHIFT:
|
||||
case sk::KEY_RSHIFT:
|
||||
Shift = true;
|
||||
break;
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseBtn(sk::MouseState *mouse)
|
||||
{
|
||||
MouseButtons = mouse->buttons;
|
||||
RotateClump = !Ctrl && !Alt && !Shift && !!(MouseButtons&1);
|
||||
TranslateClump = !Ctrl && !Alt && !Shift && !!(MouseButtons&4);
|
||||
RotateCamera = Ctrl && !!(MouseButtons&1);
|
||||
TranslateCamera = Ctrl && !!(MouseButtons&4);
|
||||
ViewXWindow = Shift && !!(MouseButtons&1);
|
||||
ViewYWindow = Shift && !!(MouseButtons&4);
|
||||
ViewXOffset = Alt && !!(MouseButtons&1);
|
||||
ViewYOffset = Alt && !!(MouseButtons&4);
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(sk::MouseState *mouse)
|
||||
{
|
||||
MouseDeltaX = mouse->posx - MouseX;
|
||||
MouseDeltaY = mouse->posy - MouseY;
|
||||
MouseX = mouse->posx;
|
||||
MouseY = mouse->posy;
|
||||
|
||||
if(RotateClump)
|
||||
ClumpRotate(Clump, MainCamera, MouseDeltaX, -MouseDeltaY);
|
||||
if(TranslateClump)
|
||||
ClumpTranslate(Clump, MainCamera, -MouseDeltaX*0.01f, -MouseDeltaY*0.1f);
|
||||
if(RotateCamera)
|
||||
ViewerRotate(SubCamera, -MouseDeltaX*0.1f, MouseDeltaY*0.1f);
|
||||
if(TranslateCamera)
|
||||
ViewerTranslate(SubCamera, -MouseDeltaX*0.01f, -MouseDeltaY*0.01f);
|
||||
if(ViewXWindow)
|
||||
ChangeViewWindow(-MouseDeltaY*0.01f, 0.0f);
|
||||
if(ViewYWindow)
|
||||
ChangeViewWindow(0.0f, -MouseDeltaY*0.01f);
|
||||
if(ViewXOffset)
|
||||
ChangeViewOffset(-MouseDeltaY*0.01f, 0.0f);
|
||||
if(ViewYOffset)
|
||||
ChangeViewOffset(0.0f, -MouseDeltaY*0.01f);
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Initialize();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return Initialize3D() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
Terminate3D();
|
||||
return EVENTPROCESSED;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
if(!io.WantCaptureMouse){
|
||||
ms = (MouseState*)param;
|
||||
MouseBtn(ms);
|
||||
}else
|
||||
MouseButtons = 0;
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
MouseMove((MouseState*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
|
||||
CameraSizeUpdate(r, 0.5f, 4.0f/3.0f);
|
||||
break;
|
||||
case IDLE:
|
||||
Idle(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
51
vendor/librw/tools/camera/viewer.cpp
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
rw::Camera*
|
||||
ViewerCreate(rw::World *world)
|
||||
{
|
||||
rw::Camera *camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
assert(camera);
|
||||
camera->setNearPlane(0.1f);
|
||||
camera->setFarPlane(500.0f);
|
||||
world->addCamera(camera);
|
||||
return camera;
|
||||
}
|
||||
|
||||
void
|
||||
ViewerDestroy(rw::Camera *camera, rw::World *world)
|
||||
{
|
||||
if(camera && world){
|
||||
world->removeCamera(camera);
|
||||
sk::CameraDestroy(camera);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ViewerMove(rw::Camera *camera, rw::V3d *offset)
|
||||
{
|
||||
sk::CameraMove(camera, offset);
|
||||
}
|
||||
|
||||
void
|
||||
ViewerRotate(rw::Camera *camera, float deltaX, float deltaY)
|
||||
{
|
||||
sk::CameraTilt(camera, nil, deltaY);
|
||||
sk::CameraPan(camera, nil, deltaX);
|
||||
}
|
||||
|
||||
void
|
||||
ViewerTranslate(rw::Camera *camera, float deltaX, float deltaY)
|
||||
{
|
||||
rw::V3d offset;
|
||||
offset.x = deltaX;
|
||||
offset.y = deltaY;
|
||||
offset.z = 0.0f;
|
||||
sk::CameraMove(camera, &offset);
|
||||
}
|
||||
|
||||
void
|
||||
ViewerSetPosition(rw::Camera *camera, rw::V3d *position)
|
||||
{
|
||||
camera->getFrame()->translate(position, rw::COMBINEREPLACE);
|
||||
}
|
||||
6
vendor/librw/tools/camera/viewer.h
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
rw::Camera *ViewerCreate(rw::World *world);
|
||||
void ViewerDestroy(rw::Camera *camera, rw::World *world);
|
||||
void ViewerMove(rw::Camera *camera, rw::V3d *offset);
|
||||
void ViewerRotate(rw::Camera *camera, float deltaX, float deltaY);
|
||||
void ViewerTranslate(rw::Camera *camera, float deltaX, float deltaY);
|
||||
void ViewerSetPosition(rw::Camera *camera, rw::V3d *position);
|
||||
16
vendor/librw/tools/dumprwtree/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
add_executable(dumprwtree
|
||||
dumprwtree.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(dumprwtree
|
||||
PRIVATE
|
||||
librw::librw
|
||||
)
|
||||
|
||||
if(LIBRW_INSTALL)
|
||||
install(TARGETS dumprwtree
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
librw_platform_target(dumprwtree INSTALL)
|
||||
145
vendor/librw/tools/dumprwtree/dumprwtree.cpp
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <rw.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace rw;
|
||||
|
||||
const char *chunks[] = { "None", "Struct", "String", "Extension", "Unknown",
|
||||
"Camera", "Texture", "Material", "Material List", "Atomic Section",
|
||||
"Plane Section", "World", "Spline", "Matrix", "Frame List",
|
||||
"Geometry", "Clump", "Unknown", "Light", "Unicode String", "Atomic",
|
||||
"Texture Native", "Texture Dictionary", "Animation Database",
|
||||
"Image", "Skin Animation", "Geometry List", "Anim Animation",
|
||||
"Team", "Crowd", "Delta Morph Animation", "Right To Render",
|
||||
"MultiTexture Effect Native", "MultiTexture Effect Dictionary",
|
||||
"Team Dictionary", "Platform Independet Texture Dictionary",
|
||||
"Table of Contents", "Particle Standard Global Data", "AltPipe",
|
||||
"Platform Independet Peds", "Patch Mesh", "Chunk Group Start",
|
||||
"Chunk Group End", "UV Animation Dictionary", "Coll Tree"
|
||||
};
|
||||
|
||||
/* From 0x0101 through 0x0135 */
|
||||
const char *toolkitchunks0[] = { "Metrics PLG", "Spline PLG", "Stereo PLG",
|
||||
"VRML PLG", "Morph PLG", "PVS PLG", "Memory Leak PLG", "Animation PLG",
|
||||
"Gloss PLG", "Logo PLG", "Memory Info PLG", "Random PLG",
|
||||
"PNG Image PLG", "Bone PLG", "VRML Anim PLG", "Sky Mipmap Val",
|
||||
"MRM PLG", "LOD Atomic PLG", "ME PLG", "Lightmap PLG",
|
||||
"Refine PLG", "Skin PLG", "Label PLG", "Particles PLG", "GeomTX PLG",
|
||||
"Synth Core PLG", "STQPP PLG",
|
||||
"Part PP PLG", "Collision PLG", "HAnim PLG", "User Data PLG",
|
||||
"Material Effects PLG", "Particle System PLG", "Delta Morph PLG",
|
||||
"Patch PLG", "Team PLG", "Crowd PP PLG", "Mip Split PLG",
|
||||
"Anisotrophy PLG", "Not used", "GCN Material PLG", "Geometric PVS PLG",
|
||||
"XBOX Material PLG", "Multi Texture PLG", "Chain PLG", "Toon PLG",
|
||||
"PTank PLG", "Particle Standard PLG", "PDS PLG", "PrtAdv PLG",
|
||||
"Normal Map PLG", "ADC PLG", "UV Animation PLG"
|
||||
};
|
||||
|
||||
/* From 0x0180 through 0x01c1 */
|
||||
const char *toolkitchunks1[] = {
|
||||
"Character Set PLG", "NOHS World PLG", "Import Util PLG",
|
||||
"Slerp PLG", "Optim PLG", "TL World PLG", "Database PLG",
|
||||
"Raytrace PLG", "Ray PLG", "Library PLG",
|
||||
"Not used", "Not used", "Not used", "Not used", "Not used", "Not used",
|
||||
"2D PLG", "Tile Render PLG", "JPEG Image PLG", "TGA Image PLG",
|
||||
"GIF Image PLG", "Quat PLG", "Spline PVS PLG", "Mipmap PLG",
|
||||
"MipmapK PLG", "2D Font", "Intersection PLG", "TIFF Image PLG",
|
||||
"Pick PLG", "BMP Image PLG", "RAS Image PLG", "Skin FX PLG",
|
||||
"VCAT PLG", "2D Path", "2D Brush", "2D Object", "2D Shape", "2D Scene",
|
||||
"2D Pick Region", "2D Object String", "2D Animation PLG",
|
||||
"2D Animation",
|
||||
"Not used", "Not used", "Not used", "Not used", "Not used", "Not used",
|
||||
"2D Keyframe", "2D Maestro", "Barycentric",
|
||||
"Platform Independent Texture Dictionary TK", "TOC TK", "TPL TK",
|
||||
"AltPipe TK", "Animation TK", "Skin Split Tookit", "Compressed Key TK",
|
||||
"Geometry Conditioning PLG", "Wing PLG", "Generic Pipeline TK",
|
||||
"Lightmap Conversion TK", "Filesystem PLG", "Dictionary TK",
|
||||
"UV Animation Linear", "UV Animation Parameter"
|
||||
};
|
||||
|
||||
const char *RSchunks[] = { "Unused 1", "Unused 2", "Extra Normals",
|
||||
"Pipeline Set", "Unused 5", "Unused 6", "Specular Material",
|
||||
"Unused 8", "2dfx", "Extra Colors", "Collision Model",
|
||||
"Unused 12", "Environment Material", "Breakable", "Node Name",
|
||||
"Unused 16"
|
||||
};
|
||||
|
||||
const char*
|
||||
getChunkName(uint32 id)
|
||||
{
|
||||
switch(id){
|
||||
case 0x50E:
|
||||
return "Bin Mesh PLG";
|
||||
case 0x510:
|
||||
return "Native Data PLG";
|
||||
case 0x511:
|
||||
return "Vertex Format PLG";
|
||||
case 0xF21E:
|
||||
return "ZModeler Lock";
|
||||
}
|
||||
|
||||
if(id <= 45)
|
||||
return chunks[id];
|
||||
else if(id <= 0x0253F2FF && id >= 0x0253F2F0)
|
||||
return RSchunks[id-0x0253F2F0];
|
||||
else if(id <= 0x0135 && id >= 0x0101)
|
||||
return toolkitchunks0[id-0x0101];
|
||||
else if(id <= 0x01C0 && id >= 0x0181)
|
||||
return toolkitchunks1[id-0x0181];
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void
|
||||
readchunk(StreamFile *s, ChunkHeaderInfo *h, int level)
|
||||
{
|
||||
for(int i = 0; i < level; i++)
|
||||
printf(" ");
|
||||
const char *name = getChunkName(h->type);
|
||||
printf("%s (%x bytes @ 0x%x/0x%x) - [0x%x]\n",
|
||||
name, h->length, s->tell()-12, s->tell(), h->type);
|
||||
|
||||
uint32 end = s->tell() + h->length;
|
||||
while(s->tell() < end){
|
||||
ChunkHeaderInfo nh;
|
||||
readChunkHeaderInfo(s, &nh);
|
||||
if(nh.version == h->version && nh.build == h->build){
|
||||
readchunk(s, &nh, level+1);
|
||||
if(h->type == 0x510)
|
||||
s->seek(end, 0);
|
||||
}else{
|
||||
s->seek(h->length-12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2){
|
||||
fprintf(stderr, "usage: %s rwStreamFile\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
StreamFile s;
|
||||
s.open(argv[1], "rb");
|
||||
|
||||
ChunkHeaderInfo header, last;
|
||||
while(readChunkHeaderInfo(&s, &header)){
|
||||
if(header.type == 0)
|
||||
break;
|
||||
last = header;
|
||||
if(argc == 2)
|
||||
readchunk(&s, &header, 0);
|
||||
}
|
||||
|
||||
printf("%x %x %x\n", last.version, last.build,
|
||||
libraryIDPack(last.version, last.build));
|
||||
|
||||
s.close();
|
||||
return 0;
|
||||
}
|
||||
23
vendor/librw/tools/im2d/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
add_executable(im2d WIN32
|
||||
im2d.cpp
|
||||
linelist.cpp
|
||||
main.cpp
|
||||
polyline.cpp
|
||||
trifan.cpp
|
||||
trilist.cpp
|
||||
tristrip.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(im2d
|
||||
PRIVATE
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET im2d POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:im2d>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/files" "$<TARGET_FILE_DIR:im2d>/files"
|
||||
)
|
||||
|
||||
librw_platform_target(im2d)
|
||||
BIN
vendor/librw/tools/im2d/files/whiteash.png
vendored
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
134
vendor/librw/tools/im2d/im2d.cpp
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
bool Im2DColored = true;
|
||||
bool Im2DTextured;
|
||||
|
||||
rw::int32 Im2DPrimType;
|
||||
|
||||
rw::V2d ScreenSize;
|
||||
float Scale;
|
||||
|
||||
rw::RGBA SolidWhite = {255, 255, 255, 255};
|
||||
rw::RGBA SolidBlack = {0, 0, 0, 255};
|
||||
rw::RGBA SolidRed = {200, 64, 64, 255};
|
||||
rw::RGBA SolidGreen = {64, 200, 64, 255};
|
||||
rw::RGBA SolidBlue = {64, 64, 200, 255};
|
||||
rw::RGBA SolidYellow = {200, 200, 64, 255};
|
||||
rw::RGBA SolidPurple = {200, 64, 200, 255};
|
||||
rw::RGBA SolidCyan = {64, 200, 200, 255};
|
||||
|
||||
rw::Texture *Im2DTexture;
|
||||
|
||||
void
|
||||
Im2DInitialize(rw::Camera *camera)
|
||||
{
|
||||
ScreenSize.x = camera->frameBuffer->width;
|
||||
ScreenSize.y = camera->frameBuffer->height;
|
||||
|
||||
Scale = ScreenSize.y / 3.0f;
|
||||
|
||||
rw::Image::setSearchPath("files/");
|
||||
Im2DTexture = rw::Texture::read("whiteash", nil);
|
||||
|
||||
LineListCreate(camera);
|
||||
LineListSetColor(!Im2DColored);
|
||||
|
||||
IndexedLineListCreate(camera);
|
||||
IndexedLineListSetColor(!Im2DColored);
|
||||
|
||||
PolyLineCreate(camera);
|
||||
PolyLineSetColor(!Im2DColored);
|
||||
|
||||
IndexedPolyLineCreate(camera);
|
||||
IndexedPolyLineSetColor(!Im2DColored);
|
||||
|
||||
TriListCreate(camera);
|
||||
TriListSetColor(!Im2DColored);
|
||||
|
||||
IndexedTriListCreate(camera);
|
||||
IndexedTriListSetColor(!Im2DColored);
|
||||
|
||||
TriStripCreate(camera);
|
||||
TriStripSetColor(!Im2DColored);
|
||||
|
||||
IndexedTriStripCreate(camera);
|
||||
IndexedTriStripSetColor(!Im2DColored);
|
||||
|
||||
TriFanCreate(camera);
|
||||
TriFanSetColor(!Im2DColored);
|
||||
|
||||
IndexedTriFanCreate(camera);
|
||||
IndexedTriFanSetColor(!Im2DColored);
|
||||
}
|
||||
|
||||
void
|
||||
Im2DTerminate(void)
|
||||
{
|
||||
if(Im2DTexture){
|
||||
Im2DTexture->destroy();
|
||||
Im2DTexture = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Im2DRender(void)
|
||||
{
|
||||
rw::SetRenderState(rw::ZTESTENABLE, 0);
|
||||
rw::SetRenderState(rw::ZWRITEENABLE, 0);
|
||||
rw::SetRenderState(rw::SRCBLEND, rw::BLENDSRCALPHA);
|
||||
rw::SetRenderState(rw::DESTBLEND, rw::BLENDINVSRCALPHA);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::FilterMode::LINEAR);
|
||||
|
||||
if(Im2DTextured)
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, Im2DTexture->raster);
|
||||
else
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||
|
||||
switch(Im2DPrimType){
|
||||
case 0: LineListRender(); break;
|
||||
case 1: IndexedLineListRender(); break;
|
||||
case 2: PolyLineRender(); break;
|
||||
case 3: IndexedPolyLineRender(); break;
|
||||
case 4: TriListRender(); break;
|
||||
case 5: IndexedTriListRender(); break;
|
||||
case 6: TriStripRender(); break;
|
||||
case 7: IndexedTriStripRender(); break;
|
||||
case 8: TriFanRender(); break;
|
||||
case 9: IndexedTriFanRender(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Im2DSize(rw::Camera *camera, rw::int32 w, rw::int32 h)
|
||||
{
|
||||
ScreenSize.x = w;
|
||||
ScreenSize.y = h;
|
||||
|
||||
if(ScreenSize.x > ScreenSize.y)
|
||||
Scale = ScreenSize.y / 3.0f;
|
||||
else
|
||||
Scale = ScreenSize.x / 3.0f;
|
||||
|
||||
LineListCreate(camera);
|
||||
|
||||
IndexedLineListCreate(camera);
|
||||
|
||||
PolyLineCreate(camera);
|
||||
|
||||
IndexedPolyLineCreate(camera);
|
||||
|
||||
TriListCreate(camera);
|
||||
|
||||
IndexedTriListCreate(camera);
|
||||
|
||||
TriStripCreate(camera);
|
||||
|
||||
IndexedTriStripCreate(camera);
|
||||
|
||||
TriFanCreate(camera);
|
||||
|
||||
IndexedTriFanCreate(camera);
|
||||
}
|
||||
62
vendor/librw/tools/im2d/im2d.h
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
extern bool Im2DColored;
|
||||
extern bool Im2DTextured;
|
||||
|
||||
extern rw::int32 Im2DPrimType;
|
||||
|
||||
extern rw::V2d ScreenSize;
|
||||
extern float Scale;
|
||||
|
||||
extern rw::RGBA SolidWhite;
|
||||
extern rw::RGBA SolidBlack;
|
||||
extern rw::RGBA SolidRed;
|
||||
extern rw::RGBA SolidGreen;
|
||||
extern rw::RGBA SolidBlue;
|
||||
extern rw::RGBA SolidYellow;
|
||||
extern rw::RGBA SolidPurple;
|
||||
extern rw::RGBA SolidCyan;
|
||||
|
||||
|
||||
void Im2DInitialize(rw::Camera *camera);
|
||||
void Im2DTerminate(void);
|
||||
void Im2DRender(void);
|
||||
void Im2DSize(rw::Camera *camera, rw::int32 w, rw::int32 h);
|
||||
|
||||
void LineListCreate(rw::Camera *camera);
|
||||
void LineListSetColor(bool white);
|
||||
void LineListRender(void);
|
||||
|
||||
void IndexedLineListCreate(rw::Camera *camera);
|
||||
void IndexedLineListSetColor(bool white);
|
||||
void IndexedLineListRender(void);
|
||||
|
||||
void PolyLineCreate(rw::Camera *camera);
|
||||
void PolyLineSetColor(bool white);
|
||||
void PolyLineRender(void);
|
||||
|
||||
void IndexedPolyLineCreate(rw::Camera *camera);
|
||||
void IndexedPolyLineSetColor(bool white);
|
||||
void IndexedPolyLineRender(void);
|
||||
|
||||
void TriListCreate(rw::Camera *camera);
|
||||
void TriListSetColor(bool white);
|
||||
void TriListRender(void);
|
||||
|
||||
void IndexedTriListCreate(rw::Camera *camera);
|
||||
void IndexedTriListSetColor(bool white);
|
||||
void IndexedTriListRender(void);
|
||||
|
||||
void TriStripCreate(rw::Camera *camera);
|
||||
void TriStripSetColor(bool white);
|
||||
void TriStripRender(void);
|
||||
|
||||
void IndexedTriStripCreate(rw::Camera *camera);
|
||||
void IndexedTriStripSetColor(bool white);
|
||||
void IndexedTriStripRender(void);
|
||||
|
||||
void TriFanCreate(rw::Camera *camera);
|
||||
void TriFanSetColor(bool white);
|
||||
void TriFanRender(void);
|
||||
|
||||
void IndexedTriFanCreate(rw::Camera *camera);
|
||||
void IndexedTriFanSetColor(bool white);
|
||||
void IndexedTriFanRender(void);
|
||||
159
vendor/librw/tools/im2d/linelist.cpp
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
float LineListData[32][4] = {
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.383f, 0.924f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.707f, 0.707f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.924f, 0.383f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.924f, -0.383f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.707f, -0.707f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.383f, -0.924f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, -1.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.383f, -0.924f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.707f, -0.707f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.924f, -0.383f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-1.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.924f, 0.383f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.707f, 0.707f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.383f, 0.924f, 1.000f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedLineListData[16][4] = {
|
||||
{-1.000f, 1.000f, 0.000f, 1.000f},
|
||||
{-0.500f, 1.000f, 0.250f, 1.000f},
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.500f, 1.000f, 0.750f, 1.000f},
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
|
||||
{-1.000f, 0.500f, 0.000f, 0.750f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-1.000f, -0.500f, 0.000f, 0.250f},
|
||||
|
||||
{ 1.000f, 0.500f, 1.000f, 0.750f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 1.000f, -0.500f, 1.000f, 0.250f},
|
||||
|
||||
{-1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-0.500f, -1.000f, 0.250f, 0.000f},
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
{ 0.500f, -1.000f, 0.750f, 0.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedLineListIndices[20] = {
|
||||
0, 11, 1, 12, 2, 13, 3, 14, 4, 15,
|
||||
0, 4, 5, 8, 6, 9, 7, 10, 11, 15
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im2DVertex LineList[32];
|
||||
rw::RWDEVICE::Im2DVertex IndexedLineList[16];
|
||||
|
||||
|
||||
void
|
||||
LineListCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 32; i++){
|
||||
LineList[i].setScreenX(ScreenSize.x/2.0f + LineListData[i][0]*Scale);
|
||||
LineList[i].setScreenY(ScreenSize.y/2.0f - LineListData[i][1]*Scale);
|
||||
LineList[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
LineList[i].setRecipCameraZ(recipZ);
|
||||
LineList[i].setU(LineListData[i][2], recipZ);
|
||||
LineList[i].setV(LineListData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineListSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidWhite;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 32; i += 2){
|
||||
LineList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
LineList[i+1].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineListRender(void)
|
||||
{
|
||||
rw::im2d::RenderPrimitive(rw::PRIMTYPELINELIST, LineList, 32);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedLineListCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 16; i++){
|
||||
IndexedLineList[i].setScreenX(ScreenSize.x/2.0f + IndexedLineListData[i][0]*Scale);
|
||||
IndexedLineList[i].setScreenY(ScreenSize.y/2.0f - IndexedLineListData[i][1]*Scale);
|
||||
IndexedLineList[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
IndexedLineList[i].setRecipCameraZ(recipZ);
|
||||
IndexedLineList[i].setU(IndexedLineListData[i][2], recipZ);
|
||||
IndexedLineList[i].setV(IndexedLineListData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedLineListSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
IndexedLineList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedLineListRender(void)
|
||||
{
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPELINELIST,
|
||||
IndexedLineList, 16, IndexedLineListIndices, 20);
|
||||
}
|
||||
254
vendor/librw/tools/im2d/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
|
||||
rw::RGBA ForegroundColor = { 200, 200, 200, 255 };
|
||||
rw::RGBA BackgroundColor = { 64, 64, 64, 0 };
|
||||
|
||||
rw::Camera *Camera;
|
||||
rw::Charset *Charset;
|
||||
|
||||
float TimeDelta;
|
||||
|
||||
rw::Camera*
|
||||
CreateCamera(void)
|
||||
{
|
||||
Camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
assert(Camera);
|
||||
|
||||
Camera->setNearPlane(0.1f);
|
||||
Camera->setFarPlane(10.0f);
|
||||
|
||||
return Camera;
|
||||
}
|
||||
|
||||
void
|
||||
Initialize(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Im2D example";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Initialize3D(void)
|
||||
{
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
Charset = rw::Charset::create(&ForegroundColor, &BackgroundColor);
|
||||
|
||||
Camera = CreateCamera();
|
||||
|
||||
Im2DInitialize(Camera);
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Terminate3D(void)
|
||||
{
|
||||
Im2DTerminate();
|
||||
|
||||
if(Camera){
|
||||
Camera->destroy();
|
||||
Camera = nil;
|
||||
}
|
||||
|
||||
if(Charset){
|
||||
Charset->destroy();
|
||||
Charset = nil;
|
||||
}
|
||||
|
||||
sk::TerminateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DisplayOnScreenInfo(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Gui(void)
|
||||
{
|
||||
static bool showWindow = true;
|
||||
ImGui::Begin("Im2D", &showWindow);
|
||||
|
||||
ImGui::RadioButton("Line-list", &Im2DPrimType, 0);
|
||||
ImGui::RadioButton("Line-list indexed", &Im2DPrimType, 1);
|
||||
ImGui::RadioButton("Poly-line", &Im2DPrimType, 2);
|
||||
ImGui::RadioButton("Poly-line indexed", &Im2DPrimType, 3);
|
||||
ImGui::RadioButton("Tri-list", &Im2DPrimType, 4);
|
||||
ImGui::RadioButton("Tri-list indexed", &Im2DPrimType, 5);
|
||||
ImGui::RadioButton("Tri-strip", &Im2DPrimType, 6);
|
||||
ImGui::RadioButton("Tri-strip indexed", &Im2DPrimType, 7);
|
||||
ImGui::RadioButton("Tri-fan", &Im2DPrimType, 8);
|
||||
ImGui::RadioButton("Tri-fan indexed", &Im2DPrimType, 9);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Checkbox("Textured", &Im2DTextured);
|
||||
if(ImGui::Checkbox("Colored", &Im2DColored)){
|
||||
LineListSetColor(!Im2DColored);
|
||||
IndexedLineListSetColor(!Im2DColored);
|
||||
PolyLineSetColor(!Im2DColored);
|
||||
IndexedPolyLineSetColor(!Im2DColored);
|
||||
TriListSetColor(!Im2DColored);
|
||||
IndexedTriListSetColor(!Im2DColored);
|
||||
TriStripSetColor(!Im2DColored);
|
||||
IndexedTriStripSetColor(!Im2DColored);
|
||||
TriFanSetColor(!Im2DColored);
|
||||
IndexedTriFanSetColor(!Im2DColored);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
Render(void)
|
||||
{
|
||||
Camera->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
|
||||
Camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(TimeDelta);
|
||||
|
||||
Im2DRender();
|
||||
DisplayOnScreenInfo();
|
||||
|
||||
Gui();
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
Camera->endUpdate();
|
||||
|
||||
Camera->showRaster(0);
|
||||
}
|
||||
|
||||
void
|
||||
Idle(float timeDelta)
|
||||
{
|
||||
TimeDelta = timeDelta;
|
||||
Render();
|
||||
}
|
||||
|
||||
int MouseX, MouseY;
|
||||
int MouseDeltaX, MouseDeltaY;
|
||||
int MouseButtons;
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseBtn(sk::MouseState *mouse)
|
||||
{
|
||||
MouseButtons = mouse->buttons;
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(sk::MouseState *mouse)
|
||||
{
|
||||
MouseDeltaX = mouse->posx - MouseX;
|
||||
MouseDeltaY = mouse->posy - MouseY;
|
||||
MouseX = mouse->posx;
|
||||
MouseY = mouse->posy;
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Initialize();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return Initialize3D() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
Terminate3D();
|
||||
return EVENTPROCESSED;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
if(!io.WantCaptureMouse){
|
||||
ms = (MouseState*)param;
|
||||
MouseBtn(ms);
|
||||
}else
|
||||
MouseButtons = 0;
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
MouseMove((MouseState*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
if(::Camera){
|
||||
sk::CameraSize(::Camera, r, 0.5f, 4.0f/3.0f);
|
||||
Im2DSize(::Camera, r->w, r->h);
|
||||
}
|
||||
break;
|
||||
case IDLE:
|
||||
Idle(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
132
vendor/librw/tools/im2d/polyline.cpp
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
float PolyLineData[16][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.672f, 0.672f, 0.836f, 0.836f},
|
||||
{ 0.900f, 0.000f, 0.950f, 0.500f},
|
||||
{ 0.601f, -0.601f, 0.800f, 0.200f},
|
||||
{ 0.000f, -0.800f, 0.500f, 0.100f},
|
||||
{-0.530f, -0.530f, 0.245f, 0.245f},
|
||||
{-0.700f, 0.000f, 0.150f, 0.500f},
|
||||
{-0.460f, 0.460f, 0.270f, 0.770f},
|
||||
{ 0.000f, 0.600f, 0.500f, 0.800f},
|
||||
{ 0.389f, 0.389f, 0.695f, 0.695f},
|
||||
{ 0.500f, 0.000f, 0.750f, 0.500f},
|
||||
{ 0.318f, -0.318f, 0.659f, 0.341f},
|
||||
{ 0.000f, -0.400f, 0.500f, 0.300f},
|
||||
{-0.247f, -0.247f, 0.376f, 0.376f},
|
||||
{-0.300f, 0.000f, 0.350f, 0.500f},
|
||||
{-0.177f, 0.177f, 0.411f, 0.589f}
|
||||
};
|
||||
|
||||
float IndexedPolyLineData[21][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
|
||||
{-0.200f, 0.600f, 0.400f, 0.800f},
|
||||
{ 0.200f, 0.600f, 0.600f, 0.800f},
|
||||
|
||||
{-0.400f, 0.200f, 0.300f, 0.600f},
|
||||
{ 0.000f, 0.200f, 0.500f, 0.600f},
|
||||
{ 0.400f, 0.200f, 0.700f, 0.600f},
|
||||
|
||||
{-0.600f, -0.200f, 0.200f, 0.400f},
|
||||
{-0.200f, -0.200f, 0.400f, 0.400f},
|
||||
{ 0.200f, -0.200f, 0.600f, 0.400f},
|
||||
{ 0.600f, -0.200f, 0.800f, 0.400f},
|
||||
|
||||
{-0.800f, -0.600f, 0.100f, 0.200f},
|
||||
{-0.400f, -0.600f, 0.300f, 0.200f},
|
||||
{ 0.000f, -0.600f, 0.500f, 0.200f},
|
||||
{ 0.400f, -0.600f, 0.700f, 0.200f},
|
||||
{ 0.800f, -0.600f, 0.900f, 0.200f},
|
||||
|
||||
{-1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-0.600f, -1.000f, 0.200f, 0.000f},
|
||||
{-0.200f, -1.000f, 0.400f, 0.000f},
|
||||
{ 0.200f, -1.000f, 0.600f, 0.000f},
|
||||
{ 0.600f, -1.000f, 0.800f, 0.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedPolyLineIndices[46] = {
|
||||
0, 2, 5, 4, 8, 5, 9, 8, 13, 9,
|
||||
14, 13, 19, 14, 20, 19, 18, 13, 12, 8,
|
||||
7, 12, 18, 17, 12, 11, 17, 16, 15, 10,
|
||||
16, 11, 10, 6, 11, 7, 6, 3, 7, 4,
|
||||
3, 1, 4, 2, 1, 0
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im2DVertex PolyLine[16];
|
||||
rw::RWDEVICE::Im2DVertex IndexedPolyLine[21];
|
||||
|
||||
|
||||
void
|
||||
PolyLineCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 16; i++){
|
||||
PolyLine[i].setScreenX(ScreenSize.x/2.0f + PolyLineData[i][0]*Scale);
|
||||
PolyLine[i].setScreenY(ScreenSize.y/2.0f - PolyLineData[i][1]*Scale);
|
||||
PolyLine[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
PolyLine[i].setRecipCameraZ(recipZ);
|
||||
PolyLine[i].setU(PolyLineData[i][2], recipZ);
|
||||
PolyLine[i].setV(PolyLineData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PolyLineSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidBlue;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
PolyLine[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
PolyLineRender(void)
|
||||
{
|
||||
rw::im2d::RenderPrimitive(rw::PRIMTYPEPOLYLINE, PolyLine, 16);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedPolyLineCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 21; i++){
|
||||
IndexedPolyLine[i].setScreenX(ScreenSize.x/2.0f + IndexedPolyLineData[i][0]*Scale);
|
||||
IndexedPolyLine[i].setScreenY(ScreenSize.y/2.0f - IndexedPolyLineData[i][1]*Scale);
|
||||
IndexedPolyLine[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
IndexedPolyLine[i].setRecipCameraZ(recipZ);
|
||||
IndexedPolyLine[i].setU(IndexedPolyLineData[i][2], recipZ);
|
||||
IndexedPolyLine[i].setV(IndexedPolyLineData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedPolyLineSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidBlue;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 21; i++)
|
||||
IndexedPolyLine[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedPolyLineRender(void)
|
||||
{
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPEPOLYLINE,
|
||||
IndexedPolyLine, 21, IndexedPolyLineIndices, 46);
|
||||
}
|
||||
119
vendor/librw/tools/im2d/trifan.cpp
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
float TriFanData[17][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{-0.383f, 0.924f, 0.308f, 0.962f},
|
||||
{-0.707f, 0.707f, 0.146f, 0.854f},
|
||||
{-0.924f, 0.383f, 0.038f, 0.692f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.924f, -0.383f, 0.038f, 0.308f},
|
||||
{-0.707f, -0.707f, 0.146f, 0.146f},
|
||||
{-0.383f, -0.924f, 0.308f, 0.038f},
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
{ 0.383f, -0.924f, 0.692f, 0.038f},
|
||||
{ 0.707f, -0.707f, 0.854f, 0.146f},
|
||||
{ 0.924f, -0.383f, 0.962f, 0.308f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.924f, 0.383f, 0.962f, 0.692f},
|
||||
{ 0.707f, 0.707f, 0.854f, 0.854f},
|
||||
{ 0.383f, 0.924f, 0.692f, 0.962f},
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedTriFanData[16][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{-0.383f, 0.924f, 0.308f, 0.962f},
|
||||
{-0.707f, 0.707f, 0.146f, 0.854f},
|
||||
{-0.924f, 0.383f, 0.038f, 0.692f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.924f, -0.383f, 0.038f, 0.308f},
|
||||
{-0.707f, -0.707f, 0.146f, 0.146f},
|
||||
{-0.383f, -0.924f, 0.308f, 0.038f},
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
{ 0.383f, -0.924f, 0.692f, 0.038f},
|
||||
{ 0.707f, -0.707f, 0.854f, 0.146f},
|
||||
{ 0.924f, -0.383f, 0.962f, 0.308f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.924f, 0.383f, 0.962f, 0.692f},
|
||||
{ 0.707f, 0.707f, 0.854f, 0.854f},
|
||||
{ 0.383f, 0.924f, 0.692f, 0.962f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriFanIndices[17] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im2DVertex TriFan[17];
|
||||
rw::RWDEVICE::Im2DVertex IndexedTriFan[16];
|
||||
|
||||
|
||||
void
|
||||
TriFanCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 17; i++){
|
||||
TriFan[i].setScreenX(ScreenSize.x/2.0f + TriFanData[i][0]*Scale);
|
||||
TriFan[i].setScreenY(ScreenSize.y/2.0f - TriFanData[i][1]*Scale);
|
||||
TriFan[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
TriFan[i].setRecipCameraZ(recipZ);
|
||||
TriFan[i].setU(TriFanData[i][2], recipZ);
|
||||
TriFan[i].setV(TriFanData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriFanSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidYellow;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 17; i++)
|
||||
TriFan[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
TriFanRender(void)
|
||||
{
|
||||
rw::im2d::RenderPrimitive(rw::PRIMTYPETRIFAN, TriFan, 17);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriFanCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 16; i++){
|
||||
IndexedTriFan[i].setScreenX(ScreenSize.x/2.0f + IndexedTriFanData[i][0]*Scale);
|
||||
IndexedTriFan[i].setScreenY(ScreenSize.y/2.0f - IndexedTriFanData[i][1]*Scale);
|
||||
IndexedTriFan[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
IndexedTriFan[i].setRecipCameraZ(recipZ);
|
||||
IndexedTriFan[i].setU(IndexedTriFanData[i][2], recipZ);
|
||||
IndexedTriFan[i].setV(IndexedTriFanData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriFanSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidGreen;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
IndexedTriFan[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriFanRender(void)
|
||||
{
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRIFAN,
|
||||
IndexedTriFan, 16, IndexedTriFanIndices, 17);
|
||||
}
|
||||
166
vendor/librw/tools/im2d/trilist.cpp
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
float TriListData[18][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{-0.500f, 0.500f, 0.250f, 0.750f},
|
||||
{ 0.500f, 0.500f, 0.750f, 0.750f},
|
||||
|
||||
{-0.500f, 0.500f, 0.250f, 0.750f},
|
||||
{ 0.500f, -0.500f, 0.750f, 0.250f},
|
||||
{ 0.500f, 0.500f, 0.750f, 0.750f},
|
||||
|
||||
{ 0.500f, 0.500f, 0.750f, 0.750f},
|
||||
{ 0.500f, -0.500f, 0.750f, 0.250f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
|
||||
{ 0.500f, -0.500f, 0.750f, 0.250f},
|
||||
{-0.500f, -0.500f, 0.250f, 0.250f},
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
|
||||
{ 0.500f, -0.500f, 0.750f, 1.250f},
|
||||
{-0.500f, 0.500f, 0.250f, 1.750f},
|
||||
{-0.500f, -0.500f, 0.250f, 1.250f},
|
||||
|
||||
{-0.500f, -0.500f, 0.250f, 0.250f},
|
||||
{-0.500f, 0.500f, 0.250f, 0.750f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f}
|
||||
};
|
||||
|
||||
float IndexedTriListData[21][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
|
||||
{-0.200f, 0.600f, 0.400f, 0.800f},
|
||||
{ 0.200f, 0.600f, 0.600f, 0.800f},
|
||||
|
||||
{-0.400f, 0.200f, 0.300f, 0.600f},
|
||||
{ 0.000f, 0.200f, 0.500f, 0.600f},
|
||||
{ 0.400f, 0.200f, 0.300f, 0.600f},
|
||||
|
||||
{-0.600f, -0.200f, 0.200f, 0.400f},
|
||||
{-0.200f, -0.200f, 0.400f, 0.400f},
|
||||
{ 0.200f, -0.200f, 0.600f, 0.400f},
|
||||
{ 0.600f, -0.200f, 0.800f, 0.400f},
|
||||
|
||||
{-0.800f, -0.600f, 0.100f, 0.200f},
|
||||
{-0.400f, -0.600f, 0.300f, 0.200f},
|
||||
{ 0.000f, -0.600f, 0.500f, 0.200f},
|
||||
{ 0.400f, -0.600f, 0.700f, 0.200f},
|
||||
{ 0.800f, -0.600f, 0.900f, 0.200f},
|
||||
|
||||
{-1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-0.600f, -1.000f, 0.200f, 0.000f},
|
||||
{-0.200f, -1.000f, 0.400f, 0.000f},
|
||||
{ 0.200f, -1.000f, 0.600f, 0.000f},
|
||||
{ 0.600f, -1.000f, 0.800f, 0.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriListIndices[45] = {
|
||||
0, 1, 2,
|
||||
1, 3, 4, 2, 4, 5,
|
||||
3, 6, 7, 4, 7, 8, 5, 8, 9,
|
||||
6, 10, 11, 7, 11, 12, 8, 12, 13, 9, 13, 14,
|
||||
10, 15, 16, 11, 16, 17, 12, 17, 18, 13, 18, 19, 14, 19, 20
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im2DVertex TriList[18];
|
||||
rw::RWDEVICE::Im2DVertex IndexedTriList[21];
|
||||
|
||||
|
||||
void
|
||||
TriListCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 18; i++){
|
||||
TriList[i].setScreenX(ScreenSize.x/2.0f + TriListData[i][0]*Scale);
|
||||
TriList[i].setScreenY(ScreenSize.y/2.0f - TriListData[i][1]*Scale);
|
||||
TriList[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
TriList[i].setRecipCameraZ(recipZ);
|
||||
TriList[i].setU(TriListData[i][2], recipZ);
|
||||
TriList[i].setV(TriListData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriListSetColor(bool white)
|
||||
{
|
||||
int i;
|
||||
rw::RGBA SolidColor1 = SolidBlue;
|
||||
rw::RGBA SolidColor2 = SolidRed;
|
||||
rw::RGBA SolidColor3 = SolidGreen;
|
||||
rw::RGBA SolidColor4 = SolidYellow;
|
||||
rw::RGBA SolidColor5 = SolidPurple;
|
||||
rw::RGBA SolidColor6 = SolidCyan;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
SolidColor4 = SolidWhite;
|
||||
SolidColor5 = SolidWhite;
|
||||
SolidColor6 = SolidWhite;
|
||||
}
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
TriList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(; i < 6; i++)
|
||||
TriList[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
for(; i < 9; i++)
|
||||
TriList[i].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
for(; i < 12; i++)
|
||||
TriList[i].setColor(SolidColor4.red, SolidColor4.green,
|
||||
SolidColor4.blue, SolidColor4.alpha);
|
||||
for(; i < 15; i++)
|
||||
TriList[i].setColor(SolidColor5.red, SolidColor5.green,
|
||||
SolidColor5.blue, SolidColor5.alpha);
|
||||
for(; i < 18; i++)
|
||||
TriList[i].setColor(SolidColor6.red, SolidColor6.green,
|
||||
SolidColor6.blue, SolidColor6.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
TriListRender(void)
|
||||
{
|
||||
rw::im2d::RenderPrimitive(rw::PRIMTYPETRILIST, TriList, 18);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriListCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 21; i++){
|
||||
IndexedTriList[i].setScreenX(ScreenSize.x/2.0f + IndexedTriListData[i][0]*Scale);
|
||||
IndexedTriList[i].setScreenY(ScreenSize.y/2.0f - IndexedTriListData[i][1]*Scale);
|
||||
IndexedTriList[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
IndexedTriList[i].setRecipCameraZ(recipZ);
|
||||
IndexedTriList[i].setU(IndexedTriListData[i][2], recipZ);
|
||||
IndexedTriList[i].setV(IndexedTriListData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriListSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidBlue;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 21; i++)
|
||||
IndexedTriList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriListRender(void)
|
||||
{
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
IndexedTriList, 21, IndexedTriListIndices, 45);
|
||||
}
|
||||
130
vendor/librw/tools/im2d/tristrip.cpp
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im2d.h"
|
||||
|
||||
float TriStripData[18][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.000f, 0.500f, 0.500f, 0.750f},
|
||||
|
||||
{ 0.707f, 0.707f, 0.853f, 0.853f},
|
||||
{ 0.354f, 0.354f, 0.677f, 0.677f},
|
||||
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.500f, 0.000f, 0.750f, 0.500f},
|
||||
|
||||
{ 0.707f, -0.707f, 0.853f, 0.147f},
|
||||
{ 0.354f, -0.354f, 0.677f, 0.323f},
|
||||
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
{ 0.000f, -0.500f, 0.500f, 0.250f},
|
||||
|
||||
{-0.707f, -0.707f, 0.147f, 0.147f},
|
||||
{-0.354f, -0.354f, 0.323f, 0.323f},
|
||||
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.500f, 0.000f, 0.250f, 0.500f},
|
||||
|
||||
{-0.707f, 0.707f, 0.147f, 0.853f},
|
||||
{-0.354f, 0.354f, 0.323f, 0.677f},
|
||||
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.000f, 0.500f, 0.500f, 0.750f}
|
||||
};
|
||||
|
||||
float IndexedTriStripData[16][4] = {
|
||||
{ 0.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.707f, 0.707f, 0.853f, 0.853f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.707f, -0.707f, 0.853f, 0.147f},
|
||||
{ 0.000f, -1.000f, 0.500f, 0.000f},
|
||||
{-0.707f, -0.707f, 0.147f, 0.147f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.707f, 0.707f, 0.147f, 0.853f},
|
||||
|
||||
{ 0.000f, 0.500f, 0.500f, 0.750f},
|
||||
{ 0.354f, 0.354f, 0.677f, 0.677f},
|
||||
{ 0.500f, 0.000f, 0.750f, 0.500f},
|
||||
{ 0.354f, -0.354f, 0.677f, 0.323f},
|
||||
{ 0.000f, -0.500f, 0.500f, 0.250f},
|
||||
{-0.354f, -0.354f, 0.323f, 0.323f},
|
||||
{-0.500f, 0.000f, 0.250f, 0.500f},
|
||||
{-0.354f, 0.354f, 0.323f, 0.677f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriStripIndices[18] = {
|
||||
0, 8, 1, 9, 2, 10, 3, 11,
|
||||
4, 12, 5, 13, 6, 14, 7, 15, 0, 8
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im2DVertex TriStrip[18];
|
||||
rw::RWDEVICE::Im2DVertex IndexedTriStrip[16];
|
||||
|
||||
|
||||
void
|
||||
TriStripCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 18; i++){
|
||||
TriStrip[i].setScreenX(ScreenSize.x/2.0f + TriStripData[i][0]*Scale);
|
||||
TriStrip[i].setScreenY(ScreenSize.y/2.0f - TriStripData[i][1]*Scale);
|
||||
TriStrip[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
TriStrip[i].setRecipCameraZ(recipZ);
|
||||
TriStrip[i].setU(TriStripData[i][2], recipZ);
|
||||
TriStrip[i].setV(TriStripData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriStripSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidPurple;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 18; i++)
|
||||
TriStrip[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
TriStripRender(void)
|
||||
{
|
||||
rw::im2d::RenderPrimitive(rw::PRIMTYPETRISTRIP, TriStrip, 18);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriStripCreate(rw::Camera *camera)
|
||||
{
|
||||
float recipZ = 1.0f/camera->nearPlane;
|
||||
for(int i = 0; i < 16; i++){
|
||||
IndexedTriStrip[i].setScreenX(ScreenSize.x/2.0f + IndexedTriStripData[i][0]*Scale);
|
||||
IndexedTriStrip[i].setScreenY(ScreenSize.y/2.0f - IndexedTriStripData[i][1]*Scale);
|
||||
IndexedTriStrip[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
IndexedTriStrip[i].setRecipCameraZ(recipZ);
|
||||
IndexedTriStrip[i].setU(IndexedTriStripData[i][2], recipZ);
|
||||
IndexedTriStrip[i].setV(IndexedTriStripData[i][3], recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriStripSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidCyan;
|
||||
|
||||
if(white)
|
||||
SolidColor1 = SolidWhite;
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
IndexedTriStrip[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriStripRender(void)
|
||||
{
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
IndexedTriStrip, 16, IndexedTriStripIndices, 18);
|
||||
}
|
||||
23
vendor/librw/tools/im3d/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
add_executable(im3d WIN32
|
||||
im3d.cpp
|
||||
linelist.cpp
|
||||
main.cpp
|
||||
polyline.cpp
|
||||
trifan.cpp
|
||||
trilist.cpp
|
||||
tristrip.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(im3d
|
||||
PRIVATE
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET im3d POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:im3d>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/files" "$<TARGET_FILE_DIR:im3d>/files"
|
||||
)
|
||||
|
||||
librw_platform_target(im3d)
|
||||
BIN
vendor/librw/tools/im3d/files/whiteash.png
vendored
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
138
vendor/librw/tools/im3d/im3d.cpp
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
bool Im3DColored = true;
|
||||
bool Im3DTextured;
|
||||
|
||||
rw::int32 Im3DPrimType;
|
||||
|
||||
rw::RGBA SolidWhite = {255, 255, 255, 255};
|
||||
rw::RGBA SolidBlack = {0, 0, 0, 255};
|
||||
rw::RGBA SolidRed = {200, 64, 64, 255};
|
||||
rw::RGBA SolidGreen = {64, 200, 64, 255};
|
||||
rw::RGBA SolidBlue = {64, 64, 200, 255};
|
||||
rw::RGBA SolidYellow = {200, 200, 64, 255};
|
||||
rw::RGBA SolidPurple = {200, 64, 200, 255};
|
||||
rw::RGBA SolidCyan = {64, 200, 200, 255};
|
||||
|
||||
rw::Matrix *Im3DMatrix;
|
||||
rw::Texture *Im3DTexture;
|
||||
|
||||
void
|
||||
Im3DInitialize(void)
|
||||
{
|
||||
Im3DMatrix = rw::Matrix::create();
|
||||
assert(Im3DMatrix);
|
||||
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::V3d pos = rw::scale(cameraMatrix->at, 6.0f);
|
||||
Im3DMatrix->rotate(&cameraMatrix->up, 30.0f);
|
||||
Im3DMatrix->translate(&pos);
|
||||
|
||||
rw::Image::setSearchPath("files/");
|
||||
Im3DTexture = rw::Texture::read("whiteash", nil);
|
||||
|
||||
LineListCreate();
|
||||
LineListSetColor(!Im3DColored);
|
||||
|
||||
IndexedLineListCreate();
|
||||
IndexedLineListSetColor(!Im3DColored);
|
||||
|
||||
PolyLineCreate();
|
||||
PolyLineSetColor(!Im3DColored);
|
||||
|
||||
IndexedPolyLineCreate();
|
||||
IndexedPolyLineSetColor(!Im3DColored);
|
||||
|
||||
TriListCreate();
|
||||
TriListSetColor(!Im3DColored);
|
||||
|
||||
IndexedTriListCreate();
|
||||
IndexedTriListSetColor(!Im3DColored);
|
||||
|
||||
TriStripCreate();
|
||||
TriStripSetColor(!Im3DColored);
|
||||
|
||||
IndexedTriStripCreate();
|
||||
IndexedTriStripSetColor(!Im3DColored);
|
||||
|
||||
TriFanCreate();
|
||||
TriFanSetColor(!Im3DColored);
|
||||
|
||||
IndexedTriFanCreate();
|
||||
IndexedTriFanSetColor(!Im3DColored);
|
||||
}
|
||||
|
||||
void
|
||||
Im3DTerminate(void)
|
||||
{
|
||||
if(Im3DMatrix){
|
||||
Im3DMatrix->destroy();
|
||||
Im3DMatrix = nil;
|
||||
}
|
||||
|
||||
if(Im3DTexture){
|
||||
Im3DTexture->destroy();
|
||||
Im3DTexture = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Im3DRender(void)
|
||||
{
|
||||
rw::SetRenderState(rw::ZTESTENABLE, 1);
|
||||
rw::SetRenderState(rw::ZWRITEENABLE, 1);
|
||||
rw::SetRenderState(rw::SRCBLEND, rw::BLENDONE);
|
||||
rw::SetRenderState(rw::DESTBLEND, rw::BLENDZERO);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::FilterMode::LINEAR);
|
||||
rw::SetRenderState(rw::CULLMODE, rw::CULLBACK);
|
||||
|
||||
rw::uint32 flags;
|
||||
if(Im3DTextured){
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, Im3DTexture->raster);
|
||||
flags = rw::im3d::VERTEXUV | rw::im3d::ALLOPAQUE;
|
||||
}else{
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||
flags = rw::im3d::ALLOPAQUE;
|
||||
}
|
||||
|
||||
switch(Im3DPrimType){
|
||||
case 0: LineListRender(Im3DMatrix, flags); break;
|
||||
case 1: IndexedLineListRender(Im3DMatrix, flags); break;
|
||||
case 2: PolyLineRender(Im3DMatrix, flags); break;
|
||||
case 3: IndexedPolyLineRender(Im3DMatrix, flags); break;
|
||||
case 4: TriListRender(Im3DMatrix, flags); break;
|
||||
case 5: IndexedTriListRender(Im3DMatrix, flags); break;
|
||||
case 6: TriStripRender(Im3DMatrix, flags); break;
|
||||
case 7: IndexedTriStripRender(Im3DMatrix, flags); break;
|
||||
case 8: TriFanRender(Im3DMatrix, flags); break;
|
||||
case 9: IndexedTriFanRender(Im3DMatrix, flags); break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Im3DRotate(float xAngle, float yAngle)
|
||||
{
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::V3d pos = Im3DMatrix->pos;
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
Im3DMatrix->translate(&pos);
|
||||
|
||||
Im3DMatrix->rotate(&cameraMatrix->up, xAngle);
|
||||
Im3DMatrix->rotate(&cameraMatrix->right, yAngle);
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
Im3DMatrix->translate(&pos);
|
||||
}
|
||||
|
||||
void
|
||||
Im3DTranslateZ(float zDelta)
|
||||
{
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::V3d delta = rw::scale(cameraMatrix->at, zDelta);
|
||||
Im3DMatrix->translate(&delta);
|
||||
}
|
||||
|
||||
62
vendor/librw/tools/im3d/im3d.h
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
extern rw::Camera *Camera;
|
||||
|
||||
extern bool Im3DColored;
|
||||
extern bool Im3DTextured;
|
||||
|
||||
extern rw::int32 Im3DPrimType;
|
||||
|
||||
extern rw::RGBA SolidWhite;
|
||||
extern rw::RGBA SolidBlack;
|
||||
extern rw::RGBA SolidRed;
|
||||
extern rw::RGBA SolidGreen;
|
||||
extern rw::RGBA SolidBlue;
|
||||
extern rw::RGBA SolidYellow;
|
||||
extern rw::RGBA SolidPurple;
|
||||
extern rw::RGBA SolidCyan;
|
||||
|
||||
|
||||
void Im3DInitialize(void);
|
||||
void Im3DTerminate(void);
|
||||
void Im3DRender(void);
|
||||
void Im3DRotate(float xAngle, float yAngle);
|
||||
void Im3DTranslateZ(float zDelta);
|
||||
|
||||
void LineListCreate(void);
|
||||
void LineListSetColor(bool white);
|
||||
void LineListRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void IndexedLineListCreate(void);
|
||||
void IndexedLineListSetColor(bool white);
|
||||
void IndexedLineListRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void PolyLineCreate(void);
|
||||
void PolyLineSetColor(bool white);
|
||||
void PolyLineRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void IndexedPolyLineCreate(void);
|
||||
void IndexedPolyLineSetColor(bool white);
|
||||
void IndexedPolyLineRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void TriListCreate(void);
|
||||
void TriListSetColor(bool white);
|
||||
void TriListRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void IndexedTriListCreate(void);
|
||||
void IndexedTriListSetColor(bool white);
|
||||
void IndexedTriListRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void TriStripCreate(void);
|
||||
void TriStripSetColor(bool white);
|
||||
void TriStripRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void IndexedTriStripCreate(void);
|
||||
void IndexedTriStripSetColor(bool white);
|
||||
void IndexedTriStripRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void TriFanCreate(void);
|
||||
void TriFanSetColor(bool white);
|
||||
void TriFanRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
|
||||
void IndexedTriFanCreate(void);
|
||||
void IndexedTriFanSetColor(bool white);
|
||||
void IndexedTriFanRender(rw::Matrix *transform, rw::uint32 transformFlags);
|
||||
176
vendor/librw/tools/im3d/linelist.cpp
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
float LineListData[28][5] = {
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, -1.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 0.000f, 1.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 0.000f, -1.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, 0.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-1.000f, 0.000f, 0.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.577f, 0.577f, 0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.577f, -0.577f, 0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.577f, 0.577f, -0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.577f, -0.577f, -0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.577f, -0.577f, -0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.577f, 0.577f, -0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.577f, -0.577f, 0.577f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.577f, 0.577f, 0.577f, 1.000f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedLineListData[18][5] = {
|
||||
{ 0.000f, 1.000f, 0.000f, 0.000f, 0.000f},
|
||||
|
||||
{ 0.577f, 0.577f, 0.577f, 0.000f, 0.000f},
|
||||
{ 0.577f, 0.577f, -0.577f, 0.000f, 0.000f},
|
||||
{-0.577f, 0.577f, -0.577f, 0.000f, 0.000f},
|
||||
{-0.577f, 0.577f, 0.577f, 0.000f, 0.000f},
|
||||
|
||||
{ 0.000f, 0.000f, 1.000f, 0.000f, 0.000f},
|
||||
{ 0.707f, 0.000f, 0.707f, 0.000f, 0.000f},
|
||||
{ 1.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{ 0.707f, 0.000f, -0.707f, 0.000f, 0.000f},
|
||||
{ 0.000f, 0.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-0.707f, 0.000f, -0.707f, 0.000f, 0.000f},
|
||||
{-1.000f, 0.000f, 0.000f, 0.000f, 0.000f},
|
||||
{-0.707f, 0.000f, 0.707f, 0.000f, 0.000f},
|
||||
|
||||
{ 0.577f, -0.577f, 0.577f, 0.000f, 0.000f},
|
||||
{ 0.577f, -0.577f, -0.577f, 0.000f, 0.000f},
|
||||
{-0.577f, -0.577f, -0.577f, 0.000f, 0.000f},
|
||||
{-0.577f, -0.577f, 0.577f, 0.000f, 0.000f},
|
||||
|
||||
{ 0.000f, -1.000f, 0.000f, 0.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedLineListIndices[96] = {
|
||||
0,1, 0,2, 0,3, 0,4, 1,2, 2,3, 3,4, 4,1,
|
||||
|
||||
1,5, 1,6, 1,7, 2,7, 2,8, 2,9, 3,9, 3,10, 3,11, 4,11, 4,12, 4,5,
|
||||
5,6, 6,7, 7,8, 8,9, 9,10, 10,11, 11,12, 12,5,
|
||||
13,5, 13,6, 13,7, 14,7, 14,8, 14,9, 15,9, 15,10, 15,11, 16,11, 16,12, 16,5,
|
||||
|
||||
17,13, 17,14, 17,15, 17,16, 13,14, 14,15, 15,16, 16,13
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im3DVertex LineList[28];
|
||||
rw::RWDEVICE::Im3DVertex IndexedLineList[18];
|
||||
|
||||
|
||||
void
|
||||
LineListCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 28; i++){
|
||||
LineList[i].setX(LineListData[i][0]);
|
||||
LineList[i].setY(LineListData[i][1]);
|
||||
LineList[i].setZ(LineListData[i][2]);
|
||||
LineList[i].setU(LineListData[i][3]);
|
||||
LineList[i].setV(LineListData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineListSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidWhite;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 28; i += 2){
|
||||
LineList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
LineList[i+1].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LineListRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(LineList, 28, transform, transformFlags);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPELINELIST);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedLineListCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 18; i++){
|
||||
IndexedLineList[i].setX(IndexedLineListData[i][0]);
|
||||
IndexedLineList[i].setY(IndexedLineListData[i][1]);
|
||||
IndexedLineList[i].setZ(IndexedLineListData[i][2]);
|
||||
IndexedLineList[i].setU(IndexedLineListData[i][3]);
|
||||
IndexedLineList[i].setV(IndexedLineListData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedLineListSetColor(bool white)
|
||||
{
|
||||
int i;
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidGreen;
|
||||
rw::RGBA SolidColor3 = SolidBlue;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
}
|
||||
|
||||
IndexedLineList[0].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(i = 1; i < 5; i++)
|
||||
IndexedLineList[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
for(; i < 13; i++)
|
||||
IndexedLineList[i].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
for(; i < 17; i++)
|
||||
IndexedLineList[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
IndexedLineList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedLineListRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(IndexedLineList, 18, transform, transformFlags);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPELINELIST, IndexedLineListIndices, 96);
|
||||
rw::im3d::End();
|
||||
}
|
||||
268
vendor/librw/tools/im3d/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
|
||||
rw::RGBA ForegroundColor = { 200, 200, 200, 255 };
|
||||
rw::RGBA BackgroundColor = { 64, 64, 64, 0 };
|
||||
|
||||
rw::Camera *Camera;
|
||||
rw::Charset *Charset;
|
||||
|
||||
float TimeDelta;
|
||||
|
||||
rw::Camera*
|
||||
CreateCamera(void)
|
||||
{
|
||||
Camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
assert(Camera);
|
||||
|
||||
Camera->setNearPlane(0.1f);
|
||||
Camera->setFarPlane(50.0f);
|
||||
|
||||
return Camera;
|
||||
}
|
||||
|
||||
void
|
||||
Initialize(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Im3D example";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Initialize3D(void)
|
||||
{
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
Charset = rw::Charset::create(&ForegroundColor, &BackgroundColor);
|
||||
|
||||
Camera = CreateCamera();
|
||||
|
||||
Im3DInitialize();
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
rw::Rect r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.w = sk::globals.width;
|
||||
r.h = sk::globals.height;
|
||||
sk::CameraSize(::Camera, &r, 0.5f, 4.0f/3.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Terminate3D(void)
|
||||
{
|
||||
Im3DTerminate();
|
||||
|
||||
if(Camera){
|
||||
Camera->destroy();
|
||||
Camera = nil;
|
||||
}
|
||||
|
||||
if(Charset){
|
||||
Charset->destroy();
|
||||
Charset = nil;
|
||||
}
|
||||
|
||||
sk::TerminateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DisplayOnScreenInfo(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Gui(void)
|
||||
{
|
||||
static bool showWindow = true;
|
||||
ImGui::Begin("Im2D", &showWindow);
|
||||
|
||||
ImGui::RadioButton("Line-list", &Im3DPrimType, 0);
|
||||
ImGui::RadioButton("Line-list indexed", &Im3DPrimType, 1);
|
||||
ImGui::RadioButton("Poly-line", &Im3DPrimType, 2);
|
||||
ImGui::RadioButton("Poly-line indexed", &Im3DPrimType, 3);
|
||||
ImGui::RadioButton("Tri-list", &Im3DPrimType, 4);
|
||||
ImGui::RadioButton("Tri-list indexed", &Im3DPrimType, 5);
|
||||
ImGui::RadioButton("Tri-strip", &Im3DPrimType, 6);
|
||||
ImGui::RadioButton("Tri-strip indexed", &Im3DPrimType, 7);
|
||||
ImGui::RadioButton("Tri-fan", &Im3DPrimType, 8);
|
||||
ImGui::RadioButton("Tri-fan indexed", &Im3DPrimType, 9);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Checkbox("Textured", &Im3DTextured);
|
||||
if(ImGui::Checkbox("Colored", &Im3DColored)){
|
||||
LineListSetColor(!Im3DColored);
|
||||
IndexedLineListSetColor(!Im3DColored);
|
||||
PolyLineSetColor(!Im3DColored);
|
||||
IndexedPolyLineSetColor(!Im3DColored);
|
||||
TriListSetColor(!Im3DColored);
|
||||
IndexedTriListSetColor(!Im3DColored);
|
||||
TriStripSetColor(!Im3DColored);
|
||||
IndexedTriStripSetColor(!Im3DColored);
|
||||
TriFanSetColor(!Im3DColored);
|
||||
IndexedTriFanSetColor(!Im3DColored);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
Render(void)
|
||||
{
|
||||
Camera->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
|
||||
Camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(TimeDelta);
|
||||
|
||||
Im3DRender();
|
||||
DisplayOnScreenInfo();
|
||||
|
||||
Gui();
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
Camera->endUpdate();
|
||||
|
||||
Camera->showRaster(0);
|
||||
}
|
||||
|
||||
void
|
||||
Idle(float timeDelta)
|
||||
{
|
||||
TimeDelta = timeDelta;
|
||||
Render();
|
||||
}
|
||||
|
||||
int MouseX, MouseY;
|
||||
int MouseDeltaX, MouseDeltaY;
|
||||
int MouseButtons;
|
||||
|
||||
bool Rotate, Translate;
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseBtn(sk::MouseState *mouse)
|
||||
{
|
||||
MouseButtons = mouse->buttons;
|
||||
Rotate = !!(MouseButtons&1);
|
||||
Translate = !!(MouseButtons&4);
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(sk::MouseState *mouse)
|
||||
{
|
||||
MouseDeltaX = mouse->posx - MouseX;
|
||||
MouseDeltaY = mouse->posy - MouseY;
|
||||
MouseX = mouse->posx;
|
||||
MouseY = mouse->posy;
|
||||
if(Rotate)
|
||||
Im3DRotate(MouseDeltaX, -MouseDeltaY);
|
||||
if(Translate)
|
||||
Im3DTranslateZ(-MouseDeltaY*0.1f);
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Initialize();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return Initialize3D() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
Terminate3D();
|
||||
return EVENTPROCESSED;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
if(!io.WantCaptureMouse){
|
||||
ms = (MouseState*)param;
|
||||
MouseBtn(ms);
|
||||
}else
|
||||
MouseButtons = 0;
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
MouseMove((MouseState*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
if(::Camera){
|
||||
sk::CameraSize(::Camera, r, 0.5f, 4.0f/3.0f);
|
||||
}
|
||||
break;
|
||||
case IDLE:
|
||||
Idle(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
157
vendor/librw/tools/im3d/polyline.cpp
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
float PolyLineData[21][5] = {
|
||||
{ 0.000f, 1.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 0.707f, 0.707f, 0.900f, 0.854f, 0.854f},
|
||||
{ 1.000f, 0.000f, 0.800f, 1.000f, 0.500f},
|
||||
{ 0.707f, -0.707f, 0.700f, 0.854f, 0.146f},
|
||||
{ 0.000f, -1.000f, 0.600f, 0.500f, 0.000f},
|
||||
{-0.707f, -0.707f, 0.500f, 0.146f, 0.146f},
|
||||
{-1.000f, -0.000f, 0.400f, 0.000f, 0.500f},
|
||||
{-0.707f, 0.707f, 0.300f, 0.146f, 0.854f},
|
||||
|
||||
{ 0.000f, 1.000f, 0.200f, 0.500f, 1.000f},
|
||||
{ 0.707f, 0.707f, 0.100f, 0.854f, 0.854f},
|
||||
{ 1.000f, 0.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.707f, -0.707f, -0.100f, 0.854f, 0.146f},
|
||||
{ 0.000f, -1.000f, -0.200f, 0.500f, 0.000f},
|
||||
{-0.707f, -0.707f, -0.300f, 0.146f, 0.146f},
|
||||
{-1.000f, -0.000f, -0.400f, 0.000f, 0.500f},
|
||||
{-0.707f, 0.707f, -0.500f, 0.146f, 0.854f},
|
||||
|
||||
{ 0.000f, 1.000f, -0.600f, 0.500f, 1.000f},
|
||||
{ 0.707f, 0.707f, -0.700f, 0.854f, 0.854f},
|
||||
{ 1.000f, 0.000f, -0.800f, 1.000f, 0.500f},
|
||||
{ 0.707f, -0.707f, -0.900f, 0.854f, 0.146f},
|
||||
{ 0.000f, -1.000f, -1.000f, 0.500f, 0.000f}
|
||||
};
|
||||
|
||||
float IndexedPolyLineData[8][5] = {
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.500f, 0.000f},
|
||||
|
||||
{ 1.000f, 1.000f, -1.000f, 0.500f, 0.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 0.500f, 1.000f},
|
||||
{-1.000f, -1.000f, -1.000f, 0.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedPolyLineIndices[25] = {
|
||||
0, 1, 2, 3, 0, 2, 6, 5, 1, 3, 7, 4, 0, 5, 4, 6, 1, 4, 3, 6, 7, 5, 2, 7, 0
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im3DVertex PolyLine[21];
|
||||
rw::RWDEVICE::Im3DVertex IndexedPolyLine[8];
|
||||
|
||||
|
||||
void
|
||||
PolyLineCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 21; i++){
|
||||
PolyLine[i].setX(PolyLineData[i][0]);
|
||||
PolyLine[i].setY(PolyLineData[i][1]);
|
||||
PolyLine[i].setZ(PolyLineData[i][2]);
|
||||
PolyLine[i].setU(PolyLineData[i][3]);
|
||||
PolyLine[i].setV(PolyLineData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PolyLineSetColor(bool white)
|
||||
{
|
||||
int i;
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidGreen;
|
||||
rw::RGBA SolidColor3 = SolidBlue;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
}
|
||||
|
||||
for(i = 0; i < 7; i++)
|
||||
PolyLine[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(; i < 14; i++)
|
||||
PolyLine[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
for(; i < 21; i++)
|
||||
PolyLine[i].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
PolyLineRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(PolyLine, 21, transform, transformFlags);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPEPOLYLINE);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedPolyLineCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 8; i++){
|
||||
IndexedPolyLine[i].setX(IndexedPolyLineData[i][0]);
|
||||
IndexedPolyLine[i].setY(IndexedPolyLineData[i][1]);
|
||||
IndexedPolyLine[i].setZ(IndexedPolyLineData[i][2]);
|
||||
IndexedPolyLine[i].setU(IndexedPolyLineData[i][3]);
|
||||
IndexedPolyLine[i].setV(IndexedPolyLineData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedPolyLineSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidYellow;
|
||||
rw::RGBA SolidColor3 = SolidBlack;
|
||||
rw::RGBA SolidColor4 = SolidPurple;
|
||||
rw::RGBA SolidColor5 = SolidGreen;
|
||||
rw::RGBA SolidColor6 = SolidCyan;
|
||||
rw::RGBA SolidColor7 = SolidBlue;
|
||||
rw::RGBA SolidColor8 = SolidWhite;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
SolidColor4 = SolidWhite;
|
||||
SolidColor5 = SolidWhite;
|
||||
SolidColor6 = SolidWhite;
|
||||
SolidColor7 = SolidWhite;
|
||||
SolidColor8 = SolidWhite;
|
||||
}
|
||||
|
||||
IndexedPolyLine[0].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
IndexedPolyLine[1].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
IndexedPolyLine[2].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
IndexedPolyLine[3].setColor(SolidColor4.red, SolidColor4.green,
|
||||
SolidColor4.blue, SolidColor4.alpha);
|
||||
IndexedPolyLine[4].setColor(SolidColor5.red, SolidColor5.green,
|
||||
SolidColor5.blue, SolidColor5.alpha);
|
||||
IndexedPolyLine[5].setColor(SolidColor6.red, SolidColor6.green,
|
||||
SolidColor6.blue, SolidColor6.alpha);
|
||||
IndexedPolyLine[6].setColor(SolidColor7.red, SolidColor7.green,
|
||||
SolidColor7.blue, SolidColor7.alpha);
|
||||
IndexedPolyLine[7].setColor(SolidColor8.red, SolidColor8.green,
|
||||
SolidColor8.blue, SolidColor8.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedPolyLineRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(IndexedPolyLine, 8, transform, transformFlags);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPEPOLYLINE, IndexedPolyLineIndices, 25);
|
||||
rw::im3d::End();
|
||||
}
|
||||
152
vendor/librw/tools/im3d/trifan.cpp
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
float TriFanData[34][5] = {
|
||||
{ 0.000f, 0.000f, -1.000f, 0.500f, 0.500f},
|
||||
|
||||
{ 0.000f, 1.000f, 0.000f, 0.500f, 1.000f},
|
||||
{ 0.383f, 0.924f, 0.000f, 0.691f, 0.962f},
|
||||
{ 0.707f, 0.707f, 0.000f, 0.854f, 0.854f},
|
||||
{ 0.924f, 0.383f, 0.000f, 0.962f, 0.691f},
|
||||
{ 1.000f, 0.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.924f, -0.383f, 0.000f, 0.962f, 0.309f},
|
||||
{ 0.707f, -0.707f, 0.000f, 0.854f, 0.146f},
|
||||
{ 0.383f, -0.924f, 0.000f, 0.691f, 0.038f},
|
||||
{ 0.000f, -1.000f, 0.000f, 0.500f, 0.000f},
|
||||
{-0.383f, -0.924f, 0.000f, 0.309f, 0.038f},
|
||||
{-0.707f, -0.707f, 0.000f, 0.146f, 0.146f},
|
||||
{-0.924f, -0.383f, 0.000f, 0.038f, 0.309f},
|
||||
{-1.000f, -0.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.924f, 0.383f, 0.000f, 0.038f, 0.691f},
|
||||
{-0.707f, 0.707f, 0.000f, 0.146f, 0.854f},
|
||||
{-0.383f, 0.924f, 0.000f, 0.309f, 0.962f},
|
||||
|
||||
{ 0.000f, 1.000f, 0.000f, 0.500f, 1.000f},
|
||||
|
||||
{-0.383f, 0.924f, 0.000f, 0.309f, 0.962f},
|
||||
{-0.707f, 0.707f, 0.000f, 0.146f, 0.854f},
|
||||
{-0.924f, 0.383f, 0.000f, 0.038f, 0.691f},
|
||||
{-1.000f, -0.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.924f, -0.383f, 0.000f, 0.038f, 0.309f},
|
||||
{-0.707f, -0.707f, 0.000f, 0.146f, 0.146f},
|
||||
{-0.383f, -0.924f, 0.000f, 0.309f, 0.038f},
|
||||
{ 0.000f, -1.000f, 0.000f, 0.500f, 0.000f},
|
||||
{ 0.383f, -0.924f, 0.000f, 0.691f, 0.038f},
|
||||
{ 0.707f, -0.707f, 0.000f, 0.854f, 0.146f},
|
||||
{ 0.924f, -0.383f, 0.000f, 0.962f, 0.309f},
|
||||
{ 1.000f, 0.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.924f, 0.383f, 0.000f, 0.962f, 0.691f},
|
||||
{ 0.707f, 0.707f, 0.000f, 0.854f, 0.854f},
|
||||
{ 0.383f, 0.924f, 0.000f, 0.691f, 0.962f},
|
||||
{ 0.000f, 1.000f, 0.000f, 0.500f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedTriFanData[17][5] = {
|
||||
/* top */
|
||||
{ 0.000f, 0.000f, -1.000f, 0.500f, 0.500f},
|
||||
/* circle */
|
||||
{ 0.000f, 1.000f, 0.000f, 0.500f, 1.000f},
|
||||
{ 0.383f, 0.924f, 0.000f, 0.691f, 0.962f},
|
||||
{ 0.707f, 0.707f, 0.000f, 0.854f, 0.854f},
|
||||
{ 0.924f, 0.383f, 0.000f, 0.962f, 0.691f},
|
||||
{ 1.000f, 0.000f, 0.000f, 1.000f, 0.500f},
|
||||
{ 0.924f, -0.383f, 0.000f, 0.962f, 0.309f},
|
||||
{ 0.707f, -0.707f, 0.000f, 0.854f, 0.146f},
|
||||
{ 0.383f, -0.924f, 0.000f, 0.691f, 0.038f},
|
||||
{ 0.000f, -1.000f, 0.000f, 0.500f, 0.000f},
|
||||
{-0.383f, -0.924f, 0.000f, 0.309f, 0.038f},
|
||||
{-0.707f, -0.707f, 0.000f, 0.146f, 0.146f},
|
||||
{-0.924f, -0.383f, 0.000f, 0.038f, 0.309f},
|
||||
{-1.000f, -0.000f, 0.000f, 0.000f, 0.500f},
|
||||
{-0.924f, 0.383f, 0.000f, 0.038f, 0.691f},
|
||||
{-0.707f, 0.707f, 0.000f, 0.146f, 0.854f},
|
||||
{-0.383f, 0.924f, 0.000f, 0.309f, 0.962f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriFanIndices[34] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1,
|
||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im3DVertex TriFan[34];
|
||||
rw::RWDEVICE::Im3DVertex IndexedTriFan[17];
|
||||
|
||||
|
||||
void
|
||||
TriFanCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 34; i++){
|
||||
TriFan[i].setX(TriFanData[i][0]);
|
||||
TriFan[i].setY(TriFanData[i][1]);
|
||||
TriFan[i].setZ(TriFanData[i][2]);
|
||||
TriFan[i].setU(TriFanData[i][3]);
|
||||
TriFan[i].setV(TriFanData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriFanSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidYellow;
|
||||
rw::RGBA SolidColor2 = SolidBlue;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
TriFan[0].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(int i = 1; i < 34; i++)
|
||||
TriFan[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
TriFanRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(TriFan, 34, transform, transformFlags);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRIFAN);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriFanCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 17; i++){
|
||||
IndexedTriFan[i].setX(IndexedTriFanData[i][0]);
|
||||
IndexedTriFan[i].setY(IndexedTriFanData[i][1]);
|
||||
IndexedTriFan[i].setZ(IndexedTriFanData[i][2]);
|
||||
IndexedTriFan[i].setU(IndexedTriFanData[i][3]);
|
||||
IndexedTriFan[i].setV(IndexedTriFanData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriFanSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidGreen;
|
||||
rw::RGBA SolidColor2 = SolidBlack;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
IndexedTriFan[0].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(int i = 1; i < 17; i++)
|
||||
IndexedTriFan[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriFanRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(IndexedTriFan, 17, transform, transformFlags);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRIFAN, IndexedTriFanIndices, 34);
|
||||
rw::im3d::End();
|
||||
}
|
||||
202
vendor/librw/tools/im3d/trilist.cpp
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
float TriListData[36][5] = {
|
||||
/* front */
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 0.000f, 1.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 0.000f, 0.000f},
|
||||
/* back */
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 1.000f, 0.000f},
|
||||
{ 1.000f, 1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, 1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 1.000f},
|
||||
/* top */
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, 1.000f, -1.000f, 1.000f, 0.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 0.000f, 1.000f},
|
||||
/* bottom */
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.000f, 0.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.000f, 0.000f},
|
||||
/* left */
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 0.000f, 0.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 1.000f, 0.000f},
|
||||
{-1.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 0.000f, 1.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 0.000f, 0.000f},
|
||||
/* right */
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{ 1.000f, 1.000f, -1.000f, 0.000f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedTriListData[8][5] = {
|
||||
{ 1.000f, 1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{-1.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
{-1.000f, -1.000f, 1.000f, 0.500f, 1.000f},
|
||||
{ 1.000f, -1.000f, 1.000f, 0.500f, 0.000f},
|
||||
|
||||
{ 1.000f, 1.000f, -1.000f, 0.500f, 0.000f},
|
||||
{-1.000f, 1.000f, -1.000f, 0.500f, 1.000f},
|
||||
{-1.000f, -1.000f, -1.000f, 0.000f, 1.000f},
|
||||
{ 1.000f, -1.000f, -1.000f, 0.000f, 0.000f}
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriListIndices[36] = {
|
||||
/* front */
|
||||
0, 1, 3, 1, 2, 3,
|
||||
/* back */
|
||||
7, 5, 4, 5, 7, 6,
|
||||
/* left */
|
||||
6, 2, 1, 1, 5, 6,
|
||||
/* right */
|
||||
0, 3, 4, 4, 3, 7,
|
||||
/* top */
|
||||
1, 0, 4, 1, 4, 5,
|
||||
/* bottom */
|
||||
2, 6, 3, 6, 7, 3
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im3DVertex TriList[36];
|
||||
rw::RWDEVICE::Im3DVertex IndexedTriList[8];
|
||||
|
||||
|
||||
void
|
||||
TriListCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 36; i++){
|
||||
TriList[i].setX(TriListData[i][0]);
|
||||
TriList[i].setY(TriListData[i][1]);
|
||||
TriList[i].setZ(TriListData[i][2]);
|
||||
TriList[i].setU(TriListData[i][3]);
|
||||
TriList[i].setV(TriListData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriListSetColor(bool white)
|
||||
{
|
||||
int i;
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidBlue;
|
||||
rw::RGBA SolidColor3 = SolidGreen;
|
||||
rw::RGBA SolidColor4 = SolidYellow;
|
||||
rw::RGBA SolidColor5 = SolidCyan;
|
||||
rw::RGBA SolidColor6 = SolidPurple;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
SolidColor4 = SolidWhite;
|
||||
SolidColor5 = SolidWhite;
|
||||
SolidColor6 = SolidWhite;
|
||||
}
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
TriList[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(; i < 12; i++)
|
||||
TriList[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
for(; i < 18; i++)
|
||||
TriList[i].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
for(; i < 24; i++)
|
||||
TriList[i].setColor(SolidColor4.red, SolidColor4.green,
|
||||
SolidColor4.blue, SolidColor4.alpha);
|
||||
for(; i < 30; i++)
|
||||
TriList[i].setColor(SolidColor5.red, SolidColor5.green,
|
||||
SolidColor5.blue, SolidColor5.alpha);
|
||||
for(; i < 36; i++)
|
||||
TriList[i].setColor(SolidColor6.red, SolidColor6.green,
|
||||
SolidColor6.blue, SolidColor6.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
TriListRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(TriList, 36, transform, transformFlags);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRILIST);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriListCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 8; i++){
|
||||
IndexedTriList[i].setX(IndexedTriListData[i][0]);
|
||||
IndexedTriList[i].setY(IndexedTriListData[i][1]);
|
||||
IndexedTriList[i].setZ(IndexedTriListData[i][2]);
|
||||
IndexedTriList[i].setU(IndexedTriListData[i][3]);
|
||||
IndexedTriList[i].setV(IndexedTriListData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriListSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidYellow;
|
||||
rw::RGBA SolidColor3 = SolidBlack;
|
||||
rw::RGBA SolidColor4 = SolidPurple;
|
||||
rw::RGBA SolidColor5 = SolidGreen;
|
||||
rw::RGBA SolidColor6 = SolidCyan;
|
||||
rw::RGBA SolidColor7 = SolidBlue;
|
||||
rw::RGBA SolidColor8 = SolidWhite;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
SolidColor3 = SolidWhite;
|
||||
SolidColor4 = SolidWhite;
|
||||
SolidColor5 = SolidWhite;
|
||||
SolidColor6 = SolidWhite;
|
||||
SolidColor7 = SolidWhite;
|
||||
SolidColor8 = SolidWhite;
|
||||
}
|
||||
|
||||
IndexedTriList[0].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
IndexedTriList[1].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
IndexedTriList[2].setColor(SolidColor3.red, SolidColor3.green,
|
||||
SolidColor3.blue, SolidColor3.alpha);
|
||||
IndexedTriList[3].setColor(SolidColor4.red, SolidColor4.green,
|
||||
SolidColor4.blue, SolidColor4.alpha);
|
||||
IndexedTriList[4].setColor(SolidColor5.red, SolidColor5.green,
|
||||
SolidColor5.blue, SolidColor5.alpha);
|
||||
IndexedTriList[5].setColor(SolidColor6.red, SolidColor6.green,
|
||||
SolidColor6.blue, SolidColor6.alpha);
|
||||
IndexedTriList[6].setColor(SolidColor7.red, SolidColor7.green,
|
||||
SolidColor7.blue, SolidColor7.alpha);
|
||||
IndexedTriList[7].setColor(SolidColor8.red, SolidColor8.green,
|
||||
SolidColor8.blue, SolidColor8.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriListRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(IndexedTriList, 8, transform, transformFlags);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, IndexedTriListIndices, 36);
|
||||
rw::im3d::End();
|
||||
}
|
||||
169
vendor/librw/tools/im3d/tristrip.cpp
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "im3d.h"
|
||||
|
||||
float TriStripData[36][5] = {
|
||||
{ 0.000f, 1.000f, -1.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, 1.000f, 0.000f, 1.000f},
|
||||
|
||||
{ 0.707f, 0.707f, -1.000f, 0.125f, 0.000f},
|
||||
{ 0.707f, 0.707f, 1.000f, 0.125f, 1.000f},
|
||||
|
||||
{ 1.000f, 0.000f, -1.000f, 0.250f, 0.000f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.250f, 1.000f},
|
||||
|
||||
{ 0.707f, -0.707f, -1.000f, 0.375f, 0.000f},
|
||||
{ 0.707f, -0.707f, 1.000f, 0.375f, 1.000f},
|
||||
|
||||
{ 0.000f, -1.000f, -1.000f, 0.500f, 0.000f},
|
||||
{ 0.000f, -1.000f, 1.000f, 0.500f, 1.000f},
|
||||
|
||||
{-0.707f, -0.707f, -1.000f, 0.625f, 0.000f},
|
||||
{-0.707f, -0.707f, 1.000f, 0.625f, 1.000f},
|
||||
|
||||
{-1.000f, -0.000f, -1.000f, 0.750f, 0.000f},
|
||||
{-1.000f, -0.000f, 1.000f, 0.750f, 1.000f},
|
||||
|
||||
{-0.707f, 0.707f, -1.000f, 0.875f, 0.000f},
|
||||
{-0.707f, 0.707f, 1.000f, 0.875f, 1.000f},
|
||||
|
||||
{ 0.000f, 1.000f, -1.000f, 1.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, 1.000f, 1.000f, 1.000f},
|
||||
|
||||
{ 0.000f, 1.000f, 1.000f, 0.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, -1.000f, 0.000f, 1.000f},
|
||||
|
||||
{ 0.707f, 0.707f, 1.000f, 0.125f, 0.000f},
|
||||
{ 0.707f, 0.707f, -1.000f, 0.125f, 1.000f},
|
||||
|
||||
{ 1.000f, 0.000f, 1.000f, 0.250f, 0.000f},
|
||||
{ 1.000f, 0.000f, -1.000f, 0.250f, 1.000f},
|
||||
|
||||
{ 0.707f, -0.707f, 1.000f, 0.375f, 0.000f},
|
||||
{ 0.707f, -0.707f, -1.000f, 0.375f, 1.000f},
|
||||
|
||||
{ 0.000f, -1.000f, 1.000f, 0.500f, 0.000f},
|
||||
{ 0.000f, -1.000f, -1.000f, 0.500f, 1.000f},
|
||||
|
||||
{-0.707f, -0.707f, 1.000f, 0.625f, 0.000f},
|
||||
{-0.707f, -0.707f, -1.000f, 0.625f, 1.000f},
|
||||
|
||||
{-1.000f, -0.000f, 1.000f, 0.750f, 0.000f},
|
||||
{-1.000f, -0.000f, -1.000f, 0.750f, 1.000f},
|
||||
|
||||
{-0.707f, 0.707f, 1.000f, 0.875f, 0.000f},
|
||||
{-0.707f, 0.707f, -1.000f, 0.875f, 1.000f},
|
||||
|
||||
{ 0.000f, 1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{ 0.000f, 1.000f, -1.000f, 1.000f, 1.000f}
|
||||
};
|
||||
|
||||
float IndexedTriStripData[16][5] = {
|
||||
{ 0.000f, 1.000f, 1.000f, 0.000f, 0.000f},
|
||||
{ 0.707f, 0.707f, 1.000f, 0.250f, 0.000f},
|
||||
{ 1.000f, 0.000f, 1.000f, 0.500f, 0.000f},
|
||||
{ 0.707f, -0.707f, 1.000f, 0.750f, 0.000f},
|
||||
{ 0.000f, -1.000f, 1.000f, 1.000f, 0.000f},
|
||||
{-0.707f, -0.707f, 1.000f, 0.750f, 0.000f},
|
||||
{-1.000f, -0.000f, 1.000f, 0.500f, 0.000f},
|
||||
{-0.707f, 0.707f, 1.000f, 0.250f, 0.000f},
|
||||
|
||||
{ 0.000f, 1.000f, -1.000f, 0.000f, 1.000f},
|
||||
{ 0.707f, 0.707f, -1.000f, 0.250f, 1.000f},
|
||||
{ 1.000f, 0.000f, -1.000f, 0.500f, 1.000f},
|
||||
{ 0.707f, -0.707f, -1.000f, 0.750f, 1.000f},
|
||||
{ 0.000f, -1.000f, -1.000f, 1.000f, 1.000f},
|
||||
{-0.707f, -0.707f, -1.000f, 0.750f, 1.000f},
|
||||
{-1.000f, -0.000f, -1.000f, 0.500f, 1.000f},
|
||||
{-0.707f, 0.707f, -1.000f, 0.250f, 1.000f},
|
||||
};
|
||||
|
||||
rw::uint16 IndexedTriStripIndices[36] = {
|
||||
0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15, 0, 8,
|
||||
8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 8, 0
|
||||
};
|
||||
|
||||
rw::RWDEVICE::Im3DVertex TriStrip[36];
|
||||
rw::RWDEVICE::Im3DVertex IndexedTriStrip[16];
|
||||
|
||||
|
||||
void
|
||||
TriStripCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 36; i++){
|
||||
TriStrip[i].setX(TriStripData[i][0]);
|
||||
TriStrip[i].setY(TriStripData[i][1]);
|
||||
TriStrip[i].setZ(TriStripData[i][2]);
|
||||
TriStrip[i].setU(TriStripData[i][3]);
|
||||
TriStrip[i].setV(TriStripData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriStripSetColor(bool white)
|
||||
{
|
||||
rw::RGBA SolidColor1 = SolidRed;
|
||||
rw::RGBA SolidColor2 = SolidYellow;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 36; i += 2){
|
||||
TriStrip[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
TriStrip[i+1].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriStripRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(TriStrip, 36, transform, transformFlags);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRISTRIP);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IndexedTriStripCreate(void)
|
||||
{
|
||||
for(int i = 0; i < 16; i++){
|
||||
IndexedTriStrip[i].setX(IndexedTriStripData[i][0]);
|
||||
IndexedTriStrip[i].setY(IndexedTriStripData[i][1]);
|
||||
IndexedTriStrip[i].setZ(IndexedTriStripData[i][2]);
|
||||
IndexedTriStrip[i].setU(IndexedTriStripData[i][3]);
|
||||
IndexedTriStrip[i].setV(IndexedTriStripData[i][4]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriStripSetColor(bool white)
|
||||
{
|
||||
int i;
|
||||
rw::RGBA SolidColor1 = SolidBlue;
|
||||
rw::RGBA SolidColor2 = SolidGreen;
|
||||
|
||||
if(white){
|
||||
SolidColor1 = SolidWhite;
|
||||
SolidColor2 = SolidWhite;
|
||||
}
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
IndexedTriStrip[i].setColor(SolidColor1.red, SolidColor1.green,
|
||||
SolidColor1.blue, SolidColor1.alpha);
|
||||
for(; i < 16; i++)
|
||||
IndexedTriStrip[i].setColor(SolidColor2.red, SolidColor2.green,
|
||||
SolidColor2.blue, SolidColor2.alpha);
|
||||
}
|
||||
|
||||
void
|
||||
IndexedTriStripRender(rw::Matrix *transform, rw::uint32 transformFlags)
|
||||
{
|
||||
rw::im3d::Transform(IndexedTriStrip, 16, transform, transformFlags);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP, IndexedTriStripIndices, 36);
|
||||
rw::im3d::End();
|
||||
}
|
||||
17
vendor/librw/tools/imguitest/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
add_executable(imguitest WIN32
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(imguitest
|
||||
PUBLIC
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
if(LIBRW_INSTALL)
|
||||
install(TARGETS imguitest
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
librw_platform_target(imguitest INSTALL)
|
||||
175
vendor/librw/tools/imguitest/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
struct SceneGlobals {
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
} Scene;
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
sk::globals.windowtitle = "ImGui test";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InitRW(void)
|
||||
{
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
Scene.world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
ambient->setColor(0.2f, 0.2f, 0.2f);
|
||||
Scene.world->addLight(ambient);
|
||||
|
||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
Scene.world->addLight(direct);
|
||||
|
||||
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
Scene.world->addCamera(Scene.camera);
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Draw(float timeDelta)
|
||||
{
|
||||
static bool show_demo_window = true;
|
||||
static bool show_another_window = false;
|
||||
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
rw::RGBA clearcol = rw::makeRGBA(clear_color.x*255, clear_color.y*255, clear_color.z*255, clear_color.w*255);
|
||||
Scene.camera->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
Scene.camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(timeDelta);
|
||||
|
||||
// 1. Show a simple window.
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug".
|
||||
{
|
||||
static float f = 0.0f;
|
||||
ImGui::Text("Hello, world!"); // Some text (you can use a format string too)
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f
|
||||
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color
|
||||
if(ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well.
|
||||
show_demo_window ^= 1;
|
||||
if(ImGui::Button("Another Window"))
|
||||
show_another_window ^= 1;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
}
|
||||
|
||||
// 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window.
|
||||
if(show_another_window){
|
||||
ImGui::Begin("Another Window", &show_another_window);
|
||||
ImGui::Text("Hello from another window!");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow().
|
||||
if(show_demo_window){
|
||||
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowDemoWindow(&show_demo_window);
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
Scene.camera->endUpdate();
|
||||
Scene.camera->showRaster(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Init();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
// TODO: set aspect ratio
|
||||
if(Scene.camera)
|
||||
sk::CameraSize(Scene.camera, r);
|
||||
break;
|
||||
case IDLE:
|
||||
Draw(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
18
vendor/librw/tools/lights/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
add_executable(lights WIN32
|
||||
main.cpp
|
||||
lights.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(lights
|
||||
PRIVATE
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET lights POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:lights>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/checker.dff" "$<TARGET_FILE_DIR:lights>"
|
||||
)
|
||||
|
||||
librw_platform_target(lights)
|
||||
BIN
vendor/librw/tools/lights/checker.dff
vendored
Normal file
463
vendor/librw/tools/lights/lights.cpp
vendored
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
rw::Light *BaseAmbientLight;
|
||||
bool BaseAmbientLightOn;
|
||||
|
||||
rw::Light *CurrentLight;
|
||||
rw::Light *AmbientLight;
|
||||
rw::Light *PointLight;
|
||||
rw::Light *DirectLight;
|
||||
rw::Light *SpotLight;
|
||||
rw::Light *SpotSoftLight;
|
||||
|
||||
float LightRadius = 100.0f;
|
||||
float LightConeAngle = 45.0f;
|
||||
rw::RGBAf LightColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
rw::RGBA LightSolidColor = { 255, 255, 0, 255 };
|
||||
bool LightOn = true;
|
||||
bool LightDrawOn = true;
|
||||
rw::V3d LightPos = {0.0f, 0.0f, 75.0f};
|
||||
rw::int32 LightTypeIndex = 1;
|
||||
|
||||
rw::BBox RoomBBox;
|
||||
|
||||
rw::Light*
|
||||
CreateBaseAmbientLight(void)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::AMBIENT);
|
||||
assert(light);
|
||||
light->setColor(0.5f, 0.5f, 0.5f);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateAmbientLight(void)
|
||||
{
|
||||
return rw::Light::create(rw::Light::AMBIENT);
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateDirectLight(void)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
assert(light);
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
||||
rw::V3d pos = LightPos;
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
light->setFrame(frame);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreatePointLight(void)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::POINT);
|
||||
assert(light);
|
||||
light->radius = LightRadius;
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
rw::V3d pos = LightPos;
|
||||
frame->translate(&pos, rw::COMBINEREPLACE);
|
||||
light->setFrame(frame);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateSpotLight(void)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::SPOT);
|
||||
assert(light);
|
||||
light->radius = LightRadius;
|
||||
light->setAngle(LightConeAngle/180.0f*M_PI);
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
||||
rw::V3d pos = LightPos;
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
light->setFrame(frame);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateSpotSoftLight(void)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::SOFTSPOT);
|
||||
assert(light);
|
||||
light->radius = LightRadius;
|
||||
light->setAngle(LightConeAngle/180.0f*M_PI);
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
||||
rw::V3d pos = LightPos;
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
light->setFrame(frame);
|
||||
return light;
|
||||
}
|
||||
|
||||
void
|
||||
DestroyLight(rw::Light **light)
|
||||
{
|
||||
if(*light == nil)
|
||||
return;
|
||||
rw::World *world = (*light)->world;
|
||||
if(world)
|
||||
world->removeLight(*light);
|
||||
rw::Frame *frame = (*light)->getFrame();
|
||||
if(frame){
|
||||
(*light)->setFrame(nil);
|
||||
frame->destroy();
|
||||
}
|
||||
|
||||
(*light)->destroy();
|
||||
*light = nil;
|
||||
}
|
||||
|
||||
void
|
||||
LightsDestroy(void)
|
||||
{
|
||||
DestroyLight(&SpotSoftLight);
|
||||
DestroyLight(&SpotLight);
|
||||
DestroyLight(&PointLight);
|
||||
DestroyLight(&DirectLight);
|
||||
DestroyLight(&AmbientLight);
|
||||
DestroyLight(&BaseAmbientLight);
|
||||
}
|
||||
|
||||
void
|
||||
LightsUpdate(void)
|
||||
{
|
||||
static rw::int32 oldLightTypeIndex = -1;
|
||||
|
||||
// Switch to a different light
|
||||
if((LightOn && oldLightTypeIndex != LightTypeIndex) || CurrentLight == nil){
|
||||
oldLightTypeIndex = LightTypeIndex;
|
||||
|
||||
// remove first
|
||||
if(CurrentLight)
|
||||
CurrentLight->world->removeLight(CurrentLight);
|
||||
|
||||
switch(LightTypeIndex){
|
||||
case 0: CurrentLight = AmbientLight; break;
|
||||
case 1: CurrentLight = PointLight; break;
|
||||
case 2: CurrentLight = DirectLight; break;
|
||||
case 3: CurrentLight = SpotLight; break;
|
||||
case 4: CurrentLight = SpotSoftLight; break;
|
||||
}
|
||||
World->addLight(CurrentLight);
|
||||
}
|
||||
|
||||
if(CurrentLight){
|
||||
CurrentLight->setColor(LightColor.red, LightColor.green, LightColor.blue);
|
||||
CurrentLight->radius = LightRadius;
|
||||
CurrentLight->setAngle(LightConeAngle / 180.0f * M_PI);
|
||||
}
|
||||
|
||||
// Remove light from world if not used
|
||||
if(!LightOn && CurrentLight){
|
||||
CurrentLight->world->removeLight(CurrentLight);
|
||||
CurrentLight = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#define POINT_LIGHT_RADIUS_FACTOR 0.05f
|
||||
|
||||
void
|
||||
DrawPointLight(void)
|
||||
{
|
||||
enum { NUMVERTS = 50 };
|
||||
rw::RWDEVICE::Im3DVertex shape[NUMVERTS];
|
||||
rw::int32 i;
|
||||
rw::V3d point;
|
||||
|
||||
rw::V3d *pos = &CurrentLight->getFrame()->getLTM()->pos;
|
||||
for(i = 0; i < NUMVERTS; i++){
|
||||
point.x = pos->x +
|
||||
cosf(i/(NUMVERTS/2.0f) * M_PI) * LightRadius * POINT_LIGHT_RADIUS_FACTOR;
|
||||
point.y = pos->y +
|
||||
sinf(i/(NUMVERTS/2.0f) * M_PI) * LightRadius * POINT_LIGHT_RADIUS_FACTOR;
|
||||
point.z = pos->z;
|
||||
|
||||
shape[i].setColor(LightSolidColor.red, LightSolidColor.green,
|
||||
LightSolidColor.blue, LightSolidColor.alpha);
|
||||
shape[i].setX(point.x);
|
||||
shape[i].setY(point.y);
|
||||
shape[i].setZ(point.z);
|
||||
}
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS, nil, rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPEPOLYLINE);
|
||||
rw::im3d::RenderLine(NUMVERTS-1, 0);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
DrawCone(float coneAngle, float coneSize, float coneRatio)
|
||||
{
|
||||
enum { NUMVERTS = 10 };
|
||||
rw::RWDEVICE::Im3DVertex shape[NUMVERTS+1];
|
||||
rw::int16 indices[NUMVERTS*3];
|
||||
rw::int32 i;
|
||||
|
||||
rw::Matrix *matrix = CurrentLight->getFrame()->getLTM();
|
||||
rw::V3d *pos = &matrix->pos;
|
||||
|
||||
// cone
|
||||
for(i = 1; i < NUMVERTS+1; i++){
|
||||
float cosValue = cosf(i/(NUMVERTS/2.0f) * M_PI) *
|
||||
sinf(coneAngle/180.0f*M_PI);
|
||||
float sinValue = sinf(i/(NUMVERTS/2.0f) * M_PI) *
|
||||
sinf(coneAngle/180.0f*M_PI);
|
||||
|
||||
float coneAngleD = cosf(coneAngle/180.0f*M_PI);
|
||||
|
||||
rw::V3d up = rw::scale(matrix->up, sinValue*coneSize);
|
||||
rw::V3d right = rw::scale(matrix->right, cosValue*coneSize);
|
||||
rw::V3d at = rw::scale(matrix->at, coneAngleD*coneSize*coneRatio);
|
||||
|
||||
shape[i].setX(pos->x + at.x + up.x + right.x);
|
||||
shape[i].setY(pos->y + at.y + up.y + right.y);
|
||||
shape[i].setZ(pos->z + at.z + up.z + right.z);
|
||||
}
|
||||
|
||||
for(i = 0; i < NUMVERTS; i++){
|
||||
indices[i*3 + 0] = 0;
|
||||
indices[i*3 + 1] = i+2;
|
||||
indices[i*3 + 2] = i+1;
|
||||
}
|
||||
indices[NUMVERTS*3-2] = 1;
|
||||
|
||||
for(i = 0; i < NUMVERTS+1; i++)
|
||||
shape[i].setColor(LightSolidColor.red, LightSolidColor.green,
|
||||
LightSolidColor.blue, 128);
|
||||
|
||||
shape[0].setX(pos->x);
|
||||
shape[0].setY(pos->y);
|
||||
shape[0].setZ(pos->z);
|
||||
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::SetRenderState(rw::SRCBLEND, rw::BLENDSRCALPHA);
|
||||
rw::SetRenderState(rw::DESTBLEND, rw::BLENDINVSRCALPHA);
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS+1, nil, 0);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRIFAN);
|
||||
rw::im3d::RenderTriangle(0, NUMVERTS, 1);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, NUMVERTS*3);
|
||||
rw::im3d::End();
|
||||
|
||||
|
||||
for(i = 0; i < NUMVERTS+1; i++)
|
||||
shape[i].setColor(LightSolidColor.red, LightSolidColor.green,
|
||||
LightSolidColor.blue, 255);
|
||||
|
||||
float coneAngleD = cosf(coneAngle/180.0f*M_PI);
|
||||
rw::V3d at = rw::scale(matrix->at, coneAngleD*coneSize*coneRatio);
|
||||
shape[0].setX(pos->x + at.x);
|
||||
shape[0].setY(pos->y + at.y);
|
||||
shape[0].setZ(pos->z + at.z);
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS+1, nil, rw::im3d::ALLOPAQUE);
|
||||
if(coneRatio > 0.0f){
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRIFAN);
|
||||
rw::im3d::RenderTriangle(0, NUMVERTS, 1);
|
||||
}else
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRIFAN, indices, NUMVERTS*3);
|
||||
rw::im3d::End();
|
||||
|
||||
|
||||
// lines
|
||||
at = rw::scale(matrix->at, -0.05f);
|
||||
shape[0].setX(pos->x + at.x);
|
||||
shape[0].setY(pos->y + at.y);
|
||||
shape[0].setZ(pos->z + at.z);
|
||||
rw::im3d::Transform(shape, NUMVERTS+1, nil, rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPEPOLYLINE, indices, NUMVERTS*3);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
DrawDirectLight(void)
|
||||
{
|
||||
enum { NUMVERTS = 20 };
|
||||
const float DIAMETER = 1.5f;
|
||||
const float CONE_ANGLE = 45.0f;
|
||||
const float CONE_SIZE = 3.0f;
|
||||
const float LENGTH = 5.0f;
|
||||
rw::RWDEVICE::Im3DVertex shape[NUMVERTS*2+1];
|
||||
rw::int16 indices[NUMVERTS*3];
|
||||
rw::int32 i;
|
||||
|
||||
rw::Matrix *matrix = CurrentLight->getFrame()->getLTM();
|
||||
rw::V3d *pos = &matrix->pos;
|
||||
|
||||
// cylinder
|
||||
for(i = 0; i < NUMVERTS*2; i += 2){
|
||||
float cosValue = cosf(i/(NUMVERTS/2.0f) * M_PI);
|
||||
float sinValue = sinf(i/(NUMVERTS/2.0f) * M_PI);
|
||||
|
||||
rw::V3d up = rw::scale(matrix->up, sinValue*DIAMETER);
|
||||
rw::V3d right = rw::scale(matrix->right, cosValue*DIAMETER);
|
||||
rw::V3d at = rw::scale(matrix->at, -(CONE_SIZE + 1.0f));
|
||||
|
||||
shape[i].setX(pos->x + at.x + up.x + right.x);
|
||||
shape[i].setY(pos->y + at.y + up.y + right.y);
|
||||
shape[i].setZ(pos->z + at.z + up.z + right.z);
|
||||
|
||||
|
||||
at = rw::scale(matrix->at, -(LENGTH + CONE_SIZE));
|
||||
|
||||
shape[i+1].setX(pos->x + at.x + up.x + right.x);
|
||||
shape[i+1].setY(pos->y + at.y + up.y + right.y);
|
||||
shape[i+1].setZ(pos->z + at.z + up.z + right.z);
|
||||
}
|
||||
|
||||
for(i = 0; i < NUMVERTS*2+1; i++)
|
||||
shape[i].setColor(LightSolidColor.red, LightSolidColor.green,
|
||||
LightSolidColor.blue, 128);
|
||||
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::SetRenderState(rw::SRCBLEND, rw::BLENDSRCALPHA);
|
||||
rw::SetRenderState(rw::DESTBLEND, rw::BLENDINVSRCALPHA);
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS*2, nil, 0);
|
||||
rw::im3d::RenderPrimitive(rw::PRIMTYPETRISTRIP);
|
||||
rw::im3d::RenderTriangle(2*NUMVERTS-2, 2*NUMVERTS-1, 0);
|
||||
rw::im3d::RenderTriangle(2*NUMVERTS-1, 1, 0);
|
||||
rw::im3d::End();
|
||||
|
||||
|
||||
// bottom cap
|
||||
for(i = 0; i < NUMVERTS*2+1; i++)
|
||||
shape[i].setColor(LightSolidColor.red, LightSolidColor.green,
|
||||
LightSolidColor.blue, 255);
|
||||
|
||||
rw::V3d at = rw::scale(matrix->at, -(LENGTH + CONE_SIZE));
|
||||
shape[NUMVERTS*2].setX(pos->x + at.x);
|
||||
shape[NUMVERTS*2].setY(pos->y + at.y);
|
||||
shape[NUMVERTS*2].setZ(pos->z + at.z);
|
||||
|
||||
for(i = 0; i < NUMVERTS; i++){
|
||||
indices[i*3+0] = NUMVERTS*2;
|
||||
indices[i*3+1] = (i+1)*2 + 1;
|
||||
indices[i*3+2] = i*2 + 1;
|
||||
}
|
||||
indices[NUMVERTS*3-2] = 1;
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS*2+1, nil, rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, NUMVERTS*3);
|
||||
rw::im3d::End();
|
||||
|
||||
|
||||
// top cap
|
||||
at = rw::scale(matrix->at, -(CONE_SIZE + 1.0f));
|
||||
shape[NUMVERTS*2].setX(pos->x + at.x);
|
||||
shape[NUMVERTS*2].setY(pos->y + at.y);
|
||||
shape[NUMVERTS*2].setZ(pos->z + at.z);
|
||||
|
||||
for(i = 0; i < NUMVERTS; i++){
|
||||
indices[i*3+0] = NUMVERTS*2;
|
||||
indices[i*3+1] = i*2;
|
||||
indices[i*3+2] = (i+1)*2;
|
||||
}
|
||||
|
||||
rw::im3d::Transform(shape, NUMVERTS*2+1, nil, rw::im3d::ALLOPAQUE);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, NUMVERTS*3);
|
||||
rw::im3d::End();
|
||||
|
||||
|
||||
// cone
|
||||
DrawCone(CONE_ANGLE, CONE_SIZE, -2.0f);
|
||||
}
|
||||
|
||||
void
|
||||
DrawCurrentLight(void)
|
||||
{
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::CULLMODE, rw::CULLBACK);
|
||||
rw::SetRenderState(rw::ZTESTENABLE, 1);
|
||||
|
||||
switch(LightTypeIndex){
|
||||
case 1: DrawPointLight(); break;
|
||||
case 2: DrawDirectLight(); break;
|
||||
case 3:
|
||||
case 4: DrawCone(LightConeAngle, LightRadius*POINT_LIGHT_RADIUS_FACTOR, 1.0f); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
LightRotate(float xAngle, float yAngle)
|
||||
{
|
||||
if(CurrentLight == nil || CurrentLight == AmbientLight || CurrentLight == PointLight)
|
||||
return;
|
||||
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::Frame *lightFrame = CurrentLight->getFrame();
|
||||
rw::V3d pos = lightFrame->matrix.pos;
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
lightFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
lightFrame->rotate(&cameraMatrix->up, xAngle, rw::COMBINEPOSTCONCAT);
|
||||
lightFrame->rotate(&cameraMatrix->right, yAngle, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
lightFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
ClampPosition(rw::V3d *pos, rw::V3d *delta, rw::BBox *bbox)
|
||||
{
|
||||
if(pos->x + delta->x < bbox->inf.x)
|
||||
delta->x = bbox->inf.x - pos->x;
|
||||
else if(pos->x + delta->x > bbox->sup.x)
|
||||
delta->x = bbox->sup.x - pos->x;
|
||||
|
||||
if(pos->y + delta->y < bbox->inf.y)
|
||||
delta->y = bbox->inf.y - pos->y;
|
||||
else if(pos->y + delta->y > bbox->sup.y)
|
||||
delta->y = bbox->sup.y - pos->y;
|
||||
|
||||
if(pos->z + delta->z < bbox->inf.z)
|
||||
delta->z = bbox->inf.z - pos->z;
|
||||
else if(pos->z + delta->z > bbox->sup.z)
|
||||
delta->z = bbox->sup.z - pos->z;
|
||||
}
|
||||
|
||||
void
|
||||
LightTranslateXY(float xDelta, float yDelta)
|
||||
{
|
||||
if(CurrentLight == nil || CurrentLight == AmbientLight || CurrentLight == DirectLight)
|
||||
return;
|
||||
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::Frame *lightFrame = CurrentLight->getFrame();
|
||||
rw::V3d right = rw::scale(cameraMatrix->right, xDelta);
|
||||
rw::V3d up = rw::scale(cameraMatrix->up, yDelta);
|
||||
rw::V3d delta = rw::add(right, up);
|
||||
|
||||
ClampPosition(&lightFrame->matrix.pos, &delta, &RoomBBox);
|
||||
|
||||
lightFrame->translate(&delta, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
LightTranslateZ(float zDelta)
|
||||
{
|
||||
if(CurrentLight == nil || CurrentLight == AmbientLight || CurrentLight == DirectLight)
|
||||
return;
|
||||
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::Frame *lightFrame = CurrentLight->getFrame();
|
||||
rw::V3d delta = rw::scale(cameraMatrix->at, zDelta);
|
||||
|
||||
ClampPosition(&lightFrame->matrix.pos, &delta, &RoomBBox);
|
||||
|
||||
lightFrame->translate(&delta, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
37
vendor/librw/tools/lights/lights.h
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
|
||||
extern rw::Light *BaseAmbientLight;
|
||||
extern bool BaseAmbientLightOn;
|
||||
|
||||
extern rw::Light *CurrentLight;
|
||||
extern rw::Light *AmbientLight;
|
||||
extern rw::Light *PointLight;
|
||||
extern rw::Light *DirectLight;
|
||||
extern rw::Light *SpotLight;
|
||||
extern rw::Light *SpotSoftLight;
|
||||
|
||||
extern float LightRadius;
|
||||
extern float LightConeAngle;
|
||||
extern rw::RGBAf LightColor;
|
||||
|
||||
extern bool LightOn;
|
||||
extern bool LightDrawOn;
|
||||
extern rw::V3d LightPos;
|
||||
extern rw::int32 LightTypeIndex;
|
||||
|
||||
extern rw::BBox RoomBBox;
|
||||
|
||||
rw::Light *CreateBaseAmbientLight(void);
|
||||
rw::Light *CreateAmbientLight(void);
|
||||
rw::Light *CreateDirectLight(void);
|
||||
rw::Light *CreatePointLight(void);
|
||||
rw::Light *CreateSpotLight(void);
|
||||
rw::Light *CreateSpotSoftLight(void);
|
||||
|
||||
void LightsDestroy(void);
|
||||
void LightsUpdate(void);
|
||||
void DrawCurrentLight(void);
|
||||
|
||||
void LightRotate(float xAngle, float yAngle);
|
||||
void LightTranslateXY(float xDelta, float yDelta);
|
||||
void LightTranslateZ(float zDelta);
|
||||
396
vendor/librw/tools/lights/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "lights.h"
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
float FOV = 70.0f;
|
||||
|
||||
rw::RGBA ForegroundColor = { 200, 200, 200, 255 };
|
||||
rw::RGBA BackgroundColor = { 64, 64, 64, 0 };
|
||||
|
||||
rw::World *World;
|
||||
rw::Camera *Camera;
|
||||
|
||||
rw::V3d Xaxis = { 1.0f, 0.0, 0.0f };
|
||||
rw::V3d Yaxis = { 0.0f, 1.0, 0.0f };
|
||||
rw::V3d Zaxis = { 0.0f, 0.0, 1.0f };
|
||||
|
||||
rw::World*
|
||||
CreateWorld(void)
|
||||
{
|
||||
rw::BBox bb;
|
||||
|
||||
bb.inf.x = bb.inf.y = bb.inf.z = -100.0f;
|
||||
bb.sup.x = bb.sup.y = bb.sup.z = 100.0f;
|
||||
|
||||
return rw::World::create(&bb);
|
||||
}
|
||||
|
||||
rw::Camera*
|
||||
CreateCamera(rw::World *world)
|
||||
{
|
||||
rw::Camera *camera;
|
||||
camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
assert(camera);
|
||||
camera->setNearPlane(0.1f);
|
||||
camera->setFarPlane(300.0f);
|
||||
camera->setFOV(FOV, (float)sk::globals.width/sk::globals.height);
|
||||
world->addCamera(camera);
|
||||
return camera;
|
||||
}
|
||||
|
||||
bool
|
||||
CreateTestScene(rw::World *world)
|
||||
{
|
||||
rw::Clump *clump;
|
||||
rw::StreamFile in;
|
||||
const char *filename = "checker.dff";
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return false;
|
||||
}
|
||||
if(!rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL))
|
||||
return false;
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
in.close();
|
||||
if(clump == nil)
|
||||
return false;
|
||||
|
||||
rw::Clump *clone;
|
||||
rw::Frame *clumpFrame;
|
||||
rw::V3d pos;
|
||||
float zOffset = 75.0f;
|
||||
|
||||
// Bottom panel
|
||||
clumpFrame = clump->getFrame();
|
||||
clumpFrame->rotate(&Xaxis, 90.0f, rw::COMBINEREPLACE);
|
||||
|
||||
pos.x = 0.0f;
|
||||
pos.y = -25.0f;
|
||||
pos.z = zOffset;
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// only need to add once
|
||||
world->addClump(clump);
|
||||
|
||||
// Top panel
|
||||
clone = clump->clone();
|
||||
clumpFrame = clone->getFrame();
|
||||
clumpFrame->rotate(&Xaxis, -90.0f, rw::COMBINEREPLACE);
|
||||
|
||||
pos.x = 0.0f;
|
||||
pos.y = 25.0f;
|
||||
pos.z = zOffset;
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// Left panel
|
||||
clone = clump->clone();
|
||||
clumpFrame = clone->getFrame();
|
||||
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
||||
clumpFrame->rotate(&Yaxis, 90.0f, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
pos.x = 25.0f;
|
||||
pos.y = 0.0f;
|
||||
pos.z = zOffset;
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// Right panel
|
||||
clone = clump->clone();
|
||||
clumpFrame = clone->getFrame();
|
||||
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
||||
clumpFrame->rotate(&Yaxis, -90.0f, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
pos.x = -25.0f;
|
||||
pos.y = 0.0f;
|
||||
pos.z = zOffset;
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// Back panel
|
||||
clone = clump->clone();
|
||||
clumpFrame = clone->getFrame();
|
||||
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
||||
|
||||
pos.x = 0.0f;
|
||||
pos.y = 0.0f;
|
||||
pos.z = zOffset + 25.0f;
|
||||
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// BBox
|
||||
pos.x = 25.0f;
|
||||
pos.y = 25.0f;
|
||||
pos.z = zOffset - 25.0f;
|
||||
RoomBBox.initialize(&pos);
|
||||
pos.x = -25.0f;
|
||||
pos.y = -25.0f;
|
||||
pos.z = zOffset + 25.0f;
|
||||
RoomBBox.addPoint(&pos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
Initialize(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Lights example";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Initialize3D(void)
|
||||
{
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
World = CreateWorld();
|
||||
|
||||
BaseAmbientLight = CreateBaseAmbientLight();
|
||||
AmbientLight = CreateAmbientLight();
|
||||
DirectLight = CreateDirectLight();
|
||||
PointLight = CreatePointLight();
|
||||
SpotLight = CreateSpotLight();
|
||||
SpotSoftLight = CreateSpotSoftLight();
|
||||
|
||||
Camera = CreateCamera(World);
|
||||
|
||||
CreateTestScene(World);
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Terminate3D(void)
|
||||
{
|
||||
FORLIST(lnk, World->clumps){
|
||||
rw::Clump *clump = rw::Clump::fromWorld(lnk);
|
||||
World->removeClump(clump);
|
||||
clump->destroy();
|
||||
}
|
||||
|
||||
if(Camera){
|
||||
World->removeCamera(Camera);
|
||||
sk::CameraDestroy(Camera);
|
||||
Camera = nil;
|
||||
}
|
||||
|
||||
LightsDestroy();
|
||||
|
||||
if(World){
|
||||
World->destroy();
|
||||
World = nil;
|
||||
}
|
||||
|
||||
sk::TerminateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Gui(void)
|
||||
{
|
||||
// ImGui::ShowDemoWindow(nil);
|
||||
|
||||
static bool showLightWindow = true;
|
||||
ImGui::Begin("Lights", &showLightWindow);
|
||||
|
||||
ImGui::Checkbox("Light", &LightOn);
|
||||
ImGui::Checkbox("Draw Light", &LightDrawOn);
|
||||
if(ImGui::Checkbox("Base Ambient", &BaseAmbientLightOn)){
|
||||
if(BaseAmbientLightOn){
|
||||
if(BaseAmbientLight->world == nil)
|
||||
World->addLight(BaseAmbientLight);
|
||||
}else{
|
||||
if(BaseAmbientLight->world)
|
||||
World->removeLight(BaseAmbientLight);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::RadioButton("Ambient Light", &LightTypeIndex, 0);
|
||||
ImGui::RadioButton("Point Light", &LightTypeIndex, 1);
|
||||
ImGui::RadioButton("Directional Light", &LightTypeIndex, 2);
|
||||
ImGui::RadioButton("Spot Light", &LightTypeIndex, 3);
|
||||
ImGui::RadioButton("Soft Spot Light", &LightTypeIndex, 4);
|
||||
|
||||
ImGui::ColorEdit3("Color", (float*)&LightColor);
|
||||
float radAngle = LightConeAngle/180.0f*M_PI;
|
||||
ImGui::SliderAngle("Cone angle", &radAngle, 0.0f, 180.0f);
|
||||
LightConeAngle = radAngle/M_PI*180.0f;
|
||||
ImGui::SliderFloat("Radius", &LightRadius, 0.1f, 500.0f);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void
|
||||
Render(float timeDelta)
|
||||
{
|
||||
Camera->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
Camera->beginUpdate();
|
||||
|
||||
ImGui_ImplRW_NewFrame(timeDelta);
|
||||
|
||||
World->render();
|
||||
|
||||
if(LightDrawOn && CurrentLight)
|
||||
DrawCurrentLight();
|
||||
|
||||
Gui();
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplRW_RenderDrawLists(ImGui::GetDrawData());
|
||||
|
||||
Camera->endUpdate();
|
||||
Camera->showRaster(0);
|
||||
}
|
||||
|
||||
void
|
||||
Idle(float timeDelta)
|
||||
{
|
||||
LightsUpdate();
|
||||
|
||||
Render(timeDelta);
|
||||
}
|
||||
|
||||
int MouseX, MouseY;
|
||||
int MouseDeltaX, MouseDeltaY;
|
||||
int MouseButtons;
|
||||
|
||||
int CtrlDown;
|
||||
|
||||
bool RotateLight;
|
||||
bool TranslateLightXY;
|
||||
bool TranslateLightZ;
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_LCTRL:
|
||||
case sk::KEY_RCTRL:
|
||||
CtrlDown = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_LCTRL:
|
||||
case sk::KEY_RCTRL:
|
||||
CtrlDown = 1;
|
||||
break;
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseBtn(sk::MouseState *mouse)
|
||||
{
|
||||
MouseButtons = mouse->buttons;
|
||||
RotateLight = !CtrlDown && !!(MouseButtons&1);
|
||||
TranslateLightXY = CtrlDown && !!(MouseButtons&1);
|
||||
TranslateLightZ = CtrlDown && !!(MouseButtons&4);
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(sk::MouseState *mouse)
|
||||
{
|
||||
MouseDeltaX = mouse->posx - MouseX;
|
||||
MouseDeltaY = mouse->posy - MouseY;
|
||||
MouseX = mouse->posx;
|
||||
MouseY = mouse->posy;
|
||||
|
||||
if(RotateLight)
|
||||
LightRotate(-MouseDeltaX, MouseDeltaY);
|
||||
if(TranslateLightXY)
|
||||
LightTranslateXY(-MouseDeltaX*0.1f, -MouseDeltaY*0.1f);
|
||||
if(TranslateLightZ)
|
||||
LightTranslateZ(-MouseDeltaY*0.1f);
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Initialize();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return Initialize3D() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
Terminate3D();
|
||||
return EVENTPROCESSED;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
if(!io.WantCaptureMouse){
|
||||
ms = (MouseState*)param;
|
||||
MouseBtn(ms);
|
||||
}else
|
||||
MouseButtons = 0;
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
MouseMove((MouseState*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
if(::Camera){
|
||||
sk::CameraSize(::Camera, r);
|
||||
::Camera->setFOV(FOV, (float)sk::globals.width/sk::globals.height);
|
||||
}
|
||||
break;
|
||||
case IDLE:
|
||||
Idle(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
7
vendor/librw/tools/lights/main.h
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
extern rw::World *World;
|
||||
extern rw::Camera *Camera;
|
||||
|
||||
extern rw::V3d Xaxis;
|
||||
extern rw::V3d Yaxis;
|
||||
extern rw::V3d Zaxis;
|
||||
22
vendor/librw/tools/playground/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
add_executable(playground WIN32
|
||||
camera.cpp
|
||||
font.cpp
|
||||
main.cpp
|
||||
ras_test.cpp
|
||||
splines.cpp
|
||||
tl_tests.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(playground
|
||||
PRIVATE
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET playground POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:playground>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/files" "$<TARGET_FILE_DIR:playground>/files"
|
||||
)
|
||||
|
||||
librw_platform_target(playground)
|
||||
134
vendor/librw/tools/playground/camera.cpp
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include <rw.h>
|
||||
|
||||
#define PI 3.14159265359f
|
||||
#include "camera.h"
|
||||
|
||||
using rw::Quat;
|
||||
using rw::V3d;
|
||||
|
||||
void
|
||||
Camera::update(void)
|
||||
{
|
||||
if(m_rwcam){
|
||||
m_rwcam->setNearPlane(m_near);
|
||||
m_rwcam->setFarPlane(m_far);
|
||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||
|
||||
rw::Frame *f = m_rwcam->getFrame();
|
||||
if(f){
|
||||
V3d forward = normalize(sub(m_target, m_position));
|
||||
V3d left = normalize(cross(m_up, forward));
|
||||
V3d nup = cross(forward, left);
|
||||
f->matrix.right = left; // lol
|
||||
f->matrix.up = nup;
|
||||
f->matrix.at = forward;
|
||||
f->matrix.pos = m_position;
|
||||
f->matrix.optimize();
|
||||
f->updateObjects();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setTarget(V3d target)
|
||||
{
|
||||
m_position = sub(m_position, sub(m_target, target));
|
||||
m_target = target;
|
||||
}
|
||||
|
||||
float
|
||||
Camera::getHeading(void)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float a = atan2(dir.y, dir.x)-PI/2.0f;
|
||||
return m_localup.z < 0.0f ? a-PI : a;
|
||||
}
|
||||
|
||||
void
|
||||
Camera::turn(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_target = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::orbit(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(-pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_position = sub(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::dolly(float dist)
|
||||
{
|
||||
V3d dir = setlength(sub(m_target, m_position), dist);
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::zoom(float dist)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float curdist = length(dir);
|
||||
if(dist >= curdist)
|
||||
dist = curdist-0.01f;
|
||||
dir = setlength(dir, dist);
|
||||
m_position = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::pan(float x, float y)
|
||||
{
|
||||
V3d dir = normalize(sub(m_target, m_position));
|
||||
V3d right = normalize(cross(dir, m_up));
|
||||
V3d localup = normalize(cross(right, dir));
|
||||
dir = add(scale(right, x), scale(localup, y));
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
float
|
||||
Camera::distanceTo(V3d v)
|
||||
{
|
||||
return length(sub(m_position, v));
|
||||
}
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
m_position.set(0.0f, 6.0f, 0.0f);
|
||||
m_target.set(0.0f, 0.0f, 0.0f);
|
||||
m_up.set(0.0f, 0.0f, 1.0f);
|
||||
m_localup = m_up;
|
||||
m_fov = 70.0f;
|
||||
m_aspectRatio = 1.0f;
|
||||
m_near = 0.1f;
|
||||
m_far = 100.0f;
|
||||
m_rwcam = NULL;
|
||||
}
|
||||
|
||||
26
vendor/librw/tools/playground/camera.h
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
class Camera
|
||||
{
|
||||
public:
|
||||
rw::Camera *m_rwcam;
|
||||
rw::V3d m_position;
|
||||
rw::V3d m_target;
|
||||
rw::V3d m_up;
|
||||
rw::V3d m_localup;
|
||||
|
||||
float m_fov, m_aspectRatio;
|
||||
float m_near, m_far;
|
||||
|
||||
|
||||
void setTarget(rw::V3d target);
|
||||
float getHeading(void);
|
||||
|
||||
void turn(float yaw, float pitch);
|
||||
void orbit(float yaw, float pitch);
|
||||
void dolly(float dist);
|
||||
void zoom(float dist);
|
||||
void pan(float x, float y);
|
||||
|
||||
void update(void);
|
||||
float distanceTo(rw::V3d v);
|
||||
Camera(void);
|
||||
};
|
||||
BIN
vendor/librw/tools/playground/files/Bm437_IBM_BIOS.FON
vendored
Normal file
BIN
vendor/librw/tools/playground/files/Bm437_IBM_BIOS.tga
vendored
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
vendor/librw/tools/playground/files/Bm437_IBM_VGA8.FON
vendored
Normal file
BIN
vendor/librw/tools/playground/files/Bm437_IBM_VGA8.tga
vendored
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
vendor/librw/tools/playground/files/foobar.tga
vendored
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
vendor/librw/tools/playground/files/maze.tga
vendored
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
vendor/librw/tools/playground/files/teapot.dff
vendored
Normal file
181
vendor/librw/tools/playground/font.cpp
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
using namespace rw;
|
||||
|
||||
struct Font
|
||||
{
|
||||
Texture *tex;
|
||||
int32 glyphwidth, glyphheight;
|
||||
int32 numglyphs;
|
||||
};
|
||||
Font vga = { nil, 8, 16, 256 };
|
||||
Font bios = { nil, 8, 8, 256 };
|
||||
Font *curfont = &bios;
|
||||
|
||||
#define NUMCHARS 100
|
||||
uint16 indices[NUMCHARS*6];
|
||||
RWDEVICE::Im2DVertex vertices[NUMCHARS*4];
|
||||
int32 curVert;
|
||||
int32 curIndex;
|
||||
|
||||
void
|
||||
printScreen(const char *s, float32 x, float32 y)
|
||||
{
|
||||
char c;
|
||||
Camera *cam;
|
||||
RWDEVICE::Im2DVertex *vert;
|
||||
uint16 *ix;
|
||||
curVert = 0;
|
||||
curIndex = 0;
|
||||
float32 u, v, du, dv;
|
||||
float recipZ;
|
||||
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
vert = &vertices[curVert];
|
||||
ix = &indices[curIndex];
|
||||
du = curfont->glyphwidth/(float32)curfont->tex->raster->width;
|
||||
dv = curfont->glyphheight/(float32)curfont->tex->raster->height;
|
||||
recipZ = 1.0f/cam->nearPlane;
|
||||
while(c = *s){
|
||||
if(c >= curfont->numglyphs)
|
||||
c = 0;
|
||||
u = (c % 16)*curfont->glyphwidth / (float32)curfont->tex->raster->width;
|
||||
v = (c / 16)*curfont->glyphheight / (float32)curfont->tex->raster->height;
|
||||
|
||||
vert->setScreenX(x);
|
||||
vert->setScreenY(y);
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(recipZ);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
vert->setU(u, recipZ);
|
||||
vert->setV(v, recipZ);
|
||||
vert++;
|
||||
|
||||
vert->setScreenX(x+curfont->glyphwidth);
|
||||
vert->setScreenY(y);
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(recipZ);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
vert->setU(u+du, recipZ);
|
||||
vert->setV(v, recipZ);
|
||||
vert++;
|
||||
|
||||
vert->setScreenX(x);
|
||||
vert->setScreenY(y+curfont->glyphheight);
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(recipZ);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
vert->setU(u, recipZ);
|
||||
vert->setV(v+dv, recipZ);
|
||||
vert++;
|
||||
|
||||
vert->setScreenX(x+curfont->glyphwidth);
|
||||
vert->setScreenY(y+curfont->glyphheight);
|
||||
vert->setScreenZ(rw::im2d::GetNearZ());
|
||||
vert->setCameraZ(cam->nearPlane);
|
||||
vert->setRecipCameraZ(recipZ);
|
||||
vert->setColor(255, 255, 255, 255);
|
||||
vert->setU(u+du, recipZ);
|
||||
vert->setV(v+dv, recipZ);
|
||||
vert++;
|
||||
|
||||
*ix++ = curVert;
|
||||
*ix++ = curVert+1;
|
||||
*ix++ = curVert+2;
|
||||
*ix++ = curVert+2;
|
||||
*ix++ = curVert+1;
|
||||
*ix++ = curVert+3;
|
||||
|
||||
curVert += 4;
|
||||
curIndex += 6;
|
||||
x += curfont->glyphwidth+1;
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, curfont->tex->raster);
|
||||
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||
|
||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST,
|
||||
vertices, curVert, indices, curIndex);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
initFont(void)
|
||||
{
|
||||
vga.tex = Texture::read("files/Bm437_IBM_VGA8", "");
|
||||
bios.tex = Texture::read("files/Bm437_IBM_BIOS", "");
|
||||
|
||||
/*
|
||||
FILE *foo = fopen("font.c", "w");
|
||||
assert(foo);
|
||||
int x, y;
|
||||
rw::Image *img = rw::readTGA("vga_font.tga");
|
||||
assert(img);
|
||||
for(y = 0; y < img->height; y++){
|
||||
for(x = 0; x < img->width; x++)
|
||||
fprintf(foo, "%d, ", !!img->pixels[y*img->width + x]);
|
||||
fprintf(foo, "\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
#define NUMGLYPHS 256
|
||||
#define GLYPHWIDTH 8
|
||||
#define GLYPHHEIGHT 16
|
||||
|
||||
|
||||
void
|
||||
convertFont(void)
|
||||
{
|
||||
FILE *f;
|
||||
Image *img;
|
||||
uint8 data[NUMGLYPHS*GLYPHHEIGHT];
|
||||
int32 i, x, y;
|
||||
uint8 *px, *line, *glyph;
|
||||
// f = fopen("font0.bin", "rb");
|
||||
f = fopen("files/Bm437_IBM_VGA8.FON", "rb");
|
||||
// f = fopen("files/Bm437_IBM_BIOS.FON", "rb");
|
||||
if(f == nil)
|
||||
return;
|
||||
fseek(f, 0x65A, 0);
|
||||
fread(data, 1, NUMGLYPHS*GLYPHHEIGHT, f);
|
||||
fclose(f);
|
||||
|
||||
img = Image::create(16*GLYPHWIDTH, NUMGLYPHS/16*GLYPHHEIGHT, 32);
|
||||
img->allocate();
|
||||
for(i = 0; i < NUMGLYPHS; i++){
|
||||
glyph = &data[i*GLYPHHEIGHT];
|
||||
x = (i % 16)*GLYPHWIDTH;
|
||||
y = (i / 16)*GLYPHHEIGHT;
|
||||
line = &img->pixels[x*4 + y*img->stride];
|
||||
for(y = 0; y < GLYPHHEIGHT; y++){
|
||||
px = line;
|
||||
for(x = 0; x < 8; x++){
|
||||
if(*glyph & 1<<(8-x)){
|
||||
*px++ = 255;
|
||||
*px++ = 255;
|
||||
*px++ = 255;
|
||||
*px++ = 255;
|
||||
}else{
|
||||
*px++ = 0;
|
||||
*px++ = 0;
|
||||
*px++ = 0;
|
||||
*px++ = 0;
|
||||
}
|
||||
}
|
||||
glyph++;
|
||||
line += img->stride;
|
||||
}
|
||||
}
|
||||
// writeTGA(img, "files/Bm437_IBM_BIOS.tga");
|
||||
writeTGA(img, "files/Bm437_IBM_VGA8.tga");
|
||||
}
|
||||
*/
|
||||
641
vendor/librw/tools/playground/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,641 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include "camera.h"
|
||||
#include <assert.h>
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
Camera *camera;
|
||||
struct SceneGlobals {
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
rw::Clump *clump;
|
||||
} Scene;
|
||||
rw::Texture *tex, *tex2;
|
||||
rw::Raster *testras;
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
|
||||
rw::Texture *frontbuffer;
|
||||
|
||||
bool dosoftras = 0;
|
||||
|
||||
namespace gen {
|
||||
void tlTest(rw::Clump *clump);
|
||||
}
|
||||
void genIm3DTransform(void *vertices, rw::int32 numVertices, rw::Matrix *xform);
|
||||
void genIm3DRenderIndexed(rw::PrimitiveType prim, void *indices, rw::int32 numIndices);
|
||||
void genIm3DEnd(void);
|
||||
void initFont(void);
|
||||
void printScreen(const char *s, float x, float y);
|
||||
|
||||
void initsplines(void);
|
||||
void rendersplines(void);
|
||||
|
||||
rw::Charset *testfont;
|
||||
|
||||
//#include <Windows.h>
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
// AllocConsole();
|
||||
// freopen("CONIN$", "r", stdin);
|
||||
// freopen("CONOUT$", "w", stdout);
|
||||
// freopen("CONOUT$", "w", stderr);
|
||||
|
||||
sk::globals.windowtitle = "Clump viewer";
|
||||
sk::globals.width = 640;
|
||||
sk::globals.height = 448;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
dumpUserData(rw::UserDataArray *ar)
|
||||
{
|
||||
int i;
|
||||
printf("name: %s\n", ar->name);
|
||||
for(i = 0; i < ar->numElements; i++){
|
||||
switch(ar->datatype){
|
||||
case rw::USERDATAINT:
|
||||
printf(" %d\n", ar->getInt(i));
|
||||
break;
|
||||
case rw::USERDATAFLOAT:
|
||||
printf(" %f\n", ar->getFloat(i));
|
||||
break;
|
||||
case rw::USERDATASTRING:
|
||||
printf(" %s\n", ar->getString(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static rw::Frame*
|
||||
dumpFrameUserDataCB(rw::Frame *f, void*)
|
||||
{
|
||||
using namespace rw;
|
||||
int32 i;
|
||||
UserDataArray *ar;
|
||||
int32 n = UserDataArray::frameGetCount(f);
|
||||
for(i = 0; i < n; i++){
|
||||
ar = UserDataArray::frameGet(f, i);
|
||||
dumpUserData(ar);
|
||||
}
|
||||
f->forAllChildren(dumpFrameUserDataCB, nil);
|
||||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
dumpUserData(rw::Clump *clump)
|
||||
{
|
||||
printf("Frames\n");
|
||||
dumpFrameUserDataCB(clump->getFrame(), nil);
|
||||
}
|
||||
|
||||
static rw::Frame*
|
||||
getHierCB(rw::Frame *f, void *data)
|
||||
{
|
||||
using namespace rw;
|
||||
HAnimData *hd = rw::HAnimData::get(f);
|
||||
if(hd->hierarchy){
|
||||
*(HAnimHierarchy**)data = hd->hierarchy;
|
||||
return nil;
|
||||
}
|
||||
f->forAllChildren(getHierCB, data);
|
||||
return f;
|
||||
}
|
||||
|
||||
rw::HAnimHierarchy*
|
||||
getHAnimHierarchyFromClump(rw::Clump *clump)
|
||||
{
|
||||
using namespace rw;
|
||||
HAnimHierarchy *hier = nil;
|
||||
getHierCB(clump->getFrame(), &hier);
|
||||
return hier;
|
||||
}
|
||||
|
||||
void
|
||||
setupAtomic(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
// just remove pipelines that we can't handle for now
|
||||
// if(atomic->pipeline && atomic->pipeline->platform != rw::platform)
|
||||
atomic->pipeline = NULL;
|
||||
|
||||
// Attach hierarchy to atomic if we're skinned
|
||||
HAnimHierarchy *hier = getHAnimHierarchyFromClump(atomic->clump);
|
||||
if(hier)
|
||||
Skin::setHierarchy(atomic, hier);
|
||||
}
|
||||
|
||||
static void
|
||||
initHierFromFrames(rw::HAnimHierarchy *hier)
|
||||
{
|
||||
using namespace rw;
|
||||
int32 i;
|
||||
for(i = 0; i < hier->numNodes; i++){
|
||||
if(hier->nodeInfo[i].frame){
|
||||
hier->matrices[hier->nodeInfo[i].index] = *hier->nodeInfo[i].frame->getLTM();
|
||||
}else
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setupClump(rw::Clump *clump)
|
||||
{
|
||||
using namespace rw;
|
||||
HAnimHierarchy *hier = getHAnimHierarchyFromClump(clump);
|
||||
if(hier){
|
||||
hier->attach();
|
||||
initHierFromFrames(hier);
|
||||
}
|
||||
|
||||
FORLIST(lnk, clump->atomics){
|
||||
rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||
setupAtomic(a);
|
||||
}
|
||||
}
|
||||
|
||||
#define MUL(x, y) ((x)*(y)/255)
|
||||
|
||||
int
|
||||
calcVCfx(int fb, int col, int a, int iter)
|
||||
{
|
||||
int prev = fb;
|
||||
int col2 = col*2;
|
||||
if(col2 > 255) col2 = 255;
|
||||
for(int i = 0; i < iter; i++){
|
||||
int tmp = MUL(fb, 255-a) + MUL(MUL(prev, col2), a);
|
||||
tmp += MUL(prev, col);
|
||||
tmp += MUL(prev, col);
|
||||
prev = tmp > 255 ? 255 : tmp;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
int
|
||||
calcIIIfx(int fb, int col, int a, int iter)
|
||||
{
|
||||
int prev = fb;
|
||||
for(int i = 0; i < iter; i++){
|
||||
int tmp = MUL(fb, 255-a) + MUL(MUL(prev, col), a);
|
||||
prev = tmp > 255 ? 255 : tmp;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
void
|
||||
postfxtest(void)
|
||||
{
|
||||
rw::Image *img = rw::Image::create(256, 256, 32);
|
||||
img->allocate();
|
||||
int x, y;
|
||||
int iter;
|
||||
static char filename[100];
|
||||
for(iter = 0; iter < 10; iter++){
|
||||
for(y = 0; y < 256; y++)
|
||||
for(x = 0; x < 256; x++){
|
||||
int res = calcVCfx(y, x, 30, iter);
|
||||
// int res = calcIIIfx(y, x, 30, iter);
|
||||
if(0 && res == y){
|
||||
img->pixels[y*img->stride + x*img->bpp + 0] = 255;
|
||||
img->pixels[y*img->stride + x*img->bpp + 1] = 0;
|
||||
img->pixels[y*img->stride + x*img->bpp + 2] = 0;
|
||||
}else{
|
||||
img->pixels[y*img->stride + x*img->bpp + 0] = res;
|
||||
img->pixels[y*img->stride + x*img->bpp + 1] = res;
|
||||
img->pixels[y*img->stride + x*img->bpp + 2] = res;
|
||||
}
|
||||
img->pixels[y*img->stride + x*img->bpp + 3] = 255;
|
||||
}
|
||||
sprintf(filename, "vcfx_%02d.bmp", iter);
|
||||
// sprintf(filename, "iiifx_%02d.bmp", iter);
|
||||
rw::writeBMP(img, filename);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
bool
|
||||
InitRW(void)
|
||||
{
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
rw::d3d::isP8supported = false;
|
||||
|
||||
// postfxtest();
|
||||
|
||||
initFont();
|
||||
|
||||
rw::RGBA foreground = { 255, 255, 0, 255 };
|
||||
rw::RGBA background = { 0, 0, 0, 0 };
|
||||
rw::Charset::open();
|
||||
testfont = rw::Charset::create(&foreground, &background);
|
||||
assert(testfont);
|
||||
foreground.blue = 255.0f;
|
||||
testfont->setColors(&foreground, &background);
|
||||
|
||||
tex = rw::Texture::read("files/maze", nil);
|
||||
tex2 = rw::Texture::read("files/checkers", nil);
|
||||
|
||||
const char *filename = "files/teapot.dff";
|
||||
if(sk::args.argc > 1)
|
||||
filename = sk::args.argv[1];
|
||||
rw::StreamFile in;
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return false;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
Scene.clump = rw::Clump::streamRead(&in);
|
||||
assert(Scene.clump);
|
||||
in.close();
|
||||
|
||||
// TEST - Set texture to the all materials of the clump
|
||||
// FORLIST(lnk, Scene.clump->atomics){
|
||||
// rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||
// for(int i = 0; i < a->geometry->matList.numMaterials; i++)
|
||||
// a->geometry->matList.materials[i]->setTexture(tex);
|
||||
// }
|
||||
|
||||
Scene.clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
|
||||
dumpUserData(Scene.clump);
|
||||
setupClump(Scene.clump);
|
||||
|
||||
Scene.world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
ambient->setColor(0.3f, 0.3f, 0.3f);
|
||||
Scene.world->addLight(ambient);
|
||||
|
||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
Scene.world->addLight(direct);
|
||||
|
||||
camera = new Camera;
|
||||
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
camera->m_rwcam = Scene.camera;
|
||||
camera->m_aspectRatio = 640.0f/448.0f;
|
||||
// camera->m_near = 0.5f;
|
||||
camera->m_near = 1.5f;
|
||||
// camera->m_far = 450.0f;
|
||||
camera->m_far = 15.0f;
|
||||
camera->m_target.set(0.0f, 0.0f, 0.0f);
|
||||
camera->m_position.set(0.0f, -10.0f, 0.0f);
|
||||
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -70.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
camera->update();
|
||||
|
||||
Scene.world->addCamera(camera->m_rwcam);
|
||||
|
||||
initsplines();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
im2dtest(void)
|
||||
{
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
static struct
|
||||
{
|
||||
float x, y;
|
||||
rw::uint8 r, g, b, a;
|
||||
float u, v;
|
||||
} vs[4] = {
|
||||
{ 0.0f, 0.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ 640.0f, 0.0f, 0, 255, 0, 128, 1.0f, 0.0f },
|
||||
{ 0.0f, 448.0f, 0, 0, 255, 128, 0.0f, 1.0f },
|
||||
{ 640.0f, 448.0f, 0, 255, 255, 128, 1.0f, 1.0f },
|
||||
/*
|
||||
{ 0.0f, 0.0f, 255, 0, 0, 128, 0.0f, 1.0f },
|
||||
{ 640.0f, 0.0f, 0, 255, 0, 128, 0.0f, 0.0f },
|
||||
{ 0.0f, 448.0f, 0, 0, 255, 128, 1.0f, 1.0f },
|
||||
{ 640.0f, 448.0f, 0, 255, 255, 128, 1.0f, 0.0f },
|
||||
*/
|
||||
};
|
||||
Im2DVertex verts[4];
|
||||
static short indices[] = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
float recipZ = 1.0f/Scene.camera->nearPlane;
|
||||
for(i = 0; i < 4; i++){
|
||||
verts[i].setScreenX(vs[i].x);
|
||||
verts[i].setScreenY(vs[i].y);
|
||||
verts[i].setScreenZ(rw::im2d::GetNearZ());
|
||||
verts[i].setCameraZ(Scene.camera->nearPlane);
|
||||
verts[i].setRecipCameraZ(recipZ);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
if(dosoftras)
|
||||
verts[i].setColor(255, 255, 255, 255);
|
||||
verts[i].setU(vs[i].u + 0.5f/640.0f, recipZ);
|
||||
verts[i].setV(vs[i].v + 0.5f/448.0f, recipZ);
|
||||
}
|
||||
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||
if(dosoftras)
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, testras);
|
||||
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
&verts, 4, &indices, 4);
|
||||
}
|
||||
|
||||
void
|
||||
im2dtest2(void)
|
||||
{
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
rw::Camera *cam = Scene.camera;
|
||||
float n = cam->nearPlane;
|
||||
float f = cam->farPlane;
|
||||
float mid = (n+f)/4.0f;
|
||||
struct
|
||||
{
|
||||
float x, y, z;
|
||||
rw::uint8 r, g, b, a;
|
||||
float u, v;
|
||||
} vs[4] = {
|
||||
{ 0.5f, 0.5f, n, 255, 255, 255, 255, 0.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, mid, 255, 255, 255, 255, 1.0f, 0.0f },
|
||||
{ 0.5f, -0.5f, n, 255, 255, 255, 255, 0.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, mid, 255, 255, 255, 255, 1.0f, 1.0f },
|
||||
};
|
||||
Im2DVertex verts[4];
|
||||
static short indices[] = {
|
||||
0, 1, 2, 3
|
||||
};
|
||||
|
||||
for(i = 0; i < 4; i++){
|
||||
float recipZ = 1.0f/vs[i].z;
|
||||
verts[i].setScreenX((vs[i].x*recipZ + 0.5f) * 640.0f);
|
||||
verts[i].setScreenY((vs[i].y*recipZ + 0.5f) * 448.0f);
|
||||
verts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
// verts[i].setCameraZ(vs[i].z);
|
||||
verts[i].setRecipCameraZ(recipZ);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
if(dosoftras)
|
||||
verts[i].setColor(255, 255, 255, 255);
|
||||
verts[i].setU(vs[i].u + 0.5f/640.0f, recipZ);
|
||||
verts[i].setV(vs[i].v + 0.5f/448.0f, recipZ);
|
||||
}
|
||||
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||
rw::SetRenderState(rw::VERTEXALPHA, 1);
|
||||
rw::im2d::RenderIndexedPrimitive(rw::PRIMTYPETRISTRIP,
|
||||
&verts, 4, &indices, 4);
|
||||
}
|
||||
|
||||
void
|
||||
im3dtest(void)
|
||||
{
|
||||
using namespace rw::RWDEVICE;
|
||||
int i;
|
||||
static struct
|
||||
{
|
||||
float x, y, z;
|
||||
rw::uint8 r, g, b, a;
|
||||
float u, v;
|
||||
} vs[8] = {
|
||||
{ -1.0f, -1.0f, -1.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, -1.0f, 0, 255, 0, 128, 0.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, -1.0f, 0, 0, 255, 128, 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, -1.0f, 255, 0, 255, 128, 1.0f, 1.0f },
|
||||
|
||||
{ -1.0f, -1.0f, 1.0f, 255, 0, 0, 128, 0.0f, 0.0f },
|
||||
{ -1.0f, 1.0f, 1.0f, 0, 255, 0, 128, 0.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 0, 0, 255, 128, 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 255, 0, 255, 128, 1.0f, 1.0f },
|
||||
};
|
||||
Im3DVertex verts[8];
|
||||
static short indices[2*6] = {
|
||||
0, 1, 2, 2, 1, 3,
|
||||
4, 5, 6, 6, 5, 7
|
||||
};
|
||||
|
||||
for(i = 0; i < 8; i++){
|
||||
verts[i].setX(vs[i].x);
|
||||
verts[i].setY(vs[i].y);
|
||||
verts[i].setZ(vs[i].z);
|
||||
verts[i].setColor(vs[i].r, vs[i].g, vs[i].b, vs[i].a);
|
||||
verts[i].setU(vs[i].u);
|
||||
verts[i].setV(vs[i].v);
|
||||
}
|
||||
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster);
|
||||
// rw::SetRenderStatePtr(rw::TEXTURERASTER, testfont->raster);
|
||||
// rw::SetRenderStatePtr(rw::TEXTURERASTER, frontbuffer->raster);
|
||||
rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP);
|
||||
rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST);
|
||||
|
||||
/*
|
||||
genIm3DTransform(verts, 8, nil);
|
||||
genIm3DRenderIndexed(rw::PRIMTYPETRILIST, indices, 12);
|
||||
genIm3DEnd();
|
||||
*/
|
||||
rw::im3d::Transform(verts, 8, nil, rw::im3d::EVERYTHING);
|
||||
rw::im3d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, indices, 12);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
getFrontBuffer(void)
|
||||
{
|
||||
rw::Raster *fb = Scene.camera->frameBuffer;
|
||||
|
||||
if(frontbuffer == nil || fb->width > frontbuffer->raster->width || fb->height > frontbuffer->raster->height){
|
||||
int w, h;
|
||||
for(w = 1; w < fb->width; w <<= 1);
|
||||
for(h = 1; h < fb->height; h <<= 1);
|
||||
rw::Raster *ras = rw::Raster::create(w, h, fb->depth, rw::Raster::CAMERATEXTURE);
|
||||
if(frontbuffer){
|
||||
frontbuffer->raster->destroy();
|
||||
frontbuffer->raster = ras;
|
||||
}else
|
||||
frontbuffer = rw::Texture::create(ras);
|
||||
printf("created FB with %d %d %d\n", ras->width, ras->height, ras->depth);
|
||||
}
|
||||
|
||||
rw::Raster::pushContext(frontbuffer->raster);
|
||||
fb->renderFast(0, 0);
|
||||
rw::Raster::popContext();
|
||||
}
|
||||
|
||||
void
|
||||
Draw(float timeDelta)
|
||||
{
|
||||
getFrontBuffer();
|
||||
|
||||
rw::SetRenderState(rw::FOGCOLOR, 0xFF0000FF);
|
||||
rw::SetRenderState(rw::FOGENABLE, 1);
|
||||
camera->m_rwcam->fogPlane = camera->m_rwcam->nearPlane;
|
||||
|
||||
static rw::RGBA clearcol = { 161, 161, 161, 0xFF };
|
||||
camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
extern void beginSoftras(void);
|
||||
beginSoftras();
|
||||
|
||||
// gen::tlTest(Scene.clump);
|
||||
void drawtest(void);
|
||||
// drawtest();
|
||||
|
||||
extern void endSoftras(void);
|
||||
if(dosoftras){
|
||||
endSoftras();
|
||||
}
|
||||
//im2dtest();
|
||||
im2dtest2();
|
||||
|
||||
// Scene.clump->render();
|
||||
// im3dtest();
|
||||
// printScreen("Hello, World!", 10, 10);
|
||||
|
||||
// testfont->print("foo ABC", 200, 200, true);
|
||||
|
||||
// rendersplines();
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
|
||||
camera->m_rwcam->showRaster(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case 'W':
|
||||
camera->orbit(0.0f, 0.1f);
|
||||
break;
|
||||
case 'S':
|
||||
camera->orbit(0.0f, -0.1f);
|
||||
break;
|
||||
case 'A':
|
||||
camera->orbit(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'D':
|
||||
camera->orbit(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_UP:
|
||||
camera->turn(0.0f, 0.1f);
|
||||
break;
|
||||
case sk::KEY_DOWN:
|
||||
camera->turn(0.0f, -0.1f);
|
||||
break;
|
||||
case sk::KEY_LEFT:
|
||||
camera->turn(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_RIGHT:
|
||||
camera->turn(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'R':
|
||||
camera->zoom(0.1f);
|
||||
break;
|
||||
case 'F':
|
||||
camera->zoom(-0.1f);
|
||||
break;
|
||||
case 'V':
|
||||
dosoftras = !dosoftras;
|
||||
break;
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MouseButton(int buttons)
|
||||
{
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Init();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
ms = (MouseState*)param;
|
||||
MouseButton(ms->buttons);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
ms = (MouseState*)param;
|
||||
MouseMove(ms->posx, ms->posy);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
if(camera)
|
||||
camera->m_aspectRatio = (float)r->w/r->h;
|
||||
if(Scene.camera)
|
||||
sk::CameraSize(Scene.camera, r);
|
||||
break;
|
||||
case IDLE:
|
||||
Draw(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
902
vendor/librw/tools/playground/ras_test.cpp
vendored
Normal file
|
|
@ -0,0 +1,902 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
namespace rs {
|
||||
|
||||
typedef int8_t i8;
|
||||
typedef uint8_t u8;
|
||||
typedef int16_t i16;
|
||||
typedef uint16_t u16;
|
||||
typedef int32_t i32;
|
||||
typedef uint32_t u32;
|
||||
typedef int64_t i64;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef struct Canvas Canvas;
|
||||
struct Canvas
|
||||
{
|
||||
u8 *fb;
|
||||
u32 *zbuf;
|
||||
int w, h;
|
||||
};
|
||||
extern Canvas *canvas;
|
||||
|
||||
typedef struct Texture Texture;
|
||||
struct Texture
|
||||
{
|
||||
u8 *pixels;
|
||||
int w, h;
|
||||
int wrap;
|
||||
};
|
||||
|
||||
typedef struct Point3 Point3;
|
||||
struct Point3
|
||||
{
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
typedef struct Color Color;
|
||||
struct Color
|
||||
{
|
||||
u8 r, g, b, a;
|
||||
};
|
||||
|
||||
typedef struct Vertex Vertex;
|
||||
struct Vertex
|
||||
{
|
||||
i32 x, y, z;
|
||||
float q; // 1/z
|
||||
u8 r, g, b, a;
|
||||
u8 f; // fog
|
||||
float s, t;
|
||||
};
|
||||
|
||||
Canvas *makecanvas(int w, int h);
|
||||
Texture *maketexture(int w, int h);
|
||||
void putpixel(Canvas *canvas, Point3 p, Color c);
|
||||
void clearcanvas(Canvas *canvas);
|
||||
void drawTriangle(Canvas *canvas, Vertex p1, Vertex p2, Vertex p3);
|
||||
|
||||
// not good
|
||||
void drawRect(Canvas *canvas, Point3 p1, Point3 p2, Color c);
|
||||
void drawLine(Canvas *canvas, Point3 p1, Point3 p2, Color c);
|
||||
|
||||
//#define trace(...) printf(__VA_ARGS__)
|
||||
#define trace(...)
|
||||
|
||||
|
||||
int clamp(int x);
|
||||
|
||||
|
||||
/*
|
||||
* Render States
|
||||
*/
|
||||
enum TextureWrap {
|
||||
WRAP_REPEAT,
|
||||
WRAP_CLAMP,
|
||||
WRAP_BORDER,
|
||||
};
|
||||
|
||||
enum TextureFunction {
|
||||
TFUNC_MODULATE,
|
||||
TFUNC_DECAL,
|
||||
TFUNC_HIGHLIGHT,
|
||||
TFUNC_HIGHLIGHT2,
|
||||
};
|
||||
|
||||
enum AlphaTestFunc {
|
||||
ALPHATEST_NEVER,
|
||||
ALPHATEST_ALWAYS,
|
||||
ALPHATEST_LESS,
|
||||
ALPHATEST_LEQUAL,
|
||||
ALPHATEST_EQUAL,
|
||||
ALPHATEST_GEQUAL,
|
||||
ALPHATEST_GREATER,
|
||||
ALPHATEST_NOTEQUAL,
|
||||
};
|
||||
|
||||
enum AlphaTestFail {
|
||||
ALPHAFAIL_KEEP,
|
||||
ALPHAFAIL_FB_ONLY,
|
||||
ALPHAFAIL_ZB_ONLY,
|
||||
};
|
||||
|
||||
enum DepthTestFunc {
|
||||
DEPTHTEST_NEVER,
|
||||
DEPTHTEST_ALWAYS,
|
||||
DEPTHTEST_GEQUAL,
|
||||
DEPTHTEST_GREATER,
|
||||
};
|
||||
|
||||
// The blend equation is
|
||||
// out = ((A - B) * C >> 7) + D
|
||||
// A, B and D select the color, C the alpha value
|
||||
enum AlphaBlendOp {
|
||||
ALPHABLEND_SRC,
|
||||
ALPHABLEND_DST,
|
||||
ALPHABLEND_ZERO,
|
||||
ALPHABLEND_FIX = ALPHABLEND_ZERO,
|
||||
};
|
||||
|
||||
extern int srScissorX0, srScissorX1;
|
||||
extern int srScissorY0, srScissorY1;
|
||||
extern int srDepthTestEnable;
|
||||
extern int srDepthTestFunction;
|
||||
extern int srWriteZ;
|
||||
extern int srAlphaTestEnable;
|
||||
extern int srAlphaTestFunction;
|
||||
extern int srAlphaTestReference;
|
||||
extern int srAlphaTestFail;
|
||||
extern int srAlphaBlendEnable;
|
||||
extern int srAlphaBlendA;
|
||||
extern int srAlphaBlendB;
|
||||
extern int srAlphaBlendC;
|
||||
extern int srAlphaBlendD;
|
||||
extern int srAlphaBlendFix;
|
||||
extern int srTexEnable;
|
||||
extern Texture *srTexture;
|
||||
extern int srWrapU;
|
||||
extern int srWrapV;
|
||||
extern Color srBorder;
|
||||
extern int srTexUseAlpha;
|
||||
extern int srTexFunc;
|
||||
extern int srFogEnable;
|
||||
extern Color srFogCol;
|
||||
|
||||
|
||||
|
||||
// end header
|
||||
|
||||
|
||||
|
||||
|
||||
#define CEIL(p) (((p)+15) >> 4)
|
||||
|
||||
// render states
|
||||
int srScissorX0, srScissorX1;
|
||||
int srScissorY0, srScissorY1;
|
||||
int srDepthTestEnable = 1;
|
||||
int srDepthTestFunction = DEPTHTEST_GEQUAL;
|
||||
int srWriteZ = 1;
|
||||
int srAlphaTestEnable = 1;
|
||||
int srAlphaTestFunction = ALPHATEST_ALWAYS;
|
||||
int srAlphaTestReference;
|
||||
int srAlphaTestFail = ALPHAFAIL_FB_ONLY;
|
||||
int srAlphaBlendEnable = 1;
|
||||
int srAlphaBlendA = ALPHABLEND_SRC;
|
||||
int srAlphaBlendB = ALPHABLEND_DST;
|
||||
int srAlphaBlendC = ALPHABLEND_SRC;
|
||||
int srAlphaBlendD = ALPHABLEND_DST;
|
||||
int srAlphaBlendFix = 0x80;
|
||||
int srTexEnable = 0;
|
||||
Texture *srTexture;
|
||||
int srWrapU = WRAP_REPEAT;
|
||||
int srWrapV = WRAP_REPEAT;
|
||||
Color srBorder = { 255, 0, 0, 255 };
|
||||
int srTexUseAlpha = 1;
|
||||
int srTexFunc = TFUNC_MODULATE;
|
||||
int srFogEnable = 0;
|
||||
Color srFogCol = { 0, 0, 0, 0 };
|
||||
|
||||
int clamp(int x) { if(x < 0) return 0; if(x > 255) return 255; return x; }
|
||||
|
||||
Canvas*
|
||||
makecanvas(int w, int h)
|
||||
{
|
||||
Canvas *canv;
|
||||
canv = (Canvas*)malloc(sizeof(*canv) + w*h*(4+4));
|
||||
canv->w = w;
|
||||
canv->h = h;
|
||||
canv->fb = ((u8*)canv + sizeof(*canv));
|
||||
canv->zbuf = (u32*)(canv->fb + w*h*4);
|
||||
return canv;
|
||||
}
|
||||
|
||||
Texture*
|
||||
maketexture(int w, int h)
|
||||
{
|
||||
Texture *t;
|
||||
t = (Texture*)malloc(sizeof(*t) + w*h*4);
|
||||
t->w = w;
|
||||
t->h = h;
|
||||
t->pixels = (u8*)t + sizeof(*t);
|
||||
t->wrap = 0x11; // wrap u and v
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
clearcanvas(Canvas *canvas)
|
||||
{
|
||||
memset(canvas->fb, 0, canvas->w*canvas->h*4);
|
||||
memset(canvas->zbuf, 0, canvas->w*canvas->h*4);
|
||||
}
|
||||
|
||||
void
|
||||
writefb(Canvas *canvas, int x, int y, Color c)
|
||||
{
|
||||
u8 *px = &canvas->fb[(y*canvas->w + x)*4];
|
||||
u32 *z = &canvas->zbuf[y*canvas->w + x];
|
||||
|
||||
px[3] = c.r;
|
||||
px[2] = c.g;
|
||||
px[1] = c.b;
|
||||
px[0] = c.a;
|
||||
}
|
||||
|
||||
void
|
||||
putpixel(Canvas *canvas, Point3 p, Color c)
|
||||
{
|
||||
// scissor test
|
||||
if(p.x < srScissorX0 || p.x > srScissorX1 ||
|
||||
p.y < srScissorY0 || p.y > srScissorY1)
|
||||
return;
|
||||
|
||||
u8 *px = &canvas->fb[(p.y*canvas->w + p.x)*4];
|
||||
u32 *z = &canvas->zbuf[p.y*canvas->w + p.x];
|
||||
|
||||
int fbwrite = 1;
|
||||
int zbwrite = srWriteZ;
|
||||
|
||||
// alpha test
|
||||
if(srAlphaTestEnable){
|
||||
int fail;
|
||||
switch(srAlphaTestFunction){
|
||||
case ALPHATEST_NEVER:
|
||||
fail = 1;
|
||||
break;
|
||||
case ALPHATEST_ALWAYS:
|
||||
fail = 0;
|
||||
break;
|
||||
case ALPHATEST_LESS:
|
||||
fail = c.a >= srAlphaTestReference;
|
||||
break;
|
||||
case ALPHATEST_LEQUAL:
|
||||
fail = c.a > srAlphaTestReference;
|
||||
break;
|
||||
case ALPHATEST_EQUAL:
|
||||
fail = c.a != srAlphaTestReference;
|
||||
break;
|
||||
case ALPHATEST_GEQUAL:
|
||||
fail = c.a < srAlphaTestReference;
|
||||
break;
|
||||
case ALPHATEST_GREATER:
|
||||
fail = c.a <= srAlphaTestReference;
|
||||
break;
|
||||
case ALPHATEST_NOTEQUAL:
|
||||
fail = c.a == srAlphaTestReference;
|
||||
break;
|
||||
}
|
||||
if(fail){
|
||||
switch(srAlphaTestFail){
|
||||
case ALPHAFAIL_KEEP:
|
||||
return;
|
||||
case ALPHAFAIL_FB_ONLY:
|
||||
zbwrite = 0;
|
||||
break;
|
||||
case ALPHAFAIL_ZB_ONLY:
|
||||
fbwrite = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ztest
|
||||
if(srDepthTestEnable){
|
||||
switch(srDepthTestFunction){
|
||||
case DEPTHTEST_NEVER:
|
||||
return;
|
||||
case DEPTHTEST_ALWAYS:
|
||||
break;
|
||||
case DEPTHTEST_GEQUAL:
|
||||
if((u32)p.z < *z)
|
||||
return;
|
||||
break;
|
||||
case DEPTHTEST_GREATER:
|
||||
if((u32)p.z <= *z)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Color d = { px[3], px[2], px[1], px[0] };
|
||||
|
||||
// blend
|
||||
if(srAlphaBlendEnable){
|
||||
int ar, ag, ab;
|
||||
int br, bg, bb;
|
||||
int dr, dg, db;
|
||||
int ca;
|
||||
switch(srAlphaBlendA){
|
||||
case ALPHABLEND_SRC:
|
||||
ar = c.r;
|
||||
ag = c.g;
|
||||
ab = c.b;
|
||||
break;
|
||||
case ALPHABLEND_DST:
|
||||
ar = d.r;
|
||||
ag = d.g;
|
||||
ab = d.b;
|
||||
break;
|
||||
case ALPHABLEND_ZERO:
|
||||
ar = 0;
|
||||
ag = 0;
|
||||
ab = 0;
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
switch(srAlphaBlendB){
|
||||
case ALPHABLEND_SRC:
|
||||
br = c.r;
|
||||
bg = c.g;
|
||||
bb = c.b;
|
||||
break;
|
||||
case ALPHABLEND_DST:
|
||||
br = d.r;
|
||||
bg = d.g;
|
||||
bb = d.b;
|
||||
break;
|
||||
case ALPHABLEND_ZERO:
|
||||
br = 0;
|
||||
bg = 0;
|
||||
bb = 0;
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
switch(srAlphaBlendC){
|
||||
case ALPHABLEND_SRC:
|
||||
ca = c.a;
|
||||
break;
|
||||
case ALPHABLEND_DST:
|
||||
ca = d.a;
|
||||
break;
|
||||
case ALPHABLEND_FIX:
|
||||
ca = srAlphaBlendFix;
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
switch(srAlphaBlendD){
|
||||
case ALPHABLEND_SRC:
|
||||
dr = c.r;
|
||||
dg = c.g;
|
||||
db = c.b;
|
||||
break;
|
||||
case ALPHABLEND_DST:
|
||||
dr = d.r;
|
||||
dg = d.g;
|
||||
db = d.b;
|
||||
break;
|
||||
case ALPHABLEND_ZERO:
|
||||
dr = 0;
|
||||
dg = 0;
|
||||
db = 0;
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
int r, g, b;
|
||||
r = ((ar - br) * ca >> 7) + dr;
|
||||
g = ((ag - bg) * ca >> 7) + dg;
|
||||
b = ((ab - bb) * ca >> 7) + db;
|
||||
|
||||
c.r = clamp(r);
|
||||
c.g = clamp(g);
|
||||
c.b = clamp(b);
|
||||
}
|
||||
|
||||
if(fbwrite)
|
||||
writefb(canvas, p.x, p.y, c);
|
||||
if(zbwrite)
|
||||
*z = p.z;
|
||||
}
|
||||
|
||||
Color
|
||||
sampletex_nearest(int u, int v)
|
||||
{
|
||||
Texture *tex = srTexture;
|
||||
|
||||
const int usize = tex->w;
|
||||
const int vsize = tex->h;
|
||||
|
||||
int iu = u >> 4;
|
||||
int iv = v >> 4;
|
||||
|
||||
switch(srWrapU){
|
||||
case WRAP_REPEAT:
|
||||
iu %= usize;
|
||||
break;
|
||||
case WRAP_CLAMP:
|
||||
if(iu < 0) iu = 0;
|
||||
if(iu >= usize) iu = usize-1;
|
||||
break;
|
||||
case WRAP_BORDER:
|
||||
if(iu < 0 || iu >= usize)
|
||||
return srBorder;
|
||||
}
|
||||
|
||||
switch(srWrapV){
|
||||
case WRAP_REPEAT:
|
||||
iv %= vsize;
|
||||
break;
|
||||
case WRAP_CLAMP:
|
||||
if(iv < 0) iv = 0;
|
||||
if(iv >= vsize) iv = vsize-1;
|
||||
break;
|
||||
case WRAP_BORDER:
|
||||
if(iv < 0 || iv >= vsize)
|
||||
return srBorder;
|
||||
}
|
||||
|
||||
u8 *cp = &tex->pixels[(iv*tex->w + iu)*4];
|
||||
Color c = { cp[0], cp[1], cp[2], cp[3] };
|
||||
return c;
|
||||
}
|
||||
|
||||
// t is texture, f is fragment
|
||||
Color
|
||||
texfunc(Color t, Color f)
|
||||
{
|
||||
int r, g, b, a;
|
||||
switch(srTexFunc){
|
||||
case TFUNC_MODULATE:
|
||||
r = t.r * f.r >> 7;
|
||||
g = t.g * f.g >> 7;
|
||||
b = t.b * f.b >> 7;
|
||||
a = srTexUseAlpha ?
|
||||
t.a * f.a >> 7 :
|
||||
f.a;
|
||||
break;
|
||||
case TFUNC_DECAL:
|
||||
r = t.r;
|
||||
g = t.g;
|
||||
b = t.b;
|
||||
a = srTexUseAlpha ? t.a : f.a;
|
||||
break;
|
||||
case TFUNC_HIGHLIGHT:
|
||||
r = (t.r * f.r >> 7) + f.a;
|
||||
g = (t.g * f.g >> 7) + f.a;
|
||||
b = (t.b * f.b >> 7) + f.a;
|
||||
a = srTexUseAlpha ?
|
||||
t.a + f.a :
|
||||
f.a;
|
||||
break;
|
||||
case TFUNC_HIGHLIGHT2:
|
||||
r = (t.r * f.r >> 7) + f.a;
|
||||
g = (t.g * f.g >> 7) + f.a;
|
||||
b = (t.b * f.b >> 7) + f.a;
|
||||
a = srTexUseAlpha ? t.a : f.a;
|
||||
break;
|
||||
}
|
||||
Color v;
|
||||
v.r = clamp(r);
|
||||
v.g = clamp(g);
|
||||
v.b = clamp(b);
|
||||
v.a = clamp(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
Point3 mkpnt(int x, int y, int z) { Point3 p = { x, y, z}; return p; }
|
||||
|
||||
void
|
||||
drawRect(Canvas *canvas, Point3 p1, Point3 p2, Color c)
|
||||
{
|
||||
int x, y;
|
||||
for(y = p1.y; y <= p2.y; y++)
|
||||
for(x = p1.x; x <= p2.x; x++)
|
||||
putpixel(canvas, mkpnt(x, y, 0), c);
|
||||
}
|
||||
|
||||
void
|
||||
drawLine(Canvas *canvas, Point3 p1, Point3 p2, Color c)
|
||||
{
|
||||
int dx, dy;
|
||||
int incx, incy;
|
||||
int e;
|
||||
int x, y;
|
||||
|
||||
dx = abs(p2.x-p1.x);
|
||||
incx = p2.x > p1.x ? 1 : -1;
|
||||
dy = abs(p2.y-p1.y);
|
||||
incy = p2.y > p1.y ? 1 : -1;
|
||||
e = 0;
|
||||
if(dx == 0){
|
||||
for(y = p1.y; y != p2.y; y += incy)
|
||||
putpixel(canvas, mkpnt(p1.x, y, 0), c);
|
||||
}else if(dx > dy){
|
||||
y = p1.y;
|
||||
for(x = p1.x; x != p2.x; x += incx){
|
||||
putpixel(canvas, mkpnt(x, y, 0), c);
|
||||
e += dy;
|
||||
if(2*e >= dx){
|
||||
e -= dx;
|
||||
y += incy;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
x = p1.x;
|
||||
for(y = p1.y; y != p2.y; y += incy){
|
||||
putpixel(canvas, mkpnt(x, y, 0), c);
|
||||
e += dx;
|
||||
if(2*e >= dy){
|
||||
e -= dy;
|
||||
x += incx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
attibutes we want to interpolate:
|
||||
R G B A
|
||||
U V / S T Q
|
||||
X Y Z F
|
||||
*/
|
||||
|
||||
struct TriAttribs
|
||||
{
|
||||
i64 z;
|
||||
i32 r, g, b, a;
|
||||
i32 f;
|
||||
float s, t;
|
||||
float q;
|
||||
};
|
||||
|
||||
static void
|
||||
add1(struct TriAttribs *a, struct TriAttribs *b)
|
||||
{
|
||||
a->z += b->z;
|
||||
a->r += b->r;
|
||||
a->g += b->g;
|
||||
a->b += b->b;
|
||||
a->a += b->a;
|
||||
a->f += b->f;
|
||||
a->s += b->s;
|
||||
a->t += b->t;
|
||||
a->q += b->q;
|
||||
}
|
||||
|
||||
static void
|
||||
sub1(struct TriAttribs *a, struct TriAttribs *b)
|
||||
{
|
||||
a->z -= b->z;
|
||||
a->r -= b->r;
|
||||
a->g -= b->g;
|
||||
a->b -= b->b;
|
||||
a->a -= b->a;
|
||||
a->f -= b->f;
|
||||
a->s -= b->s;
|
||||
a->t -= b->t;
|
||||
a->q -= b->q;
|
||||
}
|
||||
|
||||
static void
|
||||
guard(struct TriAttribs *a)
|
||||
{
|
||||
if(a->z < 0) a->z = 0;
|
||||
else if(a->z > 0x3FFFFFFFC000LL) a->z = 0x3FFFFFFFC000LL;
|
||||
if(a->r < 0) a->r = 0;
|
||||
else if(a->r > 0xFF000) a->r = 0xFF000;
|
||||
if(a->g < 0) a->g = 0;
|
||||
else if(a->g > 0xFF000) a->g = 0xFF000;
|
||||
if(a->b < 0) a->b = 0;
|
||||
else if(a->b > 0xFF000) a->b = 0xFF000;
|
||||
if(a->a < 0) a->a = 0;
|
||||
else if(a->a > 0xFF000) a->a = 0xFF000;
|
||||
if(a->f < 0) a->f = 0;
|
||||
else if(a->f > 0xFF000) a->f = 0xFF000;
|
||||
}
|
||||
|
||||
struct RasTri
|
||||
{
|
||||
int x, y;
|
||||
int ymid, yend;
|
||||
int right;
|
||||
int e[2], dx[3], dy[3];
|
||||
struct TriAttribs gx, gy, v, s;
|
||||
};
|
||||
|
||||
static int
|
||||
triangleSetup(struct RasTri *tri, Vertex v1, Vertex v2, Vertex v3)
|
||||
{
|
||||
int dx1, dx2, dx3;
|
||||
int dy1, dy2, dy3;
|
||||
|
||||
dy1 = v3.y - v1.y; // long edge
|
||||
if(dy1 == 0) return 1;
|
||||
dx1 = v3.x - v1.x;
|
||||
dx2 = v2.x - v1.x; // first small edge
|
||||
dy2 = v2.y - v1.y;
|
||||
dx3 = v3.x - v2.x; // second small edge
|
||||
dy3 = v3.y - v2.y;
|
||||
|
||||
// this is twice the triangle area
|
||||
const int area = dx2*dy1 - dx1*dy2;
|
||||
if(area == 0) return 1;
|
||||
// figure out if 0 or 1 is the right edge
|
||||
tri->right = area < 0;
|
||||
|
||||
/* The gradients are to step whole pixels,
|
||||
* so they are pre-multiplied by 16. */
|
||||
|
||||
float denom = 16.0f/area;
|
||||
// gradients x
|
||||
#define GX(p) ((v2.p - v1.p)*dy1 - (v3.p - v1.p)*dy2)
|
||||
tri->gx.z = GX(z)*denom * 16384;
|
||||
tri->gx.r = GX(r)*denom * 4096;
|
||||
tri->gx.g = GX(g)*denom * 4096;
|
||||
tri->gx.b = GX(b)*denom * 4096;
|
||||
tri->gx.a = GX(a)*denom * 4096;
|
||||
tri->gx.f = GX(f)*denom * 4096;
|
||||
tri->gx.s = GX(s)*denom;
|
||||
tri->gx.t = GX(t)*denom;
|
||||
tri->gx.q = GX(q)*denom;
|
||||
|
||||
// gradients y
|
||||
denom = -denom;
|
||||
#define GY(p) ((v2.p - v1.p)*dx1 - (v3.p - v1.p)*dx2)
|
||||
tri->gy.z = GY(z)*denom * 16384;
|
||||
tri->gy.r = GY(r)*denom * 4096;
|
||||
tri->gy.g = GY(g)*denom * 4096;
|
||||
tri->gy.b = GY(b)*denom * 4096;
|
||||
tri->gy.a = GY(a)*denom * 4096;
|
||||
tri->gy.f = GY(f)*denom * 4096;
|
||||
tri->gy.s = GY(s)*denom;
|
||||
tri->gy.t = GY(t)*denom;
|
||||
tri->gy.q = GY(q)*denom;
|
||||
|
||||
tri->ymid = CEIL(v2.y);
|
||||
tri->yend = CEIL(v3.y);
|
||||
|
||||
tri->y = CEIL(v1.y);
|
||||
tri->x = CEIL(v1.x);
|
||||
|
||||
tri->dy[0] = dy2<<4; // upper edge
|
||||
tri->dy[1] = dy1<<4; // lower edge
|
||||
tri->dy[2] = dy3<<4; // long edge
|
||||
tri->dx[0] = dx2<<4;
|
||||
tri->dx[1] = dx1<<4;
|
||||
tri->dx[2] = dx3<<4;
|
||||
|
||||
// prestep to land on pixel center
|
||||
|
||||
int stepx = v1.x - (tri->x<<4);
|
||||
int stepy = v1.y - (tri->y<<4);
|
||||
tri->e[0] = (-stepy*tri->dx[0] + stepx*tri->dy[0]) >> 4;
|
||||
tri->e[1] = (-stepy*tri->dx[1] + stepx*tri->dy[1]) >> 4;
|
||||
|
||||
// attributes along interpolated edge
|
||||
// why is this cast needed? (mingw)
|
||||
tri->v.z = (i64)v1.z*16384 - (stepy*tri->gy.z + stepx*tri->gx.z)/16;
|
||||
tri->v.r = v1.r*4096 - (stepy*tri->gy.r + stepx*tri->gx.r)/16;
|
||||
tri->v.g = v1.g*4096 - (stepy*tri->gy.g + stepx*tri->gx.g)/16;
|
||||
tri->v.b = v1.b*4096 - (stepy*tri->gy.b + stepx*tri->gx.b)/16;
|
||||
tri->v.a = v1.a*4096 - (stepy*tri->gy.a + stepx*tri->gx.a)/16;
|
||||
tri->v.f = v1.f*4096 - (stepy*tri->gy.f + stepx*tri->gx.f)/16;
|
||||
tri->v.s = v1.s - (stepy*tri->gy.s + stepx*tri->gx.s)/16.0f;
|
||||
tri->v.t = v1.t - (stepy*tri->gy.t + stepx*tri->gx.t)/16.0f;
|
||||
tri->v.q = v1.q - (stepy*tri->gy.q + stepx*tri->gx.q)/16.0f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
drawTriangle(Canvas *canvas, Vertex v1, Vertex v2, Vertex v3)
|
||||
{
|
||||
Color c;
|
||||
struct RasTri tri;
|
||||
int stepx, stepy;
|
||||
|
||||
// Sort such that we have from top to bottom v1,v2,v3
|
||||
if(v2.y < v1.y){ Vertex tmp = v1; v1 = v2; v2 = tmp; }
|
||||
if(v3.y < v1.y){ Vertex tmp = v1; v1 = v3; v3 = tmp; }
|
||||
if(v3.y < v2.y){ Vertex tmp = v2; v2 = v3; v3 = tmp; }
|
||||
|
||||
if(triangleSetup(&tri, v1, v2, v3))
|
||||
return;
|
||||
|
||||
// Current scanline start and end
|
||||
int xn[2] = { tri.x, tri.x };
|
||||
int a = !tri.right; // left edge
|
||||
int b = tri.right; // right edge
|
||||
|
||||
// If upper triangle has no height, only do the lower part
|
||||
if(tri.dy[0] == 0)
|
||||
goto secondtri;
|
||||
while(tri.y < tri.yend){
|
||||
/* TODO: is this the righ way to step the edges? */
|
||||
|
||||
/* Step x and interpolated value down left edge */
|
||||
while(tri.e[a] <= -tri.dy[a]){
|
||||
xn[a]--;
|
||||
tri.e[a] += tri.dy[a];
|
||||
sub1(&tri.v, &tri.gx);
|
||||
}
|
||||
while(tri.e[a] > 0){
|
||||
xn[a]++;
|
||||
tri.e[a] -= tri.dy[a];
|
||||
add1(&tri.v, &tri.gx);
|
||||
}
|
||||
|
||||
/* Step x down right edge */
|
||||
while(tri.e[b] <= -tri.dy[b]){
|
||||
xn[b]--;
|
||||
tri.e[b] += tri.dy[b];
|
||||
}
|
||||
while(tri.e[b] > 0){
|
||||
xn[b]++;
|
||||
tri.e[b] -= tri.dy[b];
|
||||
}
|
||||
|
||||
// When we reach the mid vertex, change state and jump to start of loop again
|
||||
// TODO: this is a bit ugly in here...can we fix it?
|
||||
if(tri.y == tri.ymid){
|
||||
secondtri:
|
||||
tri.dx[0] = tri.dx[2];
|
||||
tri.dy[0] = tri.dy[2];
|
||||
// Either the while prevents this or we returned early because dy1 == 0
|
||||
assert(tri.dy[0] != 0);
|
||||
stepx = v2.x - (xn[0]<<4);
|
||||
stepy = v2.y - (tri.y<<4);
|
||||
tri.e[0] = (-stepy*tri.dx[0] + stepx*tri.dy[0]) >> 4;
|
||||
|
||||
tri.ymid = -1; // so we don't do this again
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Rasterize one line */
|
||||
tri.s = tri.v;
|
||||
for(tri.x = xn[a]; tri.x < xn[b]; tri.x++){
|
||||
guard(&tri.s);
|
||||
c.r = tri.s.r >> 12;
|
||||
c.g = tri.s.g >> 12;
|
||||
c.b = tri.s.b >> 12;
|
||||
c.a = tri.s.a >> 12;
|
||||
if(srTexEnable && srTexture){
|
||||
float w = 1.0f/tri.s.q;
|
||||
float s = tri.s.s * w;
|
||||
float t = tri.s.t * w;
|
||||
int u = s * srTexture->w * 16;
|
||||
int v = t * srTexture->h * 16;
|
||||
Color texc = sampletex_nearest(u, v);
|
||||
c = texfunc(texc, c);
|
||||
}
|
||||
if(srFogEnable){
|
||||
const int f = tri.s.f >> 12;
|
||||
c.r = (f*c.r >> 8) + ((255 - f)*srFogCol.r >> 8);
|
||||
c.g = (f*c.g >> 8) + ((255 - f)*srFogCol.g >> 8);
|
||||
c.b = (f*c.b >> 8) + ((255 - f)*srFogCol.b >> 8);
|
||||
}
|
||||
putpixel(canvas, mkpnt(tri.x, tri.y, tri.s.z>>14), c);
|
||||
add1(&tri.s, &tri.gx);
|
||||
}
|
||||
|
||||
/* Step in y */
|
||||
tri.y++;
|
||||
tri.e[a] += tri.dx[a];
|
||||
tri.e[b] += tri.dx[b];
|
||||
add1(&tri.v, &tri.gy);
|
||||
}
|
||||
}
|
||||
|
||||
Canvas *canvas;
|
||||
|
||||
}
|
||||
|
||||
using namespace rw;
|
||||
|
||||
void
|
||||
rastest_renderTriangles(RWDEVICE::Im2DVertex *scrverts, int32 numVerts, uint16 *indices, int32 numTris)
|
||||
{
|
||||
int i;
|
||||
RGBA col;
|
||||
rs::Vertex v[3];
|
||||
RWDEVICE::Im2DVertex *iv;
|
||||
|
||||
rs::srDepthTestEnable = 1;
|
||||
rs::srAlphaTestEnable = 0;
|
||||
rs::srTexEnable = 0;
|
||||
rs::srAlphaBlendEnable = 0;
|
||||
|
||||
while(numTris--){
|
||||
for(i = 0; i < 3; i++){
|
||||
iv = &scrverts[indices[i]];
|
||||
v[i].x = iv->getScreenX() * 16.0f;
|
||||
v[i].y = iv->getScreenY() * 16.0f;
|
||||
v[i].z = 16777216*(1.0f-iv->getScreenZ());
|
||||
v[i].q = iv->getRecipCameraZ();
|
||||
col = iv->getColor();
|
||||
v[i].r = col.red;
|
||||
v[i].g = col.green;
|
||||
v[i].b = col.blue;
|
||||
v[i].a = col.alpha;
|
||||
v[i].f = 0;
|
||||
v[i].s = iv->u*iv->getRecipCameraZ();
|
||||
v[i].t = iv->v*iv->getRecipCameraZ();
|
||||
}
|
||||
drawTriangle(rs::canvas, v[0], v[1], v[2]);
|
||||
|
||||
indices += 3;
|
||||
}
|
||||
}
|
||||
|
||||
extern rw::Raster *testras;
|
||||
|
||||
void
|
||||
beginSoftras(void)
|
||||
{
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
if(rs::canvas == nil ||
|
||||
cam->frameBuffer->width != rs::canvas->w ||
|
||||
cam->frameBuffer->height != rs::canvas->h){
|
||||
rs::canvas = rs::makecanvas(cam->frameBuffer->width, cam->frameBuffer->height);
|
||||
testras = rw::Raster::create(rs::canvas->w, rs::canvas->h, 32, rw::Raster::C8888);
|
||||
}
|
||||
|
||||
clearcanvas(rs::canvas);
|
||||
rs::srScissorX0 = 0;
|
||||
rs::srScissorX1 = rs::canvas->w-1;
|
||||
rs::srScissorY0 = 0;
|
||||
rs::srScissorY1 = rs::canvas->h-1;
|
||||
}
|
||||
|
||||
void
|
||||
endSoftras(void)
|
||||
{
|
||||
int i;
|
||||
uint8 *dst = testras->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
|
||||
if(dst == nil)
|
||||
return;
|
||||
uint8 *src = rs::canvas->fb;
|
||||
for(i = 0; i < rs::canvas->w*rs::canvas->h; i++){
|
||||
dst[0] = src[1];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[3];
|
||||
dst[3] = src[0];
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
// abgr in canvas
|
||||
// bgra in raster
|
||||
testras->unlock(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
typedef struct PixVert PixVert;
|
||||
struct PixVert
|
||||
{
|
||||
float x, y, z, q;
|
||||
int r, g, b, a;
|
||||
float u, v;
|
||||
};
|
||||
#include "test.inc"
|
||||
|
||||
void
|
||||
drawtest(void)
|
||||
{
|
||||
int i, j;
|
||||
rs::Vertex v[3];
|
||||
|
||||
rs::srDepthTestEnable = 1;
|
||||
rs::srAlphaTestEnable = 0;
|
||||
rs::srTexEnable = 0;
|
||||
rs::srAlphaBlendEnable = 0;
|
||||
|
||||
for(i = 0; i < nelem(verts); i += 3){
|
||||
for(j = 0; j < 3; j++){
|
||||
v[j].x = verts[i+j].x * 16.0f;
|
||||
v[j].y = verts[i+j].y * 16.0f;
|
||||
v[j].z = 16777216*(1.0f - verts[i+j].z);
|
||||
v[j].q = verts[i+j].q;
|
||||
v[j].r = verts[i+j].r;
|
||||
v[j].g = verts[i+j].g;
|
||||
v[j].b = verts[i+j].b;
|
||||
v[j].a = verts[i+j].a;
|
||||
v[j].f = 0;
|
||||
v[j].s = verts[i+j].u*v[j].q;
|
||||
v[j].t = verts[i+j].v*v[j].q;
|
||||
}
|
||||
drawTriangle(rs::canvas, v[0], v[1], v[2]);
|
||||
}
|
||||
//exit(0);
|
||||
}
|
||||
*/
|
||||
520
vendor/librw/tools/playground/splines.cpp
vendored
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace rw;
|
||||
using namespace RWDEVICE;
|
||||
|
||||
static Im3DVertex im3dVerts[1024];
|
||||
static int numImVerts;
|
||||
static rw::PrimitiveType imPrim;
|
||||
static Im3DVertex imVert;
|
||||
|
||||
void
|
||||
BeginIm3D(rw::PrimitiveType prim)
|
||||
{
|
||||
numImVerts = 0;
|
||||
imPrim = prim;
|
||||
}
|
||||
|
||||
void
|
||||
EndIm3D(void)
|
||||
{
|
||||
rw::im3d::Transform(im3dVerts, numImVerts, nil, rw::im3d::EVERYTHING);
|
||||
rw::im3d::RenderPrimitive(imPrim);
|
||||
rw::im3d::End();
|
||||
}
|
||||
|
||||
void
|
||||
AddVertex(const rw::V3d &vert)
|
||||
{
|
||||
if(numImVerts >= 1024){
|
||||
EndIm3D();
|
||||
switch(imPrim){
|
||||
case PRIMTYPEPOLYLINE:
|
||||
im3dVerts[0] = im3dVerts[numImVerts-1];
|
||||
numImVerts = 1;
|
||||
break;
|
||||
case PRIMTYPETRISTRIP:
|
||||
// TODO: winding?
|
||||
im3dVerts[0] = im3dVerts[numImVerts-2];
|
||||
im3dVerts[1] = im3dVerts[numImVerts-1];
|
||||
numImVerts = 2;
|
||||
break;
|
||||
case PRIMTYPETRIFAN:
|
||||
im3dVerts[1] = im3dVerts[numImVerts-1];
|
||||
numImVerts = 2;
|
||||
break;
|
||||
default:
|
||||
numImVerts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
imVert.setX(vert.x);
|
||||
imVert.setY(vert.y);
|
||||
imVert.setZ(vert.z);
|
||||
im3dVerts[numImVerts++] = imVert;
|
||||
}
|
||||
|
||||
float epsilon = 0.000001;
|
||||
|
||||
class RBCurve
|
||||
{
|
||||
public:
|
||||
int degree;
|
||||
std::vector<V3d> verts;
|
||||
std::vector<float> weights; // for rational
|
||||
std::vector<float> knots;
|
||||
|
||||
V3d eval(float u);
|
||||
void drawHull(void);
|
||||
void drawSpline(void);
|
||||
};
|
||||
|
||||
class RBSurf
|
||||
{
|
||||
public:
|
||||
int degreeU, degreeV;
|
||||
int numU, numV;
|
||||
std::vector<V3d> verts;
|
||||
std::vector<float> weights;
|
||||
std::vector<float> knotsU, knotsV;
|
||||
|
||||
void update(void);
|
||||
V3d eval(float u, float v);
|
||||
void drawHull(void);
|
||||
void drawIsoparms(void);
|
||||
void drawShaded(void);
|
||||
};
|
||||
|
||||
float div0(float a, float b) { return b == 0.0f ? a : a/b; }
|
||||
|
||||
// naive algorithm
|
||||
float
|
||||
evalBasis(int i, int d, float u, float knots[])
|
||||
{
|
||||
if(d == 0){
|
||||
if(knots[i] <= u && u < knots[i+1])
|
||||
return 1.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float b0 = evalBasis(i, d-1, u, knots);
|
||||
float b1 = evalBasis(i+1, d-1, u, knots);
|
||||
return b0*div0(u-knots[i], knots[i+d] - knots[i]) + b1*div0(knots[i+d+1]-u, knots[i+d+1] - knots[i+1]);
|
||||
}
|
||||
|
||||
float
|
||||
evalBasisFast(int i, int d, float u, float knots[])
|
||||
{
|
||||
int r, j;
|
||||
float tmp[10];
|
||||
|
||||
// degree 0 values
|
||||
for(j = 0; j < d+1; j++)
|
||||
tmp[j] = knots[i+j] <= u && u < knots[i+j+1] ? 1.0f : 0.0f;
|
||||
|
||||
// build up from degree zero
|
||||
for(r = d, d = 1; r > 0; r--, d++){
|
||||
for(j = 0; j < r; j++){
|
||||
float t1 = div0(u-knots[i+j], knots[i+j + d] - knots[i+j]);
|
||||
float t2 = div0(knots[i+j + d+1]-u, knots[i+j + d+1] - knots[i+j + 1]);
|
||||
tmp[j] = tmp[j]*t1 + tmp[j+1]*t2;
|
||||
}
|
||||
}
|
||||
return tmp[0];
|
||||
}
|
||||
|
||||
V3d
|
||||
RBCurve::eval(float u)
|
||||
{
|
||||
int i;
|
||||
V3d vert = { 0.0f, 0.0f, 0.0f };
|
||||
float w = 0.0f;
|
||||
|
||||
// Find knots we're interested in
|
||||
for(i = 0; i < knots.size(); i++)
|
||||
if(knots[i] <= u && u < knots[i+1])
|
||||
break;
|
||||
int startI = i-degree;
|
||||
int endI = i+1;
|
||||
|
||||
for(i = startI; i < endI; i++){
|
||||
float r = evalBasisFast(i, degree, u, &knots[0]);
|
||||
w += weights[i]*r;
|
||||
vert = add(vert, scale(verts[i], weights[i]*r));
|
||||
}
|
||||
return scale(vert, div0(1.0f,w));
|
||||
}
|
||||
|
||||
void
|
||||
RBCurve::drawHull(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::FOGENABLE, 0);
|
||||
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
imVert.setU(0.0f);
|
||||
imVert.setV(0.0f);
|
||||
imVert.setColor(138, 72, 51, 255);
|
||||
// imVert.setColor(228, 172, 121, 255);
|
||||
for(i = 0; i < verts.size(); i++)
|
||||
AddVertex(verts[i]);
|
||||
EndIm3D();
|
||||
}
|
||||
|
||||
void
|
||||
RBCurve::drawSpline(void)
|
||||
{
|
||||
int i;
|
||||
float u, endu;
|
||||
V3d vert;
|
||||
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::FOGENABLE, 0);
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
imVert.setU(0.0f);
|
||||
imVert.setV(0.0f);
|
||||
imVert.setColor(0, 4, 96, 255);
|
||||
|
||||
u = knots[0];
|
||||
endu = knots[knots.size()-1] - epsilon;
|
||||
float uinc = (endu-knots[0])/40.0f;
|
||||
for(;; u += uinc){
|
||||
if(u > endu)
|
||||
u = endu;
|
||||
AddVertex(eval(u));
|
||||
if(u >= endu)
|
||||
break;
|
||||
}
|
||||
|
||||
EndIm3D();
|
||||
}
|
||||
|
||||
void
|
||||
RBSurf::update(void)
|
||||
{
|
||||
numU = knotsU.size() - degreeU - 1;
|
||||
numV = knotsV.size() - degreeV - 1;
|
||||
}
|
||||
|
||||
V3d
|
||||
RBSurf::eval(float u, float v)
|
||||
{
|
||||
int i, j;
|
||||
V3d vert = { 0.0f, 0.0f, 0.0f };
|
||||
float w = 0.0f;
|
||||
|
||||
float basisU[10], basisV[10];
|
||||
|
||||
// Find knots we're interested in
|
||||
int k;
|
||||
for(k = 0; k < knotsU.size(); k++)
|
||||
if(knotsU[k] <= u && u < knotsU[k+1])
|
||||
break;
|
||||
int startI = k-degreeU;
|
||||
int endI = k+1;
|
||||
for(k = 0; k < knotsV.size(); k++)
|
||||
if(knotsV[k] <= v && v < knotsV[k+1])
|
||||
break;
|
||||
int startJ = k-degreeV;
|
||||
int endJ = k+1;
|
||||
|
||||
for(i = startI; i < endI; i++) basisU[i-startI] = evalBasisFast(i, degreeU, u, &knotsU[0]);
|
||||
for(j = startJ; j < endJ; j++) basisV[j-startJ] = evalBasisFast(j, degreeV, v, &knotsV[0]);
|
||||
|
||||
for(j = startJ; j < endJ; j++)
|
||||
for(i = startI; i < endI; i++){
|
||||
float r = basisV[j-startJ]*basisU[i-startI];
|
||||
w += weights[j*numU + i]*r;
|
||||
vert = add(vert, scale(verts[j*numU + i], weights[j*numU + i]*r));
|
||||
}
|
||||
return scale(vert, div0(1.0f,w));
|
||||
}
|
||||
|
||||
void
|
||||
RBSurf::drawHull(void)
|
||||
{
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::FOGENABLE, 0);
|
||||
|
||||
imVert.setU(0.0f);
|
||||
imVert.setV(0.0f);
|
||||
imVert.setColor(138, 72, 51, 255);
|
||||
// imVert.setColor(228, 172, 121, 255);
|
||||
|
||||
int iu, iv;
|
||||
for(iv = 0; iv < numV; iv++){
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
for(iu = 0; iu < numU; iu++)
|
||||
AddVertex(verts[iu + iv*numU]);
|
||||
EndIm3D();
|
||||
}
|
||||
|
||||
for(iu = 0; iu < numU; iu++){
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
for(iv = 0; iv < numV; iv++)
|
||||
AddVertex(verts[iu + iv*numU]);
|
||||
EndIm3D();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RBSurf::drawIsoparms(void)
|
||||
{
|
||||
V3d vert;
|
||||
int iu, iv;
|
||||
float u, v;
|
||||
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::FOGENABLE, 0);
|
||||
|
||||
imVert.setU(0.0f);
|
||||
imVert.setV(0.0f);
|
||||
imVert.setColor(0, 4, 96, 255);
|
||||
|
||||
float endu = knotsU[knotsU.size()-1] - epsilon;
|
||||
float endv = knotsU[knotsV.size()-1] - epsilon;
|
||||
float uinc = (endu-knotsU[0])/40.0f;
|
||||
float vinc = (endv-knotsV[0])/40.0f;
|
||||
|
||||
v = -100000.0f;
|
||||
for(iv = 0; iv < knotsV.size(); iv++){
|
||||
if(knotsV[iv] <= v) continue;
|
||||
v = knotsV[iv];
|
||||
if(v > endv) v = endv;
|
||||
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
for(u = knotsU[0];; u += uinc){
|
||||
if(u > endu)
|
||||
u = endu;
|
||||
AddVertex(eval(u, v));
|
||||
if(u >= endu)
|
||||
break;
|
||||
}
|
||||
EndIm3D();
|
||||
}
|
||||
|
||||
u = -100000.0f;
|
||||
for(iu = 0; iu < knotsU.size(); iu++){
|
||||
if(knotsU[iu] <= u) continue;
|
||||
u = knotsU[iu];
|
||||
if(u > endu) u = endu;
|
||||
|
||||
BeginIm3D(rw::PRIMTYPEPOLYLINE);
|
||||
for(v = knotsV[0];; v += vinc){
|
||||
if(v > endv)
|
||||
v = endv;
|
||||
AddVertex(eval(u, v));
|
||||
if(v >= endv)
|
||||
break;
|
||||
}
|
||||
EndIm3D();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RBSurf::drawShaded(void)
|
||||
{
|
||||
V3d vert;
|
||||
int iu, iv;
|
||||
float u, v;
|
||||
|
||||
rw::SetRenderState(rw::TEXTURERASTER, nil);
|
||||
rw::SetRenderState(rw::FOGENABLE, 0);
|
||||
|
||||
imVert.setU(0.0f);
|
||||
imVert.setV(0.0f);
|
||||
imVert.setColor(0, 128, 240, 255);
|
||||
|
||||
float endu = knotsU[knotsU.size()-1] - epsilon;
|
||||
float endv = knotsU[knotsV.size()-1] - epsilon;
|
||||
float uinc = (endu-knotsU[0])/40.0f;
|
||||
float vinc = (endv-knotsV[0])/40.0f;
|
||||
|
||||
float vnext;
|
||||
for(v = knotsV[0];; v = vnext){
|
||||
if(v > endv)
|
||||
v = endv;
|
||||
vnext = v + vinc;
|
||||
|
||||
BeginIm3D(rw::PRIMTYPETRISTRIP);
|
||||
for(u = knotsU[0];; u += uinc){
|
||||
if(u > endu)
|
||||
u = endu;
|
||||
|
||||
AddVertex(eval(u, v));
|
||||
AddVertex(eval(u, vnext));
|
||||
|
||||
if(u >= endu)
|
||||
break;
|
||||
}
|
||||
EndIm3D();
|
||||
if(vnext >= endv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RBCurve testspline1, testspline2;
|
||||
RBSurf testsurf;
|
||||
|
||||
void
|
||||
initsplines(void)
|
||||
{
|
||||
V3d vert;
|
||||
|
||||
testspline1.degree = 3;
|
||||
testspline1.verts.clear();
|
||||
testspline1.weights.clear();
|
||||
vert.set(-30.63383, 22.65459, 0);
|
||||
vert = scale(vert, 1.0f/20.0f);
|
||||
testspline1.verts.push_back(vert);
|
||||
testspline1.weights.push_back(1.0f);
|
||||
vert.set(13.50783, 33.01786, 15.06403);
|
||||
vert = scale(vert, 1.0f/20.0f);
|
||||
testspline1.verts.push_back(vert);
|
||||
testspline1.weights.push_back(1.0f);
|
||||
vert.set(34.252, -10.36327, 15.06403);
|
||||
vert = scale(vert, 1.0f/20.0f);
|
||||
testspline1.verts.push_back(vert);
|
||||
testspline1.weights.push_back(1.0f);
|
||||
vert.set(-7.959972, -1.205032, 0);
|
||||
vert = scale(vert, 1.0f/20.0f);
|
||||
testspline1.verts.push_back(vert);
|
||||
testspline1.weights.push_back(1.0f);
|
||||
vert.set(6.995127, -41.32158, -18.19684);
|
||||
vert = scale(vert, 1.0f/20.0f);
|
||||
testspline1.verts.push_back(vert);
|
||||
testspline1.weights.push_back(1.0f);
|
||||
|
||||
testspline1.knots.clear();
|
||||
testspline1.knots.push_back(0);
|
||||
testspline1.knots.push_back(0);
|
||||
testspline1.knots.push_back(0);
|
||||
testspline1.knots.push_back(0);
|
||||
testspline1.knots.push_back(1);
|
||||
testspline1.knots.push_back(2);
|
||||
testspline1.knots.push_back(2);
|
||||
testspline1.knots.push_back(2);
|
||||
testspline1.knots.push_back(2);
|
||||
|
||||
|
||||
testspline2.degree = 2;
|
||||
testspline2.verts.clear();
|
||||
#define V(x, y, z) \
|
||||
vert.set(x, y, z); \
|
||||
testspline2.verts.push_back(scale(vert, 1.0f/20.0f)); \
|
||||
testspline2.weights.push_back(1.0f);
|
||||
V(-61.9913, 9.158239, 0);
|
||||
V(-32.32231, 27.23371, 0);
|
||||
V(25.80961, -4.820126, 0);
|
||||
testspline2.knots.clear();
|
||||
testspline2.knots.push_back(0);
|
||||
testspline2.knots.push_back(0);
|
||||
testspline2.knots.push_back(0);
|
||||
testspline2.knots.push_back(1);
|
||||
testspline2.knots.push_back(1);
|
||||
testspline2.knots.push_back(1);
|
||||
|
||||
/*
|
||||
testspline2 = testspline1;
|
||||
// testspline2.knots.clear();
|
||||
// testspline2.knots.push_back(0);
|
||||
// testspline2.knots.push_back(0);
|
||||
// testspline2.knots.push_back(0);
|
||||
// testspline2.knots.push_back(0);
|
||||
// testspline2.knots.push_back(3);
|
||||
// testspline2.knots.push_back(4);
|
||||
// testspline2.knots.push_back(4);
|
||||
// testspline2.knots.push_back(4);
|
||||
// testspline2.knots.push_back(4);
|
||||
testspline1.weights[2] = 5.0f;
|
||||
*/
|
||||
|
||||
#define V(x, y, z) \
|
||||
vert.set(x, y, z); \
|
||||
testsurf.verts.push_back(scale(vert, 1.0f/20.0f)); \
|
||||
testsurf.weights.push_back(1.0f);
|
||||
|
||||
testsurf.degreeU = 3;
|
||||
testsurf.degreeV = 3;
|
||||
testsurf.verts.clear();
|
||||
testsurf.weights.clear();
|
||||
V(-69.22764, -0, 12.77366);
|
||||
V(-48.72468, 0, 29.16251);
|
||||
V(-24.84476, 0, 39.52605);
|
||||
V(22.43265, -0, 45.79238);
|
||||
V(36.4229, 0, 28.9215);
|
||||
V(61.02645, 0, 6.74835);
|
||||
V(86.35364, -0, 20.96809);
|
||||
V(-69.22764, 9.286676, 12.77366);
|
||||
V(-48.72468, 9.286676, 29.16251);
|
||||
V(-24.84476, 9.286676, 39.52605);
|
||||
V(22.43265, 9.286676, 45.79238);
|
||||
V(36.4229, 9.286676, 28.9215);
|
||||
V(61.02645, 9.286676, 6.74835);
|
||||
V(86.35364, 9.286676, 20.96809);
|
||||
V(-68.13416, 23.51821, 6.114491);
|
||||
V(-48.19925, 23.51821, 22.27994);
|
||||
V(-26.91943, 23.51821, 33.20763);
|
||||
V(18.69658, 23.51821, 39.0488);
|
||||
V(27.88844, 23.51821, 30.80604);
|
||||
V(57.49908, 23.51821, -0.6488895);
|
||||
V(86.35364, 23.51821, 14.21974);
|
||||
V(-67.00163, 52.46369, -0.7825046);
|
||||
V(-47.65504, 52.46369, 15.15157);
|
||||
V(-29.06818, 52.46369, 26.66356);
|
||||
V(14.82709, 52.46369, 32.06438);
|
||||
V(19.04919, 52.46369, 32.75788);
|
||||
V(53.84574, 52.46369, -8.310311);
|
||||
V(86.35364, 52.46369, 7.230374);
|
||||
V(-67.86079, 70.07219, 4.449699);
|
||||
V(-48.06789, 70.07219, 20.5593);
|
||||
V(-27.43809, 70.07219, 31.62803);
|
||||
V(17.76257, 70.07219, 37.36291);
|
||||
V(25.75483, 70.07219, 31.27717);
|
||||
V(56.61724, 70.07219, -2.498198);
|
||||
V(86.35364, 70.07219, 12.53265);
|
||||
testsurf.knotsU.clear();
|
||||
testsurf.knotsU.push_back(0);
|
||||
testsurf.knotsU.push_back(0);
|
||||
testsurf.knotsU.push_back(0);
|
||||
testsurf.knotsU.push_back(0);
|
||||
testsurf.knotsU.push_back(0.25);
|
||||
testsurf.knotsU.push_back(0.5);
|
||||
testsurf.knotsU.push_back(0.75);
|
||||
testsurf.knotsU.push_back(1);
|
||||
testsurf.knotsU.push_back(1);
|
||||
testsurf.knotsU.push_back(1);
|
||||
testsurf.knotsU.push_back(1);
|
||||
testsurf.knotsV.clear();
|
||||
testsurf.knotsV.push_back(0);
|
||||
testsurf.knotsV.push_back(0);
|
||||
testsurf.knotsV.push_back(0);
|
||||
testsurf.knotsV.push_back(0);
|
||||
testsurf.knotsV.push_back(0.5);
|
||||
testsurf.knotsV.push_back(1);
|
||||
testsurf.knotsV.push_back(1);
|
||||
testsurf.knotsV.push_back(1);
|
||||
testsurf.knotsV.push_back(1);
|
||||
|
||||
testsurf.update();
|
||||
}
|
||||
|
||||
void
|
||||
rendersplines(void)
|
||||
{
|
||||
testspline1.drawHull();
|
||||
testspline1.drawSpline();
|
||||
|
||||
// testspline2.drawHull();
|
||||
// testspline2.drawSpline();
|
||||
|
||||
testsurf.drawHull();
|
||||
testsurf.drawShaded();
|
||||
testsurf.drawIsoparms();
|
||||
}
|
||||
766
vendor/librw/tools/playground/tl_tests.cpp
vendored
Normal file
|
|
@ -0,0 +1,766 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
extern bool dosoftras;
|
||||
|
||||
using namespace rw;
|
||||
using namespace RWDEVICE;
|
||||
|
||||
void rastest_renderTriangles(RWDEVICE::Im2DVertex *scrverts, int32 verts, uint16 *indices, int32 numTris);
|
||||
|
||||
//
|
||||
// This is a test to implement T&L in software and render with Im2D
|
||||
//
|
||||
|
||||
namespace gen {
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
struct Directional {
|
||||
V3d at;
|
||||
RGBAf color;
|
||||
};
|
||||
static Directional directionals[MAX_LIGHTS];
|
||||
static int32 numDirectionals;
|
||||
static RGBAf ambLight;
|
||||
|
||||
static void
|
||||
enumLights(Matrix *lightmat)
|
||||
{
|
||||
int32 n;
|
||||
World *world;
|
||||
|
||||
world = (World*)engine->currentWorld;
|
||||
ambLight.red = 0.0;
|
||||
ambLight.green = 0.0;
|
||||
ambLight.blue = 0.0;
|
||||
ambLight.alpha = 0.0;
|
||||
numDirectionals = 0;
|
||||
// only unpositioned lights right now
|
||||
FORLIST(lnk, world->globalLights){
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
if(l->getType() == Light::DIRECTIONAL){
|
||||
if(numDirectionals >= MAX_LIGHTS)
|
||||
continue;
|
||||
n = numDirectionals++;
|
||||
V3d::transformVectors(&directionals[n].at, &l->getFrame()->getLTM()->at, 1, lightmat);
|
||||
directionals[n].color = l->color;
|
||||
directionals[n].color.alpha = 0.0f;
|
||||
}else if(l->getType() == Light::AMBIENT){
|
||||
ambLight.red += l->color.red;
|
||||
ambLight.green += l->color.green;
|
||||
ambLight.blue += l->color.blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ObjSpace3DVertex
|
||||
{
|
||||
V3d objVertex;
|
||||
V3d objNormal;
|
||||
RGBA color;
|
||||
TexCoords texCoords;
|
||||
};
|
||||
|
||||
enum {
|
||||
CLIPXLO = 0x01,
|
||||
CLIPXHI = 0x02,
|
||||
CLIPX = 0x03,
|
||||
CLIPYLO = 0x04,
|
||||
CLIPYHI = 0x08,
|
||||
CLIPY = 0x0C,
|
||||
CLIPZLO = 0x10,
|
||||
CLIPZHI = 0x20,
|
||||
CLIPZ = 0x30,
|
||||
};
|
||||
|
||||
struct CamSpace3DVertex
|
||||
{
|
||||
V3d camVertex;
|
||||
uint8 clipFlags;
|
||||
RGBAf color;
|
||||
TexCoords texCoords;
|
||||
};
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
uint16 *indices;
|
||||
int32 numIndices;
|
||||
ObjSpace3DVertex *vertices;
|
||||
int32 numVertices;
|
||||
// int vertStride; // not really needed right now
|
||||
Material *material;
|
||||
Mesh *mesh;
|
||||
};
|
||||
|
||||
struct InstanceDataHeader : public rw::InstanceDataHeader
|
||||
{
|
||||
uint32 serialNumber;
|
||||
ObjSpace3DVertex *vertices;
|
||||
uint16 *indices;
|
||||
InstanceData *inst;
|
||||
};
|
||||
|
||||
static void
|
||||
instanceAtomic(Atomic *atomic)
|
||||
{
|
||||
static V3d zeroNorm = { 0.0f, 0.0f, 0.0f };
|
||||
static RGBA black = { 0, 0, 0, 255 };
|
||||
static TexCoords zeroTex = { 0.0f, 0.0f };
|
||||
int i;
|
||||
uint j;
|
||||
int x, x1, x2, x3;
|
||||
Geometry *geo;
|
||||
MeshHeader *header;
|
||||
Mesh *mesh;
|
||||
InstanceDataHeader *insthead;
|
||||
InstanceData *inst;
|
||||
uint32 firstVert;
|
||||
uint16 *srcindices, *dstindices;
|
||||
|
||||
geo = atomic->geometry;
|
||||
if(geo->instData)
|
||||
return;
|
||||
header = geo->meshHeader;
|
||||
int numTris;
|
||||
if(header->flags & MeshHeader::TRISTRIP)
|
||||
numTris = header->totalIndices - 2*header->numMeshes;
|
||||
else
|
||||
numTris = header->totalIndices / 3;
|
||||
int size;
|
||||
size = sizeof(InstanceDataHeader) + header->numMeshes*sizeof(InstanceData) +
|
||||
geo->numVertices*sizeof(ObjSpace3DVertex) + numTris*6*sizeof(uint16);
|
||||
insthead = (InstanceDataHeader*)rwNew(size, ID_GEOMETRY);
|
||||
geo->instData = insthead;
|
||||
insthead->platform = 0;
|
||||
insthead->serialNumber = header->serialNum;
|
||||
inst = (InstanceData*)(insthead+1);
|
||||
insthead->inst = inst;
|
||||
insthead->vertices = (ObjSpace3DVertex*)(inst+header->numMeshes);
|
||||
dstindices = (uint16*)(insthead->vertices+geo->numVertices);
|
||||
insthead->indices = dstindices;
|
||||
|
||||
// TODO: morphing
|
||||
MorphTarget *mt = geo->morphTargets;
|
||||
for(i = 0; i < geo->numVertices; i++){
|
||||
insthead->vertices[i].objVertex = mt->vertices[i];
|
||||
if(geo->flags & Geometry::NORMALS)
|
||||
insthead->vertices[i].objNormal = mt->normals[i];
|
||||
else
|
||||
insthead->vertices[i].objNormal = zeroNorm;
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
insthead->vertices[i].color = geo->colors[i];
|
||||
else
|
||||
insthead->vertices[i].color = black;
|
||||
if(geo->numTexCoordSets > 0)
|
||||
insthead->vertices[i].texCoords = geo->texCoords[0][i];
|
||||
else
|
||||
insthead->vertices[i].texCoords = zeroTex;
|
||||
}
|
||||
|
||||
mesh = header->getMeshes();
|
||||
for(i = 0; i < header->numMeshes; i++){
|
||||
findMinVertAndNumVertices(mesh->indices, mesh->numIndices,
|
||||
&firstVert, &inst->numVertices);
|
||||
inst->indices = dstindices;
|
||||
inst->vertices = &insthead->vertices[firstVert];
|
||||
inst->mesh = mesh;
|
||||
inst->material = mesh->material;
|
||||
srcindices = mesh->indices;
|
||||
if(header->flags & MeshHeader::TRISTRIP){
|
||||
inst->numIndices = 0;
|
||||
x = 0;
|
||||
for(j = 0; j < mesh->numIndices-2; j++){
|
||||
x1 = srcindices[j+x];
|
||||
x ^= 1;
|
||||
x2 = srcindices[j+x];
|
||||
x3 = srcindices[j+2];
|
||||
if(x1 != x2 && x2 != x3 && x1 != x3){
|
||||
dstindices[0] = x1;
|
||||
dstindices[1] = x2;
|
||||
dstindices[2] = x3;
|
||||
dstindices += 3;
|
||||
inst->numIndices += 3;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
inst->numIndices = mesh->numIndices;
|
||||
for(j = 0; j < mesh->numIndices; j += 3){
|
||||
dstindices[0] = srcindices[j+0] - firstVert;
|
||||
dstindices[1] = srcindices[j+1] - firstVert;
|
||||
dstindices[2] = srcindices[j+2] - firstVert;
|
||||
dstindices += 3;
|
||||
}
|
||||
}
|
||||
|
||||
inst++;
|
||||
mesh++;
|
||||
}
|
||||
}
|
||||
|
||||
struct MeshState
|
||||
{
|
||||
int32 flags;
|
||||
Matrix obj2cam;
|
||||
Matrix obj2world;
|
||||
int32 numVertices;
|
||||
int32 numPrimitives;
|
||||
SurfaceProperties surfProps;
|
||||
RGBA matCol;
|
||||
};
|
||||
|
||||
static void
|
||||
cam2screen(Im2DVertex *scrvert, CamSpace3DVertex *camvert)
|
||||
{
|
||||
RGBA col;
|
||||
float32 recipZ;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
recipZ = 1.0f/camvert->camVertex.z;
|
||||
|
||||
// scrvert->setScreenX(camvert->camVertex.x * recipZ * width);
|
||||
// scrvert->setScreenY(camvert->camVertex.y * recipZ * height);
|
||||
scrvert->setScreenX(camvert->camVertex.x * recipZ * width/2 + width/4);
|
||||
scrvert->setScreenY(camvert->camVertex.y * recipZ * height/2 + height/4);
|
||||
scrvert->setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
scrvert->setCameraZ(camvert->camVertex.z);
|
||||
scrvert->setRecipCameraZ(recipZ);
|
||||
scrvert->setU(camvert->texCoords.u, recipZ);
|
||||
scrvert->setV(camvert->texCoords.v, recipZ);
|
||||
convColor(&col, &camvert->color);
|
||||
scrvert->setColor(col.red, col.green, col.blue, col.alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
transform(MeshState *mstate, ObjSpace3DVertex *objverts, CamSpace3DVertex *camverts, Im2DVertex *scrverts)
|
||||
{
|
||||
int32 i;
|
||||
float32 z;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
V3d::transformPoints(&camverts[i].camVertex, &objverts[i].objVertex, 1, &mstate->obj2cam);
|
||||
convColor(&camverts[i].color, &objverts[i].color);
|
||||
camverts[i].texCoords = objverts[i].texCoords;
|
||||
|
||||
camverts[i].clipFlags = 0;
|
||||
z = camverts[i].camVertex.z;
|
||||
// 0 < x < z
|
||||
if(camverts[i].camVertex.x >= z) camverts[i].clipFlags |= CLIPXHI;
|
||||
if(camverts[i].camVertex.x <= 0) camverts[i].clipFlags |= CLIPXLO;
|
||||
// 0 < y < z
|
||||
if(camverts[i].camVertex.y >= z) camverts[i].clipFlags |= CLIPYHI;
|
||||
if(camverts[i].camVertex.y <= 0) camverts[i].clipFlags |= CLIPYLO;
|
||||
// near < z < far
|
||||
if(z >= cam->farPlane) camverts[i].clipFlags |= CLIPZHI;
|
||||
if(z <= cam->nearPlane) camverts[i].clipFlags |= CLIPZLO;
|
||||
|
||||
cam2screen(&scrverts[i], &camverts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
light(MeshState *mstate, ObjSpace3DVertex *objverts, CamSpace3DVertex *camverts)
|
||||
{
|
||||
int32 i;
|
||||
RGBAf colf;
|
||||
RGBAf amb = ambLight;
|
||||
amb = scale(ambLight, mstate->surfProps.ambient);
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
camverts[i].color = add(camverts[i].color, amb);
|
||||
if((mstate->flags & Geometry::NORMALS) == 0)
|
||||
continue;
|
||||
for(int32 k = 0; k < numDirectionals; k++){
|
||||
float32 f = dot(objverts[i].objNormal, neg(directionals[k].at));
|
||||
if(f <= 0.0f) continue;
|
||||
f *= mstate->surfProps.diffuse;
|
||||
colf = scale(directionals[k].color, f);
|
||||
camverts[i].color = add(camverts[i].color, colf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
postlight(MeshState *mstate, CamSpace3DVertex *camverts, Im2DVertex *scrverts)
|
||||
{
|
||||
int32 i;
|
||||
RGBA col;
|
||||
RGBAf colf;
|
||||
for(i = 0; i < mstate->numVertices; i++){
|
||||
convColor(&colf, &mstate->matCol);
|
||||
camverts[i].color = modulate(camverts[i].color, colf);
|
||||
clamp(&camverts[i].color);
|
||||
convColor(&col, &camverts[i].color);
|
||||
scrverts[i].setColor(col.red, col.green, col.blue, col.alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static int32
|
||||
cullTriangles(MeshState *mstate, CamSpace3DVertex *camverts, uint16 *indices, uint16 *clipindices)
|
||||
{
|
||||
int32 i;
|
||||
int32 x1, x2, x3;
|
||||
int32 newNumPrims;
|
||||
int32 numClip;
|
||||
|
||||
newNumPrims = 0;
|
||||
numClip = 0;
|
||||
for(i = 0; i < mstate->numPrimitives; i++, indices += 3){
|
||||
x1 = indices[0];
|
||||
x2 = indices[1];
|
||||
x3 = indices[2];
|
||||
// Only a simple frustum call
|
||||
if(camverts[x1].clipFlags &
|
||||
camverts[x2].clipFlags &
|
||||
camverts[x3].clipFlags)
|
||||
continue;
|
||||
if(camverts[x1].clipFlags |
|
||||
camverts[x2].clipFlags |
|
||||
camverts[x3].clipFlags)
|
||||
numClip++;
|
||||
// The Triangle is in, probably
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2;
|
||||
clipindices[2] = x3;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
}
|
||||
mstate->numPrimitives = newNumPrims;
|
||||
return numClip;
|
||||
}
|
||||
|
||||
static void
|
||||
interpVertex(CamSpace3DVertex *out, CamSpace3DVertex *v1, CamSpace3DVertex *v2, float32 t)
|
||||
{
|
||||
float32 z;
|
||||
float32 invt;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
invt = 1.0f - t;
|
||||
out->camVertex = add(scale(v1->camVertex, invt), scale(v2->camVertex, t));
|
||||
out->color = add(scale(v1->color, invt), scale(v2->color, t));
|
||||
out->texCoords.u = v1->texCoords.u*invt + v2->texCoords.u*t;
|
||||
out->texCoords.v = v1->texCoords.v*invt + v2->texCoords.v*t;
|
||||
|
||||
out->clipFlags = 0;
|
||||
z = out->camVertex.z;
|
||||
// 0 < x < z
|
||||
if(out->camVertex.x >= z) out->clipFlags |= CLIPXHI;
|
||||
if(out->camVertex.x <= 0) out->clipFlags |= CLIPXLO;
|
||||
// 0 < y < z
|
||||
if(out->camVertex.y >= z) out->clipFlags |= CLIPYHI;
|
||||
if(out->camVertex.y <= 0) out->clipFlags |= CLIPYLO;
|
||||
// near < z < far
|
||||
if(z >= cam->farPlane) out->clipFlags |= CLIPZHI;
|
||||
if(z <= cam->nearPlane) out->clipFlags |= CLIPZLO;
|
||||
}
|
||||
|
||||
static void
|
||||
clipTriangles(MeshState *mstate, CamSpace3DVertex *camverts, Im2DVertex *scrverts, uint16 *indices, uint16 *clipindices)
|
||||
{
|
||||
int32 i, j;
|
||||
int32 x1, x2, x3;
|
||||
int32 newNumPrims;
|
||||
CamSpace3DVertex buf[18];
|
||||
CamSpace3DVertex *in, *out, *tmp;
|
||||
int32 nin, nout;
|
||||
float32 t;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
newNumPrims = 0;
|
||||
for(i = 0; i < mstate->numPrimitives; i++, indices += 3){
|
||||
x1 = indices[0];
|
||||
x2 = indices[1];
|
||||
x3 = indices[2];
|
||||
|
||||
if((camverts[x1].clipFlags |
|
||||
camverts[x2].clipFlags |
|
||||
camverts[x3].clipFlags) == 0){
|
||||
// all inside
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2;
|
||||
clipindices[2] = x3;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// set up triangle
|
||||
in = &buf[0];
|
||||
out = &buf[9];
|
||||
in[0] = camverts[x1];
|
||||
in[1] = camverts[x2];
|
||||
in[2] = camverts[x3];
|
||||
nin = 3;
|
||||
nout = 0;
|
||||
|
||||
#define V(a) in[a].camVertex.
|
||||
|
||||
// clip z near
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPZLO){
|
||||
t = (cam->nearPlane - V(x1)z)/(V(x2)z - V(x1)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPZLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip z far
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPZHI){
|
||||
t = (cam->farPlane - V(x1)z)/(V(x2)z - V(x1)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPZHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip y 0
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPYLO){
|
||||
t = -V(x1)y/(V(x2)y - V(x1)y);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPYLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip y z
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPYHI){
|
||||
t = (V(x1)z - V(x1)y)/(V(x1)z - V(x1)y + V(x2)y - V(x2)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPYHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip x 0
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPXLO){
|
||||
t = -V(x1)x/(V(x2)x - V(x1)x);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPXLO) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
// clip x z
|
||||
nin = nout; nout = 0;
|
||||
tmp = in; in = out; out = tmp;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
if((in[x1].clipFlags ^ in[x2].clipFlags) & CLIPXHI){
|
||||
t = (V(x1)z - V(x1)x)/(V(x1)z - V(x1)x + V(x2)x - V(x2)z);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if((in[x2].clipFlags & CLIPXHI) == 0)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
|
||||
// Insert new triangles
|
||||
x1 = mstate->numVertices;
|
||||
for(j = 0; j < nout; j++){
|
||||
x2 = mstate->numVertices++;
|
||||
camverts[x2] = out[j];
|
||||
cam2screen(&scrverts[x2], &camverts[x2]);
|
||||
}
|
||||
x2 = x1+1;
|
||||
for(j = 0; j < nout-2; j++){
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2++;
|
||||
clipindices[2] = x2;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
}
|
||||
}
|
||||
mstate->numPrimitives = newNumPrims;
|
||||
}
|
||||
|
||||
static int32
|
||||
clipPoly(CamSpace3DVertex *in, int32 nin, CamSpace3DVertex *out, Plane *plane)
|
||||
{
|
||||
int32 j;
|
||||
int32 nout;
|
||||
int32 x1, x2;
|
||||
float32 d1, d2, t;
|
||||
|
||||
nout = 0;
|
||||
for(j = 0; j < nin; j++){
|
||||
x1 = j;
|
||||
x2 = (j+1) % nin;
|
||||
|
||||
d1 = dot(plane->normal, in[x1].camVertex) + plane->distance;
|
||||
d2 = dot(plane->normal, in[x2].camVertex) + plane->distance;
|
||||
if(d1*d2 < 0.0f){
|
||||
t = d1/(d1 - d2);
|
||||
interpVertex(&out[nout++], &in[x1], &in[x2], t);
|
||||
}
|
||||
if(d2 >= 0.0f)
|
||||
out[nout++] = in[x2];
|
||||
}
|
||||
return nout;
|
||||
}
|
||||
|
||||
static void
|
||||
clipTriangles2(MeshState *mstate, CamSpace3DVertex *camverts, Im2DVertex *scrverts, uint16 *indices, uint16 *clipindices)
|
||||
{
|
||||
int32 i, j;
|
||||
int32 x1, x2, x3;
|
||||
int32 newNumPrims;
|
||||
CamSpace3DVertex buf[18];
|
||||
CamSpace3DVertex *in, *out;
|
||||
int32 nout;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
Plane planes[6] = {
|
||||
{ { 0.0f, 0.0f, 1.0f }, -cam->nearPlane }, // z = near
|
||||
{ { 0.0f, 0.0f, -1.0f }, cam->farPlane }, // z = far
|
||||
|
||||
{ { -1.0f, 0.0f, 1.0f }, 0.0f }, // x = w
|
||||
// { { 1.0f, 0.0f, 1.0f }, 0.0f }, // x = -w
|
||||
{ { 1.0f, 0.0f, 0.0f }, 0.0f }, // x = 0
|
||||
|
||||
{ { 0.0f, -1.0f, 1.0f }, 0.0f }, // y = w
|
||||
// { { 0.0f, 1.0f, 1.0f }, 0.0f } // y = -1
|
||||
{ { 0.0f, 1.0f, 0.0f }, 0.0f } // y = 0
|
||||
};
|
||||
|
||||
newNumPrims = 0;
|
||||
for(i = 0; i < mstate->numPrimitives; i++, indices += 3){
|
||||
x1 = indices[0];
|
||||
x2 = indices[1];
|
||||
x3 = indices[2];
|
||||
|
||||
if((camverts[x1].clipFlags |
|
||||
camverts[x2].clipFlags |
|
||||
camverts[x3].clipFlags) == 0){
|
||||
// all inside
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2;
|
||||
clipindices[2] = x3;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// set up triangle
|
||||
in = &buf[0];
|
||||
out = &buf[9];
|
||||
in[0] = camverts[x1];
|
||||
in[1] = camverts[x2];
|
||||
in[2] = camverts[x3];
|
||||
nout = 0;
|
||||
|
||||
// clip here
|
||||
if(nout = clipPoly(in, 3, out, &planes[0]), nout == 0) continue;
|
||||
if(nout = clipPoly(out, nout, in, &planes[1]), nout == 0) continue;
|
||||
if(nout = clipPoly(in, nout, out, &planes[2]), nout == 0) continue;
|
||||
if(nout = clipPoly(out, nout, in, &planes[3]), nout == 0) continue;
|
||||
if(nout = clipPoly(in, nout, out, &planes[4]), nout == 0) continue;
|
||||
if(nout = clipPoly(out, nout, in, &planes[5]), nout == 0) continue;
|
||||
out = in;
|
||||
|
||||
// Insert new triangles
|
||||
x1 = mstate->numVertices;
|
||||
for(j = 0; j < nout; j++){
|
||||
x2 = mstate->numVertices++;
|
||||
camverts[x2] = out[j];
|
||||
cam2screen(&scrverts[x2], &camverts[x2]);
|
||||
}
|
||||
x2 = x1+1;
|
||||
for(j = 0; j < nout-2; j++){
|
||||
clipindices[0] = x1;
|
||||
clipindices[1] = x2++;
|
||||
clipindices[2] = x2;
|
||||
clipindices += 3;
|
||||
newNumPrims++;
|
||||
}
|
||||
}
|
||||
mstate->numPrimitives = newNumPrims;
|
||||
}
|
||||
|
||||
static void
|
||||
submitTriangles(RWDEVICE::Im2DVertex *scrverts, int32 numVerts, uint16 *indices, int32 numTris)
|
||||
{
|
||||
rw::SetRenderStatePtr(rw::TEXTURERASTER, nil);
|
||||
if(dosoftras)
|
||||
rastest_renderTriangles(scrverts, numVerts, indices, numTris);
|
||||
else{
|
||||
//int i;
|
||||
//for(i = 0; i < numVerts; i++){
|
||||
// scrverts[i].x = (int)(scrverts[i].x*16.0f) / 16.0f;
|
||||
// scrverts[i].y = (int)(scrverts[i].y*16.0f) / 16.0f;
|
||||
//}
|
||||
im2d::RenderIndexedPrimitive(rw::PRIMTYPETRILIST, scrverts, numVerts,
|
||||
indices, numTris*3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
drawMesh(MeshState *mstate, ObjSpace3DVertex *objverts, uint16 *indices)
|
||||
{
|
||||
CamSpace3DVertex *camverts;
|
||||
Im2DVertex *scrverts;
|
||||
uint16 *cullindices, *clipindices;
|
||||
uint32 numClip;
|
||||
|
||||
camverts = rwNewT(CamSpace3DVertex, mstate->numVertices, MEMDUR_FUNCTION);
|
||||
scrverts = rwNewT(Im2DVertex, mstate->numVertices, MEMDUR_FUNCTION);
|
||||
cullindices = rwNewT(uint16, mstate->numPrimitives*3, MEMDUR_FUNCTION);
|
||||
|
||||
transform(mstate, objverts, camverts, scrverts);
|
||||
|
||||
numClip = cullTriangles(mstate, camverts, indices, cullindices);
|
||||
|
||||
// int32 i;
|
||||
// for(i = 0; i < mstate->numVertices; i++){
|
||||
// if(camverts[i].clipFlags & CLIPX)
|
||||
// camverts[i].color.red = 255;
|
||||
// if(camverts[i].clipFlags & CLIPY)
|
||||
// camverts[i].color.green = 255;
|
||||
// if(camverts[i].clipFlags & CLIPZ)
|
||||
// camverts[i].color.blue = 255;
|
||||
// }
|
||||
|
||||
light(mstate, objverts, camverts);
|
||||
|
||||
// mstate->matCol.red = 255;
|
||||
// mstate->matCol.green = 255;
|
||||
// mstate->matCol.blue = 255;
|
||||
|
||||
postlight(mstate, camverts, scrverts);
|
||||
|
||||
// each triangle can have a maximum of 9 vertices (7 triangles) after clipping
|
||||
// so resize to whatever we may need
|
||||
camverts = rwResizeT(CamSpace3DVertex, camverts, mstate->numVertices + numClip*9, MEMDUR_FUNCTION);
|
||||
scrverts = rwResizeT(Im2DVertex, scrverts, mstate->numVertices + numClip*9, MEMDUR_FUNCTION);
|
||||
clipindices = rwNewT(uint16, mstate->numPrimitives*3 + numClip*7*3, MEMDUR_FUNCTION);
|
||||
|
||||
// clipTriangles(mstate, camverts, scrverts, cullindices, clipindices);
|
||||
clipTriangles2(mstate, camverts, scrverts, cullindices, clipindices);
|
||||
|
||||
submitTriangles(scrverts, mstate->numVertices, clipindices, mstate->numPrimitives);
|
||||
|
||||
rwFree(camverts);
|
||||
rwFree(scrverts);
|
||||
rwFree(cullindices);
|
||||
rwFree(clipindices);
|
||||
}
|
||||
|
||||
static void
|
||||
drawAtomic(Atomic *atomic)
|
||||
{
|
||||
MeshState mstate;
|
||||
Matrix lightmat;
|
||||
Geometry *geo;
|
||||
MeshHeader *header;
|
||||
InstanceData *inst;
|
||||
int i;
|
||||
Camera *cam = (Camera*)engine->currentCamera;
|
||||
|
||||
instanceAtomic(atomic);
|
||||
|
||||
mstate.obj2world = *atomic->getFrame()->getLTM();
|
||||
mstate.obj2cam = mstate.obj2world;
|
||||
mstate.obj2cam.transform(&cam->viewMatrix, COMBINEPOSTCONCAT);
|
||||
Matrix::invert(&lightmat, &mstate.obj2world);
|
||||
enumLights(&lightmat);
|
||||
|
||||
geo = atomic->geometry;
|
||||
header = geo->meshHeader;
|
||||
inst = ((InstanceDataHeader*)geo->instData)->inst;
|
||||
for(i = 0; i < header->numMeshes; i++){
|
||||
mstate.flags = geo->flags;
|
||||
mstate.numVertices = inst->numVertices;
|
||||
mstate.numPrimitives = inst->numIndices / 3;
|
||||
mstate.surfProps = inst->material->surfaceProps;
|
||||
mstate.matCol = inst->material->color;
|
||||
drawMesh(&mstate, inst->vertices, inst->indices);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tlTest(Clump *clump)
|
||||
{
|
||||
FORLIST(lnk, clump->atomics){
|
||||
Atomic *a = Atomic::fromClump(lnk);
|
||||
drawAtomic(a);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Im2DVertex *clipverts;
|
||||
static int32 numClipverts;
|
||||
|
||||
void
|
||||
genIm3DTransform(void *vertices, int32 numVertices, Matrix *world)
|
||||
{
|
||||
Im3DVertex *objverts;
|
||||
V3d pos;
|
||||
Matrix xform;
|
||||
Camera *cam;
|
||||
int32 i;
|
||||
objverts = (Im3DVertex*)vertices;
|
||||
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
int32 width = cam->frameBuffer->width;
|
||||
int32 height = cam->frameBuffer->height;
|
||||
|
||||
|
||||
xform = cam->viewMatrix;
|
||||
if(world)
|
||||
xform.transform(world, COMBINEPRECONCAT);
|
||||
|
||||
clipverts = rwNewT(Im2DVertex, numVertices, MEMDUR_EVENT);
|
||||
numClipverts = numVertices;
|
||||
|
||||
for(i = 0; i < numVertices; i++){
|
||||
V3d::transformPoints(&pos, &objverts[i].position, 1, &xform);
|
||||
|
||||
float32 recipZ = 1.0f/pos.z;
|
||||
RGBA c = objverts[i].getColor();
|
||||
|
||||
clipverts[i].setScreenX(pos.x * recipZ * width);
|
||||
clipverts[i].setScreenY(pos.y * recipZ * height);
|
||||
clipverts[i].setScreenZ(recipZ * cam->zScale + cam->zShift);
|
||||
clipverts[i].setCameraZ(pos.z);
|
||||
clipverts[i].setRecipCameraZ(recipZ);
|
||||
clipverts[i].setColor(c.red, c.green, c.blue, c.alpha);
|
||||
clipverts[i].setU(objverts[i].u, recipZ);
|
||||
clipverts[i].setV(objverts[i].v, recipZ);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DRenderIndexed(PrimitiveType prim, void *indices, int32 numIndices)
|
||||
{
|
||||
im2d::RenderIndexedPrimitive(prim, clipverts, numClipverts, indices, numIndices);
|
||||
}
|
||||
|
||||
void
|
||||
genIm3DEnd(void)
|
||||
{
|
||||
rwFree(clipverts);
|
||||
clipverts = nil;
|
||||
numClipverts = 0;
|
||||
}
|
||||
26
vendor/librw/tools/ps2test/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
add_executable(ps2test
|
||||
gs.h
|
||||
main.cpp
|
||||
mem.h
|
||||
ps2.h
|
||||
|
||||
vu/defaultpipe.dsm
|
||||
vu/skinpipe.dsm
|
||||
|
||||
vu/light.vu
|
||||
vu/setup_persp.vu
|
||||
)
|
||||
|
||||
target_link_libraries(ps2test
|
||||
PRIVATE
|
||||
librw::librw
|
||||
kernel
|
||||
)
|
||||
|
||||
librw_platform_target(ps2test INSTALL)
|
||||
|
||||
if(LIBRW_INSTALL)
|
||||
install(TARGETS ps2test
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
437
vendor/librw/tools/ps2test/gs.h
vendored
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
#define GS_NONINTERLACED 0
|
||||
#define GS_INTERLACED 1
|
||||
|
||||
#define GS_NTSC 2
|
||||
#define GS_PAL 3
|
||||
#define GS_VESA1A 0x1a
|
||||
#define GS_VESA1B 0x1b
|
||||
#define GS_VESA1C 0x1c
|
||||
#define GS_VESA1D 0x1d
|
||||
#define GS_VESA2A 0x2a
|
||||
#define GS_VESA2B 0x2b
|
||||
#define GS_VESA2C 0x2c
|
||||
#define GS_VESA2D 0x2d
|
||||
#define GS_VESA2E 0x2e
|
||||
#define GS_VESA3B 0x3b
|
||||
#define GS_VESA3C 0x3c
|
||||
#define GS_VESA3D 0x3d
|
||||
#define GS_VESA3E 0x3e
|
||||
#define GS_VESA4A 0x4a
|
||||
#define GS_VESA4B 0x4b
|
||||
#define GS_DTV480P 0x50
|
||||
|
||||
#define GS_FIELD 0
|
||||
#define GS_FRAME 1
|
||||
|
||||
#define GS_PSMCT32 0
|
||||
#define GS_PSMCT24 1
|
||||
#define GS_PSMCT16 2
|
||||
#define GS_PSMCT16S 10
|
||||
#define GS_PS_GPU24 18
|
||||
|
||||
#define GS_PSMZ32 0
|
||||
#define GS_PSMZ24 1
|
||||
#define GS_PSMZ16 2
|
||||
#define GS_PSMZ16S 10
|
||||
|
||||
#define GS_ZTST_NEVER 0
|
||||
#define GS_ZTST_ALWAYS 1
|
||||
#define GS_ZTST_GREATER 2
|
||||
#define GS_ZTST_GEQUAL 3
|
||||
|
||||
#define GS_PRIM_POINT 0
|
||||
#define GS_PRIM_LINE 1
|
||||
#define GS_PRIM_LINE_STRIP 2
|
||||
#define GS_PRIM_TRI 3
|
||||
#define GS_PRIM_TRI_STRIP 4
|
||||
#define GS_PRIM_TRI_FAN 5
|
||||
#define GS_PRIM_SPRITE 6
|
||||
#define GS_PRIM_NO_SPEC 7
|
||||
#define GS_IIP_FLAT 0
|
||||
#define GS_IIP_GOURAUD 1
|
||||
|
||||
/* GS general purpose registers */
|
||||
|
||||
#define GS_PRIM 0x00
|
||||
#define GS_RGBAQ 0x01
|
||||
#define GS_ST 0x02
|
||||
#define GS_UV 0x03
|
||||
#define GS_XYZF2 0x04
|
||||
#define GS_XYZ2 0x05
|
||||
#define GS_TEX0_1 0x06
|
||||
#define GS_TEX0_2 0x07
|
||||
#define GS_CLAMP_1 0x08
|
||||
#define GS_CLAMP_2 0x09
|
||||
#define GS_FOG 0x0a
|
||||
#define GS_XYZF3 0x0c
|
||||
#define GS_XYZ3 0x0d
|
||||
#define GS_TEX1_1 0x14
|
||||
#define GS_TEX1_2 0x15
|
||||
#define GS_TEX2_1 0x16
|
||||
#define GS_TEX2_2 0x17
|
||||
#define GS_XYOFFSET_1 0x18
|
||||
#define GS_XYOFFSET_2 0x19
|
||||
#define GS_PRMODECONT 0x1a
|
||||
#define GS_PRMODE 0x1b
|
||||
#define GS_TEXCLUT 0x1c
|
||||
#define GS_SCANMSK 0x22
|
||||
#define GS_MIPTBP1_1 0x34
|
||||
#define GS_MIPTBP1_2 0x35
|
||||
#define GS_MIPTBP2_1 0x36
|
||||
#define GS_MIPTBP2_2 0x37
|
||||
#define GS_TEXA 0x3b
|
||||
#define GS_FOGCOL 0x3d
|
||||
#define GS_TEXFLUSH 0x3f
|
||||
#define GS_SCISSOR_1 0x40
|
||||
#define GS_SCISSOR_2 0x41
|
||||
#define GS_ALPHA_1 0x42
|
||||
#define GS_ALPHA_2 0x43
|
||||
#define GS_DIMX 0x44
|
||||
#define GS_DTHE 0x45
|
||||
#define GS_COLCLAMP 0x46
|
||||
#define GS_TEST_1 0x47
|
||||
#define GS_TEST_2 0x48
|
||||
#define GS_PABE 0x49
|
||||
#define GS_FBA_1 0x4a
|
||||
#define GS_FBA_2 0x4b
|
||||
#define GS_FRAME_1 0x4c
|
||||
#define GS_FRAME_2 0x4d
|
||||
#define GS_ZBUF_1 0x4e
|
||||
#define GS_ZBUF_2 0x4f
|
||||
#define GS_BITBLTBUF 0x50
|
||||
#define GS_TRXPOS 0x51
|
||||
#define GS_TRXREG 0x52
|
||||
#define GS_TRXDIR 0x53
|
||||
#define GS_HWREG 0x54
|
||||
#define GS_SIGNAL 0x60
|
||||
#define GS_FINISH 0x61
|
||||
#define GS_LABEL 0x62
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 EN1 : 1;
|
||||
uint64 EN2 : 1;
|
||||
uint64 CRTMD : 3;
|
||||
uint64 MMOD : 1;
|
||||
uint64 AMOD : 1;
|
||||
uint64 SLBG : 1;
|
||||
uint64 ALP : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsPmode;
|
||||
|
||||
#define GS_MAKE_PMODE(EN1,EN2,MMOD,AMOD,SLBG,ALP) \
|
||||
(BIT64(EN1,0) | BIT64(EN2,1) | BIT64(1,2) | \
|
||||
BIT64(MMOD,5) | BIT64(AMOD,6) | BIT64(SLBG,7) | BIT64(ALP,8))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 INT : 1;
|
||||
uint64 FFMD : 1;
|
||||
uint64 DPMS : 2;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsSmode2;
|
||||
|
||||
#define GS_MAKE_SMODE2(INT,FFMD,DPMS) \
|
||||
(BIT64(INT,0) | BIT64(FFMD,1) | BIT64(DPMS,2))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 FBP : 9;
|
||||
uint64 FBW : 6;
|
||||
uint64 PSM : 5;
|
||||
uint64 : 12;
|
||||
uint64 DBX : 11;
|
||||
uint64 DBY : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsDispfb;
|
||||
|
||||
#define GS_MAKE_DISPFB(FBP,FBW,PSM,DBX,DBY) \
|
||||
(BIT64(FBP,0) | BIT64(FBW,9) | BIT64(PSM,15) | \
|
||||
BIT64(DBX,32) | BIT64(DBY,43))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 DX : 12;
|
||||
uint64 DY : 11;
|
||||
uint64 MAGH : 4;
|
||||
uint64 MAGV : 2;
|
||||
uint64 : 3;
|
||||
uint64 DW : 12;
|
||||
uint64 DH : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsDisplay;
|
||||
|
||||
#define GS_MAKE_DISPLAY(DX,DY,MAGH,MAGV,DW,DH) \
|
||||
(BIT64(DX,0) | BIT64(DY,12) | BIT64(MAGH,23) | \
|
||||
BIT64(MAGV,27) | BIT64(DW,32) | BIT64(DH,44))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 EXBP : 14;
|
||||
uint64 EXBW : 6;
|
||||
uint64 FBIN : 2;
|
||||
uint64 WFFMD : 1;
|
||||
uint64 EMODA : 2;
|
||||
uint64 EMODC : 2;
|
||||
uint64 : 5;
|
||||
uint64 WDX : 11;
|
||||
uint64 WDY : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtbuf;
|
||||
|
||||
#define GS_MAKE_EXTBUF(EXBP,EXBW,FBIN,WFFMD,EMODA,EMODC,WDX,WDY) \
|
||||
(BIT64(EXBP,0) | BIT64(EXBW,14) | BIT64(FBIN,20) | \
|
||||
BIT64(WFFMD,22) | BIT64(EMODA,23) | BIT64(EMODC,25) | \
|
||||
BIT64(WDX,32) | BIT64(WDY,43))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SX : 12;
|
||||
uint64 SY : 11;
|
||||
uint64 SMPH : 4;
|
||||
uint64 SMPV : 2;
|
||||
uint64 : 3;
|
||||
uint64 WW : 12;
|
||||
uint64 WH : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtdata;
|
||||
|
||||
#define GS_MAKE_EXTDATA(SX,SY,SMPH,SMPV,WW,WH) \
|
||||
(BIT64(SX,0) | BIT64(SY,12) | BIT64(SMPH,23) | \
|
||||
BIT64(SMPV,27) | BIT64(WW,32) | BIT64(WH,44))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 WRITE : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtwrite;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 R : 8;
|
||||
uint64 G : 8;
|
||||
uint64 B : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsBgcolor;
|
||||
|
||||
#define GS_MAKE_BGCOLOR(R,G,B) \
|
||||
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SIGNAL : 1;
|
||||
uint64 FINISH : 1;
|
||||
uint64 HSINT : 1;
|
||||
uint64 VSINT : 1;
|
||||
uint64 EDWINT : 1;
|
||||
uint64 : 3;
|
||||
uint64 FLUSH : 1;
|
||||
uint64 RESET : 1;
|
||||
uint64 : 2;
|
||||
uint64 NFIELD : 1;
|
||||
uint64 FIELD : 1;
|
||||
uint64 FIFO : 2;
|
||||
uint64 REV : 8;
|
||||
uint64 ID : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsCsr;
|
||||
|
||||
#define GS_CSR_SIGNAL_O 0
|
||||
#define GS_CSR_FINISH_O 1
|
||||
#define GS_CSR_HSINT_O 2
|
||||
#define GS_CSR_VSINT_O 3
|
||||
#define GS_CSR_EDWINT_O 4
|
||||
#define GS_CSR_FLUSH_O 8
|
||||
#define GS_CSR_RESET_O 9
|
||||
#define GS_CSR_NFIELD_O 12
|
||||
#define GS_CSR_FIELD_O 13
|
||||
#define GS_CSR_FIFO_O 14
|
||||
#define GS_CSR_REV_O 16
|
||||
#define GS_CSR_ID_O 24
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 : 8;
|
||||
uint64 SIGMSK : 1;
|
||||
uint64 FINISHMSK : 1;
|
||||
uint64 HSMSKMSK : 1;
|
||||
uint64 VSMSKMSK : 1;
|
||||
uint64 EDWMSKMSK : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsImr;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 DIR : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsBusdir;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SIGID : 32;
|
||||
uint64 LBLID : 32;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsSiglblid;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 FBP : 9;
|
||||
uint64 : 7;
|
||||
uint64 FBW : 6;
|
||||
uint64 : 2;
|
||||
uint64 PSM : 6;
|
||||
uint64 : 2;
|
||||
uint64 FBMSK : 32;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsFrame;
|
||||
|
||||
#define GS_MAKE_FRAME(FBP,FBW,PSM,FBMASK) \
|
||||
(BIT64(FBP,0) | BIT64(FBW,16) | BIT64(PSM,24) | BIT64(FBMASK,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 ZBP : 9;
|
||||
uint64 : 15;
|
||||
uint64 PSM : 4;
|
||||
uint64 : 4;
|
||||
uint64 ZMSDK : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsZbuf;
|
||||
|
||||
#define GS_MAKE_ZBUF(ZBP,PSM,ZMSK) \
|
||||
(BIT64(ZBP,0) | BIT64(PSM,24) | BIT64(ZMSK,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 OFX : 16;
|
||||
uint64 : 16;
|
||||
uint64 OFY : 16;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsXyOffset;
|
||||
|
||||
#define GS_MAKE_XYOFFSET(OFX,OFY) \
|
||||
(BIT64(OFX,0) | BIT64(OFY,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SCAX0 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAX1 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAY0 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAY1 : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsScissor;
|
||||
|
||||
#define GS_MAKE_SCISSOR(SCAX0,SCAX1,SCAY0,SCAY1) \
|
||||
(BIT64(SCAX0,0) | BIT64(SCAX1,16) | BIT64(SCAY0,32) | BIT64(SCAY1,48))
|
||||
|
||||
#define GS_MAKE_TEST(ATE,ATST,AREF,AFAIL,DATE,DATM,ZTE,ZTST) \
|
||||
(BIT64(ATE,0) | BIT64(ATST,1) | BIT64(AREF,4) | BIT64(AFAIL,12) | \
|
||||
BIT64(DATE,14) | BIT64(DATM,15) | BIT64(ZTE,16) | BIT64(ZTST,17))
|
||||
|
||||
#define GS_MAKE_PRIM(PRIM,IIP,TME,FGE,ABE,AA1,FST,CTXT,FIX) \
|
||||
(BIT64(PRIM,0) | BIT64(IIP,3) | BIT64(TME,4) | BIT64(FGE,5) | \
|
||||
BIT64(ABE,6) | BIT64(AA1,7) | BIT64(FST,8) | BIT64(CTXT,9) | BIT64(FIX,10))
|
||||
|
||||
#define GS_MAKE_RGBAQ(R,G,B,A,Q) \
|
||||
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16) | BIT64(A,24) | BIT64(Q,32))
|
||||
|
||||
#define GS_MAKE_XYZ(X,Y,Z) \
|
||||
(BIT64(X,0) | BIT64(Y,16) | BIT64(Z,32))
|
||||
|
||||
#define GIF_PACKED 0
|
||||
#define GIF_REGLIST 1
|
||||
#define GIF_IMAGE 2
|
||||
|
||||
#define GIF_MAKE_TAG(NLOOP,EOP,PRE,PRIM,FLG,NREG) \
|
||||
(BIT64(NLOOP,0) | BIT64(EOP,15) | BIT64(PRE,46) | \
|
||||
BIT64(PRIM,47) | BIT64(FLG,58) | BIT64(NREG,60))
|
||||
|
||||
/* This is global and not tied to a user context because
|
||||
* it is set up by kernel functions and not really changed
|
||||
* afterwards. */
|
||||
typedef struct GsCrtState GsCrtState;
|
||||
struct GsCrtState
|
||||
{
|
||||
short inter, mode, ff;
|
||||
};
|
||||
extern GsCrtState gsCrtState;
|
||||
|
||||
typedef struct GsDispCtx GsDispCtx;
|
||||
struct GsDispCtx
|
||||
{
|
||||
// two circuits
|
||||
GsPmode pmode;
|
||||
GsDispfb dispfb1;
|
||||
GsDispfb dispfb2;
|
||||
GsDisplay display1;
|
||||
GsDisplay display2;
|
||||
GsBgcolor bgcolor;
|
||||
};
|
||||
|
||||
typedef struct GsDrawCtx GsDrawCtx;
|
||||
struct GsDrawCtx
|
||||
{
|
||||
//two contexts
|
||||
uint128 gifTag;
|
||||
GsFrame frame1;
|
||||
uint64 ad_frame1;
|
||||
GsFrame frame2;
|
||||
uint64 ad_frame2;
|
||||
GsZbuf zbuf1;
|
||||
uint64 ad_zbuf1;
|
||||
GsZbuf zbuf2;
|
||||
uint64 ad_zbuf2;
|
||||
GsXyOffset xyoffset1;
|
||||
uint64 ad_xyoffset1;
|
||||
GsXyOffset xyoffset2;
|
||||
uint64 ad_xyoffset2;
|
||||
GsScissor scissor1;
|
||||
uint64 ad_scissor1;
|
||||
GsScissor scissor2;
|
||||
uint64 ad_scissor2;
|
||||
};
|
||||
|
||||
typedef struct GsCtx GsCtx;
|
||||
struct GsCtx
|
||||
{
|
||||
// display context; two buffers
|
||||
GsDispCtx disp[2];
|
||||
// draw context; two buffers
|
||||
GsDrawCtx draw[2];
|
||||
};
|
||||
787
vendor/librw/tools/ps2test/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,787 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#define PAL
|
||||
|
||||
#include <rw.h>
|
||||
using rw::uint8;
|
||||
using rw::uint16;
|
||||
using rw::uint32;
|
||||
using rw::uint64;
|
||||
using rw::int8;
|
||||
using rw::int16;
|
||||
using rw::int32;
|
||||
using rw::int64;
|
||||
using rw::bool32;
|
||||
using rw::float32;
|
||||
typedef uint8 uchar;
|
||||
typedef uint16 ushort;
|
||||
typedef uint32 uint;
|
||||
|
||||
#define WIDTH 640
|
||||
#ifdef PAL
|
||||
#define HEIGHT 512
|
||||
#define VMODE GS_PAL
|
||||
#else
|
||||
#define HEIGHT 448
|
||||
#define VMODE GS_NTSC
|
||||
#endif
|
||||
|
||||
#include "ps2.h"
|
||||
|
||||
// getting undefined references otherwise :/
|
||||
int *__errno() { return &errno; }
|
||||
|
||||
// NONINTERLACED and FRAME have half of the FIELD vertical resolution!
|
||||
// NONINTERLACED has half the vertical units
|
||||
|
||||
uint128 packetbuf[128];
|
||||
uint128 vuXYZScale;
|
||||
uint128 vuXYZOffset;
|
||||
extern uint32 geometryCall[];
|
||||
extern uint32 skinPipe[];
|
||||
|
||||
uint128 *curVifPtr;
|
||||
uint128 lightpacket[128];
|
||||
int32 numLightQ;
|
||||
|
||||
|
||||
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
|
||||
|
||||
int frames;
|
||||
|
||||
void
|
||||
printquad(uint128 p)
|
||||
{
|
||||
uint64 *lp;
|
||||
lp = (uint64*)&p;
|
||||
printf("%016lx %016lx\n", lp[1], lp[0]);
|
||||
}
|
||||
|
||||
void
|
||||
printquad4(uint128 p)
|
||||
{
|
||||
uint32 *lp;
|
||||
lp = (uint32*)&p;
|
||||
printf("%08x %08x %08x %08x\n", lp[0], lp[1], lp[2], lp[3]);
|
||||
}
|
||||
|
||||
void
|
||||
dump4(uint128 *p, int n)
|
||||
{
|
||||
printf("data at %p\n", p);
|
||||
while(n--)
|
||||
printquad4(*p++);
|
||||
}
|
||||
|
||||
struct DmaChannel {
|
||||
uint32 chcr; uint32 pad0[3];
|
||||
uint32 madr; uint32 pad1[3];
|
||||
uint32 qwc; uint32 pad2[3];
|
||||
uint32 tadr; uint32 pad3[3];
|
||||
uint32 asr0; uint32 pad4[3];
|
||||
uint32 asr1; uint32 pad5[3];
|
||||
uint32 pad6[8];
|
||||
uint32 sadr;
|
||||
};
|
||||
|
||||
static struct DmaChannel *dmaChannels[] = {
|
||||
(struct DmaChannel *) &D0_CHCR,
|
||||
(struct DmaChannel *) &D1_CHCR,
|
||||
(struct DmaChannel *) &D2_CHCR,
|
||||
(struct DmaChannel *) &D3_CHCR,
|
||||
(struct DmaChannel *) &D4_CHCR,
|
||||
(struct DmaChannel *) &D5_CHCR,
|
||||
(struct DmaChannel *) &D6_CHCR,
|
||||
(struct DmaChannel *) &D7_CHCR,
|
||||
(struct DmaChannel *) &D8_CHCR,
|
||||
(struct DmaChannel *) &D9_CHCR
|
||||
};
|
||||
|
||||
void
|
||||
dmaReset(void)
|
||||
{
|
||||
/* don't clear the SIF channels */
|
||||
int doclear[] = { 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 };
|
||||
int i;
|
||||
|
||||
D_CTRL = 0;
|
||||
for(i = 0; i < 10; i++)
|
||||
if(doclear[i]){
|
||||
dmaChannels[i]->chcr = 0;
|
||||
dmaChannels[i]->madr = 0;
|
||||
dmaChannels[i]->qwc = 0;
|
||||
dmaChannels[i]->tadr = 0;
|
||||
dmaChannels[i]->asr0 = 0;
|
||||
dmaChannels[i]->asr1 = 0;
|
||||
dmaChannels[i]->sadr = 0;
|
||||
}
|
||||
D_CTRL = 1;
|
||||
}
|
||||
|
||||
void
|
||||
waitDMA(volatile uint32 *chcr)
|
||||
{
|
||||
while(*chcr & (1<<8));
|
||||
}
|
||||
|
||||
void
|
||||
qwcpy(uint128 *dst, uint128 *src, int n)
|
||||
{
|
||||
while(n--) *dst++ = *src++;
|
||||
}
|
||||
|
||||
void
|
||||
toGIF(void *src, int n)
|
||||
{
|
||||
FlushCache(0);
|
||||
D2_QWC = n;
|
||||
D2_MADR = (uint32)src;
|
||||
D2_CHCR = 1<<8;
|
||||
waitDMA(&D2_CHCR);
|
||||
}
|
||||
|
||||
void
|
||||
toGIFchain(void *src)
|
||||
{
|
||||
FlushCache(0);
|
||||
D2_QWC = 0;
|
||||
D2_TADR = (uint32)src & 0x0FFFFFFF;
|
||||
D2_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
|
||||
waitDMA(&D2_CHCR);
|
||||
}
|
||||
|
||||
void
|
||||
toVIF1chain(void *src)
|
||||
{
|
||||
FlushCache(0);
|
||||
D1_QWC = 0;
|
||||
D1_TADR = (uint32)src & 0x0FFFFFFF;
|
||||
D1_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
|
||||
waitDMA(&D1_CHCR);
|
||||
}
|
||||
|
||||
|
||||
GsCrtState gsCrtState;
|
||||
|
||||
int psmsizemap[64] = {
|
||||
4, // GS_PSMCT32
|
||||
4, // GS_PSMCT24
|
||||
2, // GS_PSMCT16
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
2, // GS_PSMCT16S
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, // GS_PSMZ32
|
||||
4, // GS_PSMZ24
|
||||
2, // GS_PSMZ16
|
||||
2, // GS_PSMZ16S
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void
|
||||
GsResetCrt(uchar inter, uchar mode, uchar ff)
|
||||
{
|
||||
gsCrtState.inter = inter;
|
||||
gsCrtState.mode = mode;
|
||||
gsCrtState.ff = ff;
|
||||
GS_CSR = 1 << GS_CSR_RESET_O;
|
||||
__asm__("sync.p; nop");
|
||||
GsPutIMR(0xff00);
|
||||
SetGsCrt(gsCrtState.inter, gsCrtState.mode, gsCrtState.ff);
|
||||
}
|
||||
|
||||
uint gsAllocPtr = 0;
|
||||
|
||||
void
|
||||
GsInitDispCtx(GsDispCtx *disp, int width, int height, int psm)
|
||||
{
|
||||
int magh, magv;
|
||||
int dx, dy;
|
||||
int dw, dh;
|
||||
|
||||
dx = gsCrtState.mode == GS_NTSC ? 636 : 656;
|
||||
dy = gsCrtState.mode == GS_NTSC ? 25 : 36;
|
||||
magh = 2560/width - 1;
|
||||
magv = 0;
|
||||
dw = 2560-1;
|
||||
dh = height-1;
|
||||
|
||||
if(gsCrtState.inter == GS_INTERLACED){
|
||||
dy *= 2;
|
||||
if(gsCrtState.ff == GS_FRAME)
|
||||
dh = (dh+1)*2-1;
|
||||
}
|
||||
|
||||
disp->pmode.d = GS_MAKE_PMODE(0, 1, 1, 1, 0, 0x00);
|
||||
// disp->bgcolor.d = 0x404040;
|
||||
disp->bgcolor.d = 0x000000;
|
||||
disp->dispfb1.d = 0;
|
||||
disp->dispfb2.d = GS_MAKE_DISPFB(0, width/64, psm, 0, 0);
|
||||
disp->display1.d = 0;
|
||||
disp->display2.d = GS_MAKE_DISPLAY(dx, dy, magh, magv, dw, dh);
|
||||
}
|
||||
|
||||
void
|
||||
GsPutDispCtx(GsDispCtx *disp)
|
||||
{
|
||||
GS_PMODE = disp->pmode.d;
|
||||
GS_DISPFB1 = disp->dispfb1.d;
|
||||
GS_DISPLAY1 = disp->display1.d;
|
||||
GS_DISPFB2 = disp->dispfb2.d;
|
||||
GS_DISPLAY2 = disp->display2.d;
|
||||
GS_BGCOLOR = disp->bgcolor.d;
|
||||
}
|
||||
|
||||
void
|
||||
GsInitDrawCtx(GsDrawCtx *draw, int width, int height, int psm, int zpsm)
|
||||
{
|
||||
MAKE128(draw->gifTag, 0xe,
|
||||
GIF_MAKE_TAG(8, 1, 0, 0, GIF_PACKED, 1));
|
||||
draw->frame1.d = GS_MAKE_FRAME(0, width/64, psm, 0);
|
||||
draw->ad_frame1 = GS_FRAME_1;
|
||||
draw->frame2.d = draw->frame1.d;
|
||||
draw->ad_frame2 = GS_FRAME_2;
|
||||
draw->zbuf1.d = GS_MAKE_ZBUF(0, zpsm, 0);
|
||||
draw->ad_zbuf1 = GS_ZBUF_1;
|
||||
draw->zbuf2.d = draw->zbuf1.d;
|
||||
draw->ad_zbuf2 = GS_ZBUF_2;
|
||||
draw->xyoffset1.d = GS_MAKE_XYOFFSET(2048<<4, 2048<<4);
|
||||
draw->ad_xyoffset1 = GS_XYOFFSET_1;
|
||||
draw->xyoffset2.d = draw->xyoffset1.d;
|
||||
draw->ad_xyoffset2 = GS_XYOFFSET_2;
|
||||
draw->scissor1.d = GS_MAKE_SCISSOR(0, width-1, 0, height-1);
|
||||
draw->ad_scissor1 = GS_SCISSOR_1;
|
||||
draw->scissor2.d = draw->scissor1.d;
|
||||
draw->ad_scissor2 = GS_SCISSOR_2;
|
||||
}
|
||||
|
||||
void
|
||||
GsPutDrawCtx(GsDrawCtx *draw)
|
||||
{
|
||||
// printquad(*(uint128*)&draw->frame1);
|
||||
toGIF(draw, 9);
|
||||
}
|
||||
|
||||
void
|
||||
GsInitCtx(GsCtx *ctx, int width, int height, int psm, int zpsm)
|
||||
{
|
||||
uint fbsz, zbsz;
|
||||
uint fbp, zbp;
|
||||
fbsz = (width*height*psmsizemap[psm] + 2047)/2048;
|
||||
zbsz = (width*height*psmsizemap[0x30|zpsm] + 2047)/2048;
|
||||
gsAllocPtr = 2*fbsz + zbsz;
|
||||
fbp = fbsz;
|
||||
zbp = fbsz*2;
|
||||
|
||||
GsInitDispCtx(&ctx->disp[0], width, height, psm);
|
||||
GsInitDispCtx(&ctx->disp[1], width, height, psm);
|
||||
GsInitDrawCtx(&ctx->draw[0], width, height, psm, zpsm);
|
||||
GsInitDrawCtx(&ctx->draw[1], width, height, psm, zpsm);
|
||||
ctx->disp[1].dispfb2.f.FBP = fbp/4;
|
||||
ctx->draw[0].frame1.f.FBP = fbp/4;
|
||||
ctx->draw[0].frame2.f.FBP = fbp/4;
|
||||
ctx->draw[0].zbuf1.f.ZBP = zbp/4;
|
||||
ctx->draw[0].zbuf2.f.ZBP = zbp/4;
|
||||
ctx->draw[1].zbuf1.f.ZBP = zbp/4;
|
||||
ctx->draw[1].zbuf2.f.ZBP = zbp/4;
|
||||
}
|
||||
|
||||
void
|
||||
initrender(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
p = packetbuf;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRMODECONT, 1);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_COLCLAMP, 1);
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 3);
|
||||
}
|
||||
|
||||
void
|
||||
clearscreen(int r, int g, int b)
|
||||
{
|
||||
int x, y;
|
||||
uint128 *p, tmp;
|
||||
p = packetbuf;
|
||||
|
||||
x = (2048 + WIDTH)<<4;
|
||||
y = (2048 + HEIGHT)<<4;
|
||||
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(5, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(r, g, b, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(2048<<4, 2048<<4, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x, y, 0));
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 6);
|
||||
}
|
||||
|
||||
void
|
||||
drawtest(void)
|
||||
{
|
||||
int x0, x1, x2, x3;
|
||||
int y0, y1, y2;
|
||||
uint128 *p, tmp;
|
||||
int n;
|
||||
|
||||
x0 = 2048<<4;
|
||||
x1 = (2048 + 210)<<4;
|
||||
x2 = (2048 + 430)<<4;
|
||||
x3 = (2048 + 640)<<4;
|
||||
y0 = 2048<<4;
|
||||
y1 = (2048 + 224)<<4;
|
||||
y2 = (2048 + 448)<<4;
|
||||
|
||||
n = 2 + 3*7;
|
||||
p = packetbuf;
|
||||
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(n, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 0, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ((2048+20)<<4, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, (2048+20)<<4, 0));
|
||||
*p++ = tmp;
|
||||
toGIFchain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
drawtri(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
uint32 *ip;
|
||||
int nverts, n;
|
||||
|
||||
nverts = 3;
|
||||
n = 2*nverts;
|
||||
p = packetbuf;
|
||||
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, (0x5<<4) | 0x1,
|
||||
GIF_MAKE_TAG(nverts, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI, 1, 0, 0, 0, 0, 0, 0, 0), GIF_PACKED, 2));
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 255, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+85)<<4, (2048+70)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 0, 255, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+260)<<4, (2048+200)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 0, 0, 255, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+180)<<4, (2048+350)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
toGIFchain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
printMatrix(rw::Matrix *m)
|
||||
{
|
||||
rw::V3d *x = &m->right;
|
||||
rw::V3d *y = &m->up;
|
||||
rw::V3d *z = &m->at;
|
||||
rw::V3d *w = &m->pos;
|
||||
printf(
|
||||
"[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n"
|
||||
" %08x == flags\n",
|
||||
x->x, y->x, z->x, w->x,
|
||||
x->y, y->y, z->y, w->y,
|
||||
x->z, y->z, z->z, w->z,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
m->flags);
|
||||
}
|
||||
|
||||
// This is not proper data, just for testing
|
||||
void
|
||||
setupLight(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
Matrix *lightmat;
|
||||
float32 *lp;
|
||||
|
||||
numLightQ = 0;
|
||||
lp = (float32*)lightpacket;
|
||||
|
||||
// TODO: this is the wrong matrix. we actually want to
|
||||
// transform the light, not all normals.
|
||||
lightmat = atomic->getFrame()->getLTM();
|
||||
*lp++ = lightmat->right.x;
|
||||
*lp++ = lightmat->right.y;
|
||||
*lp++ = lightmat->right.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->up.x;
|
||||
*lp++ = lightmat->up.y;
|
||||
*lp++ = lightmat->up.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->at.x;
|
||||
*lp++ = lightmat->at.y;
|
||||
*lp++ = lightmat->at.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->pos.x;
|
||||
*lp++ = lightmat->pos.y;
|
||||
*lp++ = lightmat->pos.z;
|
||||
*lp++ = 1.0f;
|
||||
// TODO: make a proper light block
|
||||
// ambient
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 0.0f;
|
||||
// directional
|
||||
*lp++ = 0.5f;
|
||||
*lp++ = -0.5f;
|
||||
*lp++ = -0.7071f;
|
||||
*lp++ = 0.0f;
|
||||
numLightQ = 6;
|
||||
}
|
||||
|
||||
void
|
||||
setupTransform(rw::Atomic *atomic, rw::Matrix *trans)
|
||||
{
|
||||
rw::Matrix::mult(trans, atomic->getFrame()->getLTM(), &camera->viewMatrix);
|
||||
}
|
||||
|
||||
enum {
|
||||
DMAcnt = 0x10000000,
|
||||
DMAref = 0x30000000,
|
||||
DMAcall = 0x50000000,
|
||||
DMAret = 0x60000000,
|
||||
DMAend = 0x70000000,
|
||||
|
||||
V4_32 = 0x6C
|
||||
};
|
||||
|
||||
#define UNPACK(type, nq, offset) ((type)<<24 | (nq)<<16 | (offset))
|
||||
#define STCYCL(WL,CL) (0x01000000 | (WL)<<8 | (CL))
|
||||
|
||||
void
|
||||
drawAtomic(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
|
||||
Matrix trans;
|
||||
Geometry *geo;
|
||||
ps2::ObjPipeline *pipe;
|
||||
ps2::MatPipeline *matpipe;
|
||||
Material *material;
|
||||
uint128 tmp, *lp;
|
||||
uint32 *vec;
|
||||
RGBAf color;
|
||||
int i;
|
||||
|
||||
geo = atomic->geometry;
|
||||
pipe = (ps2::ObjPipeline*)atomic->getPipeline();
|
||||
if(pipe->platform != PLATFORM_PS2)
|
||||
return;
|
||||
|
||||
setupLight(atomic);
|
||||
setupTransform(atomic, &trans);
|
||||
|
||||
curVifPtr = packetbuf;
|
||||
// upload lights
|
||||
MAKEQ(tmp, DMAcnt | numLightQ+8, 0, STCYCL(4,4), UNPACK(V4_32, numLightQ, 0x3d0));
|
||||
*curVifPtr++ = tmp;
|
||||
for(lp = lightpacket; numLightQ--;)
|
||||
*curVifPtr++ = *lp++;
|
||||
|
||||
// upload transformation matrix
|
||||
MAKEQ(tmp, 0, 0, STCYCL(4,4), UNPACK(V4_32, 4, 0x3f0));
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.right;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.up;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.at;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.pos;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
|
||||
// upload camera/screen info
|
||||
MAKEQ(tmp, 0, 0, STCYCL(4,4), UNPACK(V4_32, 2, 0x3f7));
|
||||
*curVifPtr++ = tmp;
|
||||
*curVifPtr++ = vuXYZScale;
|
||||
*curVifPtr++ = vuXYZOffset;
|
||||
|
||||
assert(geo->instData != NULL);
|
||||
rw::ps2::InstanceDataHeader *instData =
|
||||
(rw::ps2::InstanceDataHeader*)geo->instData;
|
||||
rw::MeshHeader *meshHeader = geo->meshHeader;
|
||||
rw::Mesh *mesh;
|
||||
for(i = 0; i < instData->numMeshes; i++){
|
||||
material = instData->instanceMeshes[i].material;
|
||||
matpipe = pipe->groupPipeline;
|
||||
if(matpipe == nil)
|
||||
matpipe = (ps2::MatPipeline*)material->pipeline;
|
||||
if(matpipe == nil)
|
||||
matpipe = ps2::defaultMatPipe;
|
||||
|
||||
// call vu code
|
||||
MAKEQ(tmp, DMAcall, (uint32)skinPipe, 0, 0);
|
||||
*curVifPtr++ = tmp;
|
||||
// unpack GIF tag, material color, surface properties
|
||||
MAKEQ(tmp, DMAcnt | 3, 0, STCYCL(4,4), UNPACK(V4_32, 3, 0x3fa));
|
||||
*curVifPtr++ = tmp;
|
||||
MAKE128(tmp, 0x412,
|
||||
GIF_MAKE_TAG(0, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI_STRIP,1,0,0,0,0,0,0,0), GIF_PACKED, 3));
|
||||
*curVifPtr++ = tmp;
|
||||
convColor(&color, &material->color);
|
||||
color.alpha *= 128.0f/255.0f;
|
||||
MAKEQ(tmp, *(uint32*)&color.red, *(uint32*)&color.green,
|
||||
*(uint32*)&color.blue, *(uint32*)&color.alpha);
|
||||
*curVifPtr++ = tmp;
|
||||
MAKEQ(tmp, *(uint32*)&material->surfaceProps.ambient,
|
||||
*(uint32*)&material->surfaceProps.specular,
|
||||
*(uint32*)&material->surfaceProps.diffuse,
|
||||
0.0f); // extra
|
||||
*curVifPtr++ = tmp;
|
||||
// call geometry
|
||||
MAKEQ(tmp, DMAcall, (uint32)instData->instanceMeshes[i].data, 0x03000000, 0x02000000 | matpipe->vifOffset);
|
||||
*curVifPtr++ = tmp;
|
||||
}
|
||||
MAKEQ(tmp, DMAend, 0, 0, 0);
|
||||
*curVifPtr++ = tmp;
|
||||
// for(lp = packetbuf; lp < curVifPtr; lp++)
|
||||
// printquad4(*lp);
|
||||
toVIF1chain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
beginCamera(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
float32 *f;
|
||||
|
||||
p = packetbuf;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYOFFSET_1, GS_MAKE_XYOFFSET(2048-WIDTH/2 <<4, 2048-HEIGHT/2 <<4));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 2));
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 3);
|
||||
f = (float32*)&vuXYZScale;
|
||||
f[0] = WIDTH;
|
||||
f[1] = HEIGHT;
|
||||
f[2] = camera->zScale;
|
||||
f[3] = 0.0f;
|
||||
f = (float32*)&vuXYZOffset;
|
||||
f[0] = 2048.0f;
|
||||
f[1] = 2048.0f;
|
||||
f[2] = camera->zShift;
|
||||
f[3] = 0.0f;
|
||||
}
|
||||
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
|
||||
void
|
||||
pluginattach(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
}
|
||||
|
||||
bool32
|
||||
initrw(void)
|
||||
{
|
||||
rw::version = 0x34000;
|
||||
rw::platform = rw::PLATFORM_PS2;
|
||||
if(!rw::Engine::init())
|
||||
return 0;
|
||||
pluginattach();
|
||||
if(!rw::Engine::open(&engineOpenParams))
|
||||
return 0;
|
||||
if(!rw::Engine::start())
|
||||
return 0;
|
||||
rw::Texture::setLoadTextures(0);
|
||||
|
||||
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
|
||||
rw::Image::setSearchPath(".");
|
||||
|
||||
world = rw::World::create();
|
||||
camera = rw::Camera::create();
|
||||
camera->frameBuffer = rw::Raster::create(WIDTH, HEIGHT, 0, rw::Raster::CAMERA);
|
||||
camera->zBuffer = rw::Raster::create(WIDTH, HEIGHT, 0, rw::Raster::ZBUFFER);
|
||||
camera->setFrame(rw::Frame::create());
|
||||
rw::V3d t = { 0.0f, 0.0f, -4.0f };
|
||||
// rw::V3d t = { 0.0f, 0.0f, -40.0f };
|
||||
camera->getFrame()->translate(&t, rw::COMBINEPOSTCONCAT);
|
||||
rw::V3d axis = { 0.0f, 1.0f, 0.0f };
|
||||
camera->getFrame()->rotate(&axis, 40.0f, rw::COMBINEPOSTCONCAT);
|
||||
camera->setNearPlane(0.1f);
|
||||
camera->setFarPlane(450.0f);
|
||||
camera->setFOV(60.0f, 4.0f/3.0f);
|
||||
world->addCamera(camera);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vsynchInt = 0;
|
||||
|
||||
int
|
||||
vsynch(int id)
|
||||
{
|
||||
vsynchInt = 1;
|
||||
frames++;
|
||||
ExitHandler();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
FlushCache(0);
|
||||
if(!initrw()){
|
||||
printf("init failed!\n");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
rw::uint32 len;
|
||||
rw::uint8 *data = rw::getFileContents("host:player.DFF", &len);
|
||||
// rw::uint8 *data = rw::getFileContents("host:od_newscafe_dy.dff", &len);
|
||||
rw::StreamMemory in;
|
||||
in.open(data, len);
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
rw::Clump *clump = rw::Clump::streamRead(&in);
|
||||
in.close();
|
||||
rwFree(data);
|
||||
|
||||
GsCtx gsCtx;
|
||||
|
||||
dmaReset();
|
||||
|
||||
// GsResetCrt(GS_NONINTERLACED, GS_NTSC, 0);
|
||||
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
// GsResetCrt(GS_INTERLACED, GS_NTSC, GS_FRAME);
|
||||
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
GsResetCrt(GS_INTERLACED, VMODE, GS_FIELD);
|
||||
GsInitCtx(&gsCtx, WIDTH, HEIGHT, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
initrender();
|
||||
|
||||
AddIntcHandler(2, vsynch, 0);
|
||||
EnableIntc(2);
|
||||
|
||||
GsPutDrawCtx(&gsCtx.draw[0]);
|
||||
GsPutDispCtx(&gsCtx.disp[1]);
|
||||
// PCSX2 needs a delay for some reason
|
||||
{ int i; for(i = 0; i < 1000000; i++); }
|
||||
clearscreen(0x80, 0x80, 0x80);
|
||||
// drawtest();
|
||||
// drawtri();
|
||||
|
||||
float angle = 40.0f;
|
||||
int drawbuf = 0;
|
||||
int dispbuf = 1;
|
||||
for(;;){
|
||||
clearscreen(0x80, 0x80, 0x80);
|
||||
|
||||
rw::V3d t = { 0.0f, 0.0f, -4.0f };
|
||||
camera->getFrame()->translate(&t, rw::COMBINEREPLACE);
|
||||
rw::V3d axis = { 0.0f, 1.0f, 0.0f };
|
||||
camera->getFrame()->rotate(&axis, angle, rw::COMBINEPOSTCONCAT);
|
||||
angle += 1.0f;
|
||||
|
||||
camera->beginUpdate();
|
||||
beginCamera();
|
||||
FORLIST(lnk, clump->atomics)
|
||||
drawAtomic(rw::Atomic::fromClump(lnk));
|
||||
camera->endUpdate();
|
||||
printf("");
|
||||
|
||||
while(vsynchInt == 0);
|
||||
GsPutDrawCtx(&gsCtx.draw[drawbuf]);
|
||||
GsPutDispCtx(&gsCtx.disp[dispbuf]);
|
||||
drawbuf = !drawbuf;
|
||||
dispbuf = !dispbuf;
|
||||
vsynchInt = 0;
|
||||
}
|
||||
/*
|
||||
camera->beginUpdate();
|
||||
beginCamera();
|
||||
FORLIST(lnk, clump->atomics)
|
||||
drawAtomic(rw::Atomic::fromClump(lnk));
|
||||
camera->endUpdate();
|
||||
|
||||
printf("hello %p\n", clump);
|
||||
for(;;)
|
||||
printf("");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
95
vendor/librw/tools/ps2test/mem.h
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* FIFOs */
|
||||
#define VIF0_FIFO (*(volatile uint128*)0x10004000)
|
||||
#define VIF1_FIFO (*(volatile uint128*)0x10005000)
|
||||
#define GIF_FIFO (*(volatile uint128*)0x10006000)
|
||||
#define IPU_out_FIFO (*(volatile uint128*)0x10007000)
|
||||
#define IPU_in_FIFO (*(volatile uint128*)0x10007010)
|
||||
|
||||
/* DMA channels */
|
||||
// to VIF0
|
||||
#define D0_CHCR (*(volatile uint32*)0x10008000)
|
||||
#define D0_MADR (*(volatile uint32*)0x10008010)
|
||||
#define D0_QWC (*(volatile uint32*)0x10008020)
|
||||
#define D0_TADR (*(volatile uint32*)0x10008030)
|
||||
#define D0_ASR0 (*(volatile uint32*)0x10008040)
|
||||
#define D0_ASR1 (*(volatile uint32*)0x10008050)
|
||||
// VIF1
|
||||
#define D1_CHCR (*(volatile uint32*)0x10009000)
|
||||
#define D1_MADR (*(volatile uint32*)0x10009010)
|
||||
#define D1_QWC (*(volatile uint32*)0x10009020)
|
||||
#define D1_TADR (*(volatile uint32*)0x10009030)
|
||||
#define D1_ASR0 (*(volatile uint32*)0x10009040)
|
||||
#define D1_ASR1 (*(volatile uint32*)0x10009050)
|
||||
// to GIF
|
||||
#define D2_CHCR (*(volatile uint32*)0x1000a000)
|
||||
#define D2_MADR (*(volatile uint32*)0x1000a010)
|
||||
#define D2_QWC (*(volatile uint32*)0x1000a020)
|
||||
#define D2_TADR (*(volatile uint32*)0x1000a030)
|
||||
#define D2_ASR0 (*(volatile uint32*)0x1000a040)
|
||||
#define D2_ASR1 (*(volatile uint32*)0x1000a050)
|
||||
// fromIPU
|
||||
#define D3_CHCR (*(volatile uint32*)0x1000b000)
|
||||
#define D3_MADR (*(volatile uint32*)0x1000b010)
|
||||
#define D3_QWC (*(volatile uint32*)0x1000b020)
|
||||
// toIPU
|
||||
#define D4_CHCR (*(volatile uint32*)0x1000b400)
|
||||
#define D4_MADR (*(volatile uint32*)0x1000b410)
|
||||
#define D4_QWC (*(volatile uint32*)0x1000b420)
|
||||
#define D4_TADR (*(volatile uint32*)0x1000b430)
|
||||
// from SIF0
|
||||
#define D5_CHCR (*(volatile uint32*)0x1000c000)
|
||||
#define D5_MADR (*(volatile uint32*)0x1000c010)
|
||||
#define D5_QWC (*(volatile uint32*)0x1000c020)
|
||||
// to SIF1
|
||||
#define D6_CHCR (*(volatile uint32*)0x1000c400)
|
||||
#define D6_MADR (*(volatile uint32*)0x1000c410)
|
||||
#define D6_QWC (*(volatile uint32*)0x1000c420)
|
||||
#define D6_TADR (*(volatile uint32*)0x1000c430)
|
||||
// SIF2
|
||||
#define D7_CHCR (*(volatile uint32*)0x1000c800)
|
||||
#define D7_MADR (*(volatile uint32*)0x1000c810)
|
||||
#define D7_QWC (*(volatile uint32*)0x1000c820)
|
||||
// fromSPR
|
||||
#define D8_CHCR (*(volatile uint32*)0x1000d000)
|
||||
#define D8_MADR (*(volatile uint32*)0x1000d010)
|
||||
#define D8_QWC (*(volatile uint32*)0x1000d020)
|
||||
#define D8_SADR (*(volatile uint32*)0x1000d080)
|
||||
// toSPR
|
||||
#define D9_CHCR (*(volatile uint32*)0x1000d400)
|
||||
#define D9_MADR (*(volatile uint32*)0x1000d410)
|
||||
#define D9_QWC (*(volatile uint32*)0x1000d420)
|
||||
#define D9_TADR (*(volatile uint32*)0x1000d430)
|
||||
#define D9_SADR (*(volatile uint32*)0x1000d480)
|
||||
|
||||
/* DMA controller */
|
||||
#define D_CTRL (*(volatile uint32*)0x1000e000)
|
||||
#define D_STAT (*(volatile uint32*)0x1000e010)
|
||||
#define D_PCR (*(volatile uint32*)0x1000e020)
|
||||
#define D_SQWC (*(volatile uint32*)0x1000e030)
|
||||
#define D_RBSR (*(volatile uint32*)0x1000e040)
|
||||
#define D_RBOR (*(volatile uint32*)0x1000e050)
|
||||
#define D_STADR (*(volatile uint32*)0x1000e060)
|
||||
#define D_ENABLER (*(volatile uint32*)0x1000f520)
|
||||
#define D_ENABLEW (*(volatile uint32*)0x1000f590)
|
||||
|
||||
|
||||
/* GS privileged registers */
|
||||
#define GS_PMODE (*(volatile uint64*)0x12000000)
|
||||
#define GS_SMODE1 (*(volatile uint64*)0x12000010)
|
||||
#define GS_SMODE2 (*(volatile uint64*)0x12000020)
|
||||
#define GS_SRFSH (*(volatile uint64*)0x12000030)
|
||||
#define GS_SYNCH1 (*(volatile uint64*)0x12000040)
|
||||
#define GS_SYNCH2 (*(volatile uint64*)0x12000050)
|
||||
#define GS_SYNCV (*(volatile uint64*)0x12000060)
|
||||
#define GS_DISPFB1 (*(volatile uint64*)0x12000070)
|
||||
#define GS_DISPLAY1 (*(volatile uint64*)0x12000080)
|
||||
#define GS_DISPFB2 (*(volatile uint64*)0x12000090)
|
||||
#define GS_DISPLAY2 (*(volatile uint64*)0x120000a0)
|
||||
#define GS_EXTBUF (*(volatile uint64*)0x120000b0)
|
||||
#define GS_EXTDATA (*(volatile uint64*)0x120000c0)
|
||||
#define GS_EXTWRITE (*(volatile uint64*)0x120000d0)
|
||||
#define GS_BGCOLOR (*(volatile uint64*)0x120000e0)
|
||||
#define GS_CSR (*(volatile uint64*)0x12001000)
|
||||
#define GS_IMR (*(volatile uint64*)0x12001010)
|
||||
#define GS_BUSDIR (*(volatile uint64*)0x12001040)
|
||||
#define GS_SIGLBLID (*(volatile uint64*)0x12001080)
|
||||
23
vendor/librw/tools/ps2test/ps2.h
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#include <kernel.h>
|
||||
|
||||
typedef int quad __attribute__((mode(TI)));
|
||||
typedef int int128 __attribute__((mode(TI)));
|
||||
typedef unsigned int uquad __attribute__((mode(TI)));
|
||||
typedef unsigned int uint128 __attribute__((mode(TI)));
|
||||
|
||||
#define MAKE128(RES,MSB,LSB) \
|
||||
__asm__ ( "pcpyld %0, %1, %2" : "=r" (RES) : "r" ((uint64)MSB), "r" ((uint64)LSB))
|
||||
#define UINT64(LOW,HIGH) (((uint64)HIGH)<<32 | ((uint64)LOW))
|
||||
#define MAKEQ(RES,W0,W1,W2,W3) MAKE128(RES,UINT64(W2,W3),UINT64(W0,W1))
|
||||
|
||||
#define BIT64(v,s) (((uint64)(v)) << (s))
|
||||
|
||||
#include "mem.h"
|
||||
#include "gs.h"
|
||||
|
||||
extern uint128 packetbuf[128];
|
||||
|
||||
void waitDMA(volatile uint32 *chcr);
|
||||
void toGIF(void *src, int n);
|
||||
|
||||
void drawcube(void);
|
||||
93
vendor/librw/tools/ps2test/vu/defaultpipe.dsm
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
.global defaultPipe
|
||||
|
||||
.equ vertexTop, 0x3d0
|
||||
.equ numInAttribs, 4
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
.equ outSize, ((vertexTop-outBuf1-2)/2)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ lightMat, 0x3d0
|
||||
.equ ambientLight, 0x3d4
|
||||
.equ lightDir, 0x3d5
|
||||
|
||||
.equ matrix, 0x3f0
|
||||
.equ XYZScale, 0x3f7
|
||||
.equ XYZOffset, 0x3f8
|
||||
.equ gifTag, 0x3fa
|
||||
.equ matColor, 0x3fb
|
||||
.equ surfProps, 0x3fc
|
||||
|
||||
|
||||
.balign 16,0
|
||||
defaultPipe:
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
Start:
|
||||
#include "setup_persp.vu"
|
||||
Cnt:
|
||||
NOP XTOP VI02 ; input pointer
|
||||
NOP LQ VF01, gifTag(VI00)
|
||||
NOP XITOP VI01 ; vertex count
|
||||
NOP IADDIU VI05, VI00, 0x4000
|
||||
NOP IADD VI05, VI05, VI05
|
||||
NOP IOR VI05, VI05, VI01
|
||||
NOP SQ VF01, 0(VI12)
|
||||
NOP ISW.x VI05, 0(VI12)
|
||||
NOP IADDIU VI03, VI12, 1 ; output pointer
|
||||
NOP LQ VF18, lightMat(VI00)
|
||||
NOP LQ VF19, lightMat+1(VI00)
|
||||
NOP LQ VF20, lightMat+2(VI00)
|
||||
|
||||
Loop:
|
||||
NOP LQI VF01, (VI02++) ; vertex
|
||||
NOP LQI VF02, (VI02++) ; UV
|
||||
NOP LQI VF03, (VI02++) ; color
|
||||
NOP LQI VF04, (VI02++) ; normal
|
||||
|
||||
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
|
||||
MADDAx.xyw ACC, VF28, VF01x NOP
|
||||
MADDAy.xyw ACC, VF29, VF01y NOP
|
||||
MADDz.xyzw VF01, VF30, VF01z NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
|
||||
NOP NOP
|
||||
NOP DIV Q, VF00w, VF01w
|
||||
NOP WAITQ
|
||||
MULq VF01, VF01, Q NOP ; perspective division
|
||||
MULi VF04, VF04, I NOP ; scale normal
|
||||
NOP MR32.z VF02, VF00
|
||||
NOP NOP
|
||||
SUB.w VF01, VF01, VF01 NOP
|
||||
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
|
||||
MADDAy.xyz ACC, VF19, VF04y NOP
|
||||
MADDz.xyz VF04, VF20, VF04z NOP
|
||||
ADD.xyz VF01, VF01, VF25 NOP
|
||||
MULq VF02, VF02, Q NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
FTOI4 VF01, VF01 NOP
|
||||
NOP SQ VF04, -2(VI02) ; store normal
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP SQI VF02, (VI03++) ; STQ
|
||||
NOP SQI VF03, (VI03++) ; color
|
||||
NOP SQI VF01, (VI03++) ; vertex
|
||||
NOP IBNE VI01, VI00, Loop
|
||||
NOP NOP
|
||||
|
||||
#include "light.vu"
|
||||
|
||||
NOP XGKICK VI12
|
||||
NOP IADD VI15,VI00,VI12
|
||||
NOP IADD VI12,VI00,VI13
|
||||
NOP[E] IADD VI13,VI00,VI15
|
||||
NOP NOP
|
||||
NOP B Cnt
|
||||
NOP NOP
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
||||
94
vendor/librw/tools/ps2test/vu/light.vu
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
; Ambient light:
|
||||
NOP LQ VF26, ambientLight(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
Ambloop:
|
||||
NOP LQ VF03, 0(VI03) ; output color
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADD.xyz VF03, VF03, VF26 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Ambloop
|
||||
NOP SQ VF03, -numOutAttribs(VI03)
|
||||
; end amblight
|
||||
|
||||
; Direct Light
|
||||
NOP LQ VF26, lightDir(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP XTOP VI02
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
SUB.xyz VF26, VF00, VF26 NOP
|
||||
Dirloop:
|
||||
NOP LQ VF01, 3(VI02); ; normal
|
||||
NOP LQ VF02, 0(VI03); ; output color
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MUL VF03, VF01, VF26 NOP
|
||||
ITOF0 VF02, VF02 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDy.x VF03, VF03, VF03y NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDz.x VF03, VF03, VF03z NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MAX.x VF03, VF00, VF03 NOP ; clamp to 0
|
||||
NOP[I] LOI 255
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MULi.x VF03, VF03, I NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDx.xyz VF02, VF02, VF03x NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF02, VF02 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI02, VI02, numInAttribs
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Dirloop
|
||||
NOP SQ VF02, -numOutAttribs(VI03)
|
||||
; end dirlight
|
||||
|
||||
; Material color and clamp
|
||||
NOP LQ VF27, matColor(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
Colorloop:
|
||||
NOP LQ VF03, 0(VI03)
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MUL VF03, VF03, VF27 NOP
|
||||
NOP[I] LOI 255
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MINIi VF03, VF03, I NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Colorloop
|
||||
NOP SQ VF03, -numOutAttribs(VI03)
|
||||
; end material color
|
||||
39
vendor/librw/tools/ps2test/vu/setup_persp.vu
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* This is the the projection matrix we start with:
|
||||
* 1/2w 0 ox/2w + 1/2 -ox/2w
|
||||
* 0 -1/2h -oy/2h + 1/2 oy/2h
|
||||
* 0 0 1 0
|
||||
* 0 0 1 0
|
||||
* To get rid of the +1/2 in the combined matrix we
|
||||
* subtract the z-row/2 from the x- and y-rows.
|
||||
*
|
||||
* The z-row is then set to [0 0 0 1] such that multiplication
|
||||
* by XYZscale gives [0 0 0 zScale]. After perspective division
|
||||
* and addition of XYZoffset we then get zScale/w + zShift for z.
|
||||
*
|
||||
* XYZScale scales xy to the resolution and z by zScale.
|
||||
* XYZOffset translates xy to the GS coordinate system (where
|
||||
* [2048, 2048] is the center of the frame buffer) and add zShift to z.
|
||||
*/
|
||||
|
||||
; constant:
|
||||
; VF28-VF31 transformation matrix
|
||||
; VF25 XYZ offset
|
||||
|
||||
|
||||
SUB.z VF28, VF28, VF28 LOI 0.5 ; right.z = 0
|
||||
SUB.z VF29, VF29, VF29 LQ VF28, matrix(VI00) ; up.z = 0 - load matrix
|
||||
SUB.z VF30, VF30, VF30 LQ VF29, matrix+1(VI00) ; at.z = 0 - load matrix
|
||||
ADDw.z VF31, VF00, VF00 LQ VF30, matrix+2(VI00) ; at.z = 1 - load matrix
|
||||
NOP LQ VF31, matrix+3(VI00) ; - load matrix
|
||||
MULi.w VF20, VF28, I LQ.xyz VF01, XYZScale(VI00) ; fix matrix - load scale
|
||||
MULi.w VF21, VF29, I NOP ; fix matrix
|
||||
MULi.w VF22, VF30, I NOP ; fix matrix
|
||||
MULi.w VF23, VF31, I NOP ; fix matrix
|
||||
SUBw.xy VF28, VF28, VF20 NOP ; fix matrix
|
||||
SUBw.xy VF29, VF29, VF21 NOP ; fix matrix
|
||||
SUBw.xy VF30, VF30, VF22 NOP ; fix matrix
|
||||
SUBw.xy VF31, VF31, VF23 NOP ; fix matrix
|
||||
MUL.xy VF28, VF28, VF01 LQ.xyz VF25, XYZOffset(VI00) ; scale matrix
|
||||
MUL.xy VF29, VF29, VF01 IADDIU VI12, VI00, outBuf1 ; scale matrix
|
||||
MUL.xy VF30, VF30, VF01 IADDIU VI13, VI00, outBuf2 ; scale matrix
|
||||
MUL.xyz VF31, VF31, VF01 NOP ; scale matrix
|
||||
94
vendor/librw/tools/ps2test/vu/skinpipe.dsm
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
.global skinPipe
|
||||
|
||||
.equ vertexTop, 0x2d0
|
||||
.equ numInAttribs, 5
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
.equ outSize, ((vertexTop-outBuf1-2)/2)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ lightMat, 0x3d0
|
||||
.equ ambientLight, 0x3d4
|
||||
.equ lightDir, 0x3d5
|
||||
|
||||
.equ matrix, 0x3f0
|
||||
.equ XYZScale, 0x3f7
|
||||
.equ XYZOffset, 0x3f8
|
||||
.equ gifTag, 0x3fa
|
||||
.equ matColor, 0x3fb
|
||||
.equ surfProps, 0x3fc
|
||||
|
||||
|
||||
.balign 16,0
|
||||
skinPipe:
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
Start:
|
||||
#include "setup_persp.vu"
|
||||
Cnt:
|
||||
NOP XTOP VI02 ; input pointer
|
||||
NOP LQ VF01, gifTag(VI00)
|
||||
NOP XITOP VI01 ; vertex count
|
||||
NOP IADDIU VI05, VI00, 0x4000
|
||||
NOP IADD VI05, VI05, VI05
|
||||
NOP IOR VI05, VI05, VI01
|
||||
NOP SQ VF01, 0(VI12)
|
||||
NOP ISW.x VI05, 0(VI12)
|
||||
NOP IADDIU VI03, VI12, 1 ; output pointer
|
||||
NOP LQ VF18, lightMat(VI00)
|
||||
NOP LQ VF19, lightMat+1(VI00)
|
||||
NOP LQ VF20, lightMat+2(VI00)
|
||||
|
||||
Loop:
|
||||
NOP LQI VF01, (VI02++) ; vertex
|
||||
NOP LQI VF02, (VI02++) ; UV
|
||||
NOP LQI VF03, (VI02++) ; color
|
||||
NOP LQI VF04, (VI02++) ; normal
|
||||
NOP IADDIU VI02, VI02, 1 ; skip weights
|
||||
|
||||
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
|
||||
MADDAx.xyw ACC, VF28, VF01x NOP
|
||||
MADDAy.xyw ACC, VF29, VF01y NOP
|
||||
MADDz.xyzw VF01, VF30, VF01z NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
|
||||
NOP NOP
|
||||
NOP DIV Q, VF00w, VF01w
|
||||
NOP WAITQ
|
||||
MULq VF01, VF01, Q NOP ; perspective division
|
||||
MULi VF04, VF04, I NOP ; scale normal
|
||||
NOP MR32.z VF02, VF00
|
||||
NOP NOP
|
||||
SUB.w VF01, VF01, VF01 NOP
|
||||
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
|
||||
MADDAy.xyz ACC, VF19, VF04y NOP
|
||||
MADDz.xyz VF04, VF20, VF04z NOP
|
||||
ADD.xyz VF01, VF01, VF25 NOP
|
||||
MULq VF02, VF02, Q NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
FTOI4 VF01, VF01 NOP
|
||||
NOP SQ VF04, -2(VI02) ; store normal
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP SQI VF02, (VI03++) ; STQ
|
||||
NOP SQI VF03, (VI03++) ; color
|
||||
NOP SQI VF01, (VI03++) ; vertex
|
||||
NOP IBNE VI01, VI00, Loop
|
||||
NOP NOP
|
||||
|
||||
#include "light.vu"
|
||||
|
||||
NOP XGKICK VI12
|
||||
NOP IADD VI15,VI00,VI12
|
||||
NOP IADD VI12,VI00,VI13
|
||||
NOP[E] IADD VI13,VI00,VI15
|
||||
NOP NOP
|
||||
NOP B Cnt
|
||||
NOP NOP
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
||||
16
vendor/librw/tools/ska2anm/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
add_executable(ska2anm
|
||||
ska2anm.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(ska2anm
|
||||
PUBLIC
|
||||
librw::librw
|
||||
)
|
||||
|
||||
librw_platform_target(ska2anm INSTALL)
|
||||
|
||||
if(LIBRW_INSTALL)
|
||||
install(TARGETS ska2anm
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
83
vendor/librw/tools/ska2anm/ska2anm.cpp
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <rw.h>
|
||||
#include <args.h>
|
||||
|
||||
using namespace rw;
|
||||
|
||||
char *argv0;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s in.ska [out.anm]\n", argv0);
|
||||
fprintf(stderr, " or: %s in.anm [out.ska]\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
rw::Engine::init();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::Engine::open(nil);
|
||||
rw::Engine::start();
|
||||
|
||||
ARGBEGIN{
|
||||
case 'v':
|
||||
sscanf(EARGF(usage()), "%x", &rw::version);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND;
|
||||
|
||||
if(argc < 1)
|
||||
usage();
|
||||
|
||||
StreamFile stream;
|
||||
if(!stream.open(argv[0], "rb")){
|
||||
fprintf(stderr, "Error: couldn't open %s\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 firstword = stream.readU32();
|
||||
stream.seek(0, 0);
|
||||
Animation *anim = nil;
|
||||
if(firstword == ID_ANIMANIMATION){
|
||||
// it's an anm file
|
||||
if(findChunk(&stream, ID_ANIMANIMATION, nil, nil))
|
||||
anim = Animation::streamRead(&stream);
|
||||
}else{
|
||||
// it's a ska file
|
||||
anim = Animation::streamReadLegacy(&stream);
|
||||
}
|
||||
stream.close();
|
||||
|
||||
if(anim == nil){
|
||||
fprintf(stderr, "Error: couldn't read anim file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *file;
|
||||
if(argc > 1)
|
||||
file = argv[1];
|
||||
else if(firstword == ID_ANIMANIMATION)
|
||||
file = "out.ska";
|
||||
else
|
||||
file = "out.anm";
|
||||
if(!stream.open(file, "wb")){
|
||||
fprintf(stderr, "Error: couldn't open %s\n", file);
|
||||
return 1;
|
||||
}
|
||||
if(firstword == ID_ANIMANIMATION)
|
||||
anim->streamWriteLegacy(&stream);
|
||||
else
|
||||
anim->streamWrite(&stream);
|
||||
|
||||
anim->destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
vendor/librw/tools/subrast/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
add_executable(subrast WIN32
|
||||
main.cpp
|
||||
subrast.cpp
|
||||
subrast.h
|
||||
)
|
||||
|
||||
target_link_libraries(subrast
|
||||
PUBLIC
|
||||
librw::skeleton
|
||||
librw::librw
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET subrast POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:subrast>/files"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/files" "$<TARGET_FILE_DIR:subrast>/files"
|
||||
)
|
||||
|
||||
librw_platform_target(subrast)
|
||||
BIN
vendor/librw/tools/subrast/files/clump.dff
vendored
Normal file
BIN
vendor/librw/tools/subrast/files/textures/whiteash.png
vendored
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
354
vendor/librw/tools/subrast/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "subrast.h"
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
rw::EngineOpenParams engineOpenParams;
|
||||
float FOV = 70.0f;
|
||||
|
||||
rw::RGBA ForegroundColor = { 200, 200, 200, 255 };
|
||||
rw::RGBA BackgroundColor = { 64, 64, 64, 0 };
|
||||
rw::RGBA BorderColor = { 128, 128, 128, 0 };
|
||||
|
||||
rw::Clump *Clump = nil;
|
||||
rw::Light *MainLight = nil;
|
||||
rw::Light *AmbientLight = nil;
|
||||
|
||||
rw::World *World;
|
||||
rw::Charset *Charset;
|
||||
|
||||
const char *SubCameraCaption[4] = {
|
||||
"Perspective view",
|
||||
"Parallel view: Z-axis",
|
||||
"Parallel view: X-axis",
|
||||
"Parallel view: Y-axis"
|
||||
};
|
||||
|
||||
rw::V3d Xaxis = { 1.0f, 0.0, 0.0f };
|
||||
rw::V3d Yaxis = { 0.0f, 1.0, 0.0f };
|
||||
rw::V3d Zaxis = { 0.0f, 0.0, 1.0f };
|
||||
|
||||
rw::World*
|
||||
CreateWorld(void)
|
||||
{
|
||||
rw::BBox bb;
|
||||
|
||||
bb.inf.x = bb.inf.y = bb.inf.z = -100.0f;
|
||||
bb.sup.x = bb.sup.y = bb.sup.z = 100.0f;
|
||||
|
||||
return rw::World::create(&bb);
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateAmbientLight(rw::World *world)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::AMBIENT);
|
||||
assert(light);
|
||||
World->addLight(light);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Light*
|
||||
CreateMainLight(rw::World *world)
|
||||
{
|
||||
rw::Light *light = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
assert(light);
|
||||
rw::Frame *frame = rw::Frame::create();
|
||||
assert(frame);
|
||||
frame->rotate(&Xaxis, 30.0f, rw::COMBINEREPLACE);
|
||||
frame->rotate(&Yaxis, 30.0f, rw::COMBINEPOSTCONCAT);
|
||||
light->setFrame(frame);
|
||||
World->addLight(light);
|
||||
return light;
|
||||
}
|
||||
|
||||
rw::Clump*
|
||||
CreateClump(rw::World *world)
|
||||
{
|
||||
rw::Clump *clump;
|
||||
rw::StreamFile in;
|
||||
|
||||
rw::Image::setSearchPath("files/textures/");
|
||||
const char *filename = "files/clump.dff";
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return nil;
|
||||
}
|
||||
if(!rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL))
|
||||
return nil;
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
in.close();
|
||||
if(clump == nil)
|
||||
return nil;
|
||||
|
||||
rw::Frame *frame = clump->getFrame();
|
||||
frame->rotate(&Xaxis, -120.0f, rw::COMBINEREPLACE);
|
||||
frame->rotate(&Yaxis, 45.0f, rw::COMBINEPOSTCONCAT);
|
||||
World->addClump(clump);
|
||||
return clump;
|
||||
}
|
||||
|
||||
void
|
||||
RotateClump(float xAngle, float yAngle)
|
||||
{
|
||||
rw::Matrix *cameraMatrix = &Camera->getFrame()->matrix;
|
||||
rw::Frame *frame = Clump->getFrame();
|
||||
rw::V3d pos = frame->matrix.pos;
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
frame->rotate(&cameraMatrix->up, xAngle, rw::COMBINEPOSTCONCAT);
|
||||
frame->rotate(&cameraMatrix->right, yAngle, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
pos = rw::scale(pos, -1.0f);
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
Initialize(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Sub-raster example";
|
||||
sk::globals.width = 1280;
|
||||
sk::globals.height = 800;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Initialize3D(void)
|
||||
{
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
Charset = rw::Charset::create(&ForegroundColor, &BackgroundColor);
|
||||
|
||||
World = CreateWorld();
|
||||
|
||||
AmbientLight = CreateAmbientLight(World);
|
||||
MainLight = CreateMainLight(World);
|
||||
Clump = CreateClump(World);
|
||||
if (Clump == nil)
|
||||
return false;
|
||||
|
||||
CreateCameras(World);
|
||||
UpdateSubRasters(Camera, sk::globals.width, sk::globals.height);
|
||||
|
||||
rw::SetRenderState(rw::CULLMODE, rw::CULLBACK);
|
||||
rw::SetRenderState(rw::ZTESTENABLE, 1);
|
||||
rw::SetRenderState(rw::ZWRITEENABLE, 1);
|
||||
|
||||
ImGui_ImplRW_Init();
|
||||
ImGui::StyleColorsClassic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Terminate3D(void)
|
||||
{
|
||||
DestroyCameras(World);
|
||||
|
||||
if(AmbientLight){
|
||||
World->removeLight(AmbientLight);
|
||||
AmbientLight->destroy();
|
||||
AmbientLight = nil;
|
||||
}
|
||||
|
||||
if(MainLight){
|
||||
World->removeLight(MainLight);
|
||||
rw::Frame *frame = MainLight->getFrame();
|
||||
MainLight->setFrame(nil);
|
||||
frame->destroy();
|
||||
MainLight->destroy();
|
||||
MainLight = nil;
|
||||
}
|
||||
|
||||
if(Clump){
|
||||
World->removeClump(Clump);
|
||||
Clump->destroy();
|
||||
Clump = nil;
|
||||
}
|
||||
|
||||
if(World){
|
||||
World->destroy();
|
||||
World = nil;
|
||||
}
|
||||
|
||||
if(Charset){
|
||||
Charset->destroy();
|
||||
Charset = nil;
|
||||
}
|
||||
|
||||
sk::TerminateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerUserDataPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DisplayOnScreenInfo(void)
|
||||
{
|
||||
for(int i = 0; i < 4; i++){
|
||||
rw::Raster *scr = SubCameras[i]->frameBuffer;
|
||||
|
||||
rw::int32 scrw = scr->width;
|
||||
rw::int32 scrh = scr->height;
|
||||
|
||||
rw::int32 captionWidth = strlen(SubCameraCaption[i])*Charset->desc.width;
|
||||
|
||||
if(captionWidth < scrw && scrh > Charset->desc.height*2){
|
||||
rw::int32 x = scr->offsetX + (scrw - captionWidth)/2;
|
||||
rw::int32 y = scr->offsetY + Charset->desc.height;
|
||||
Charset->print(SubCameraCaption[i], x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rw::RGBA BackgroundColors[] = {
|
||||
{ 64, 64, 64, 0 },
|
||||
{ 128, 0, 0, 0 },
|
||||
{ 0, 128, 0, 0 },
|
||||
{ 0, 0, 128, 0 },
|
||||
};
|
||||
void
|
||||
Render(float timeDelta)
|
||||
{
|
||||
Camera->clear(&BorderColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
SubCameras[i]->clear(&BackgroundColor, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
// SubCameras[i]->clear(&BackgroundColors[i], rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
SubCameras[i]->beginUpdate();
|
||||
World->render();
|
||||
SubCameras[i]->endUpdate();
|
||||
}
|
||||
|
||||
Camera->beginUpdate();
|
||||
DisplayOnScreenInfo();
|
||||
Camera->endUpdate();
|
||||
|
||||
Camera->showRaster(0);
|
||||
}
|
||||
|
||||
void
|
||||
Idle(float timeDelta)
|
||||
{
|
||||
Render(timeDelta);
|
||||
}
|
||||
|
||||
int MouseX, MouseY;
|
||||
int MouseDeltaX, MouseDeltaY;
|
||||
int MouseButtons;
|
||||
|
||||
bool Rotating;
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MouseBtn(sk::MouseState *mouse)
|
||||
{
|
||||
MouseButtons = mouse->buttons;
|
||||
Rotating = !!(MouseButtons&1);
|
||||
}
|
||||
|
||||
void
|
||||
MouseMove(sk::MouseState *mouse)
|
||||
{
|
||||
MouseDeltaX = mouse->posx - MouseX;
|
||||
MouseDeltaY = mouse->posy - MouseY;
|
||||
MouseX = mouse->posx;
|
||||
MouseY = mouse->posy;
|
||||
if(Rotating)
|
||||
RotateClump(-MouseDeltaX, MouseDeltaY);
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
Rect *r;
|
||||
MouseState *ms;
|
||||
|
||||
ImGuiEventHandler(e, param);
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Initialize();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return Initialize3D() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
Terminate3D();
|
||||
return EVENTPROCESSED;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEBTN:
|
||||
if(!io.WantCaptureMouse){
|
||||
ms = (MouseState*)param;
|
||||
MouseBtn(ms);
|
||||
}else
|
||||
MouseButtons = 0;
|
||||
return EVENTPROCESSED;
|
||||
case MOUSEMOVE:
|
||||
MouseMove((MouseState*)param);
|
||||
return EVENTPROCESSED;
|
||||
case RESIZE:
|
||||
r = (Rect*)param;
|
||||
// TODO: register when we're minimized
|
||||
if(r->w == 0) r->w = 1;
|
||||
if(r->h == 0) r->h = 1;
|
||||
|
||||
sk::globals.width = r->w;
|
||||
sk::globals.height = r->h;
|
||||
if(::Camera){
|
||||
sk::CameraSize(::Camera, r);
|
||||
::Camera->setFOV(FOV, (float)sk::globals.width/sk::globals.height);
|
||||
|
||||
UpdateSubRasters(::Camera, r->w, r->h);
|
||||
}
|
||||
break;
|
||||
case IDLE:
|
||||
Idle(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
||||
141
vendor/librw/tools/subrast/subrast.cpp
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
|
||||
#include "subrast.h"
|
||||
|
||||
rw::Camera *Camera;
|
||||
rw::Camera *SubCameras[4];
|
||||
|
||||
void
|
||||
CameraSetViewWindow(rw::Camera *camera, float width, float height, float vw)
|
||||
{
|
||||
rw::V2d viewWindow;
|
||||
|
||||
// TODO: aspect ratio when fullscreen
|
||||
if(width > height){
|
||||
viewWindow.x = vw;
|
||||
viewWindow.y = vw / (width/height);
|
||||
}else{
|
||||
viewWindow.x = vw / (height/width);
|
||||
viewWindow.y = vw;
|
||||
}
|
||||
|
||||
camera->setViewWindow(&viewWindow);
|
||||
}
|
||||
|
||||
void
|
||||
UpdateSubRasters(rw::Camera *mainCamera, rw::int32 mainWidth, rw::int32 mainHeight)
|
||||
{
|
||||
rw::Rect rect[4];
|
||||
float width, height, border;
|
||||
|
||||
border = mainHeight*0.05f;
|
||||
|
||||
width = (mainWidth - border*3.0f) / 2.0f;
|
||||
height = (mainHeight - border*3.0f) / 2.0f;
|
||||
|
||||
// top left
|
||||
rect[0].x = border;
|
||||
rect[0].y = border;
|
||||
rect[0].w = width;
|
||||
rect[0].h = height;
|
||||
|
||||
// top right
|
||||
rect[1].x = border*2 + width;
|
||||
rect[1].y = border;
|
||||
rect[1].w = width;
|
||||
rect[1].h = height;
|
||||
|
||||
// bottom left
|
||||
rect[2].x = border;
|
||||
rect[2].y = border*2 + height;
|
||||
rect[2].w = width;
|
||||
rect[2].h = height;
|
||||
|
||||
// bottom left
|
||||
rect[3].x = border*2 + width;
|
||||
rect[3].y = border*2 + height;
|
||||
rect[3].w = width;
|
||||
rect[3].h = height;
|
||||
|
||||
CameraSetViewWindow(SubCameras[0], width, height, 0.5f);
|
||||
for(int i = 1; i < 4; i++)
|
||||
CameraSetViewWindow(SubCameras[i], width, height, 0.5f + 0.4f);
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
SubCameras[i]->frameBuffer->subRaster(mainCamera->frameBuffer, &rect[i]);
|
||||
SubCameras[i]->zBuffer->subRaster(mainCamera->zBuffer, &rect[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PositionSubCameras(void)
|
||||
{
|
||||
rw::Frame *frame;
|
||||
rw::V3d pos;
|
||||
const float dist = 2.5f;
|
||||
|
||||
// perspective
|
||||
pos.x = pos.y = 0.0f;
|
||||
pos.z = -4.0f;
|
||||
frame = SubCameras[0]->getFrame();
|
||||
frame->translate(&pos, rw::COMBINEREPLACE);
|
||||
|
||||
// look along z
|
||||
pos.x = pos.y = 0.0f;
|
||||
pos.z = -dist;
|
||||
frame = SubCameras[1]->getFrame();
|
||||
frame->translate(&pos, rw::COMBINEREPLACE);
|
||||
|
||||
// look along x
|
||||
pos.x = -dist;
|
||||
pos.y = pos.z = 0.0f;
|
||||
frame = SubCameras[2]->getFrame();
|
||||
frame->rotate(&Yaxis, 90.0f, rw::COMBINEREPLACE);
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
|
||||
// look along y
|
||||
pos.x = pos.z = 0.0f;
|
||||
pos.y = -dist;
|
||||
frame = SubCameras[3]->getFrame();
|
||||
frame->rotate(&Xaxis, -90.0f, rw::COMBINEREPLACE);
|
||||
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
||||
}
|
||||
|
||||
void
|
||||
CreateCameras(rw::World *world)
|
||||
{
|
||||
Camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||
assert(Camera);
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
SubCameras[i] = sk::CameraCreate(0, 0, 1);
|
||||
assert(SubCameras[i]);
|
||||
|
||||
SubCameras[i]->setNearPlane(0.1f);
|
||||
SubCameras[i]->setFarPlane(30.0f);
|
||||
|
||||
world->addCamera(SubCameras[i]);
|
||||
|
||||
if(i > 0)
|
||||
SubCameras[i]->setProjection(rw::Camera::PARALLEL);
|
||||
}
|
||||
|
||||
PositionSubCameras();
|
||||
}
|
||||
|
||||
void
|
||||
DestroyCameras(rw::World *world)
|
||||
{
|
||||
if(Camera){
|
||||
sk::CameraDestroy(Camera);
|
||||
Camera = nil;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(SubCameras[i]){
|
||||
world->removeCamera(SubCameras[i]);
|
||||
sk::CameraDestroy(SubCameras[i]);
|
||||
SubCameras[i] = nil;
|
||||
}
|
||||
}
|
||||
10
vendor/librw/tools/subrast/subrast.h
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
extern rw::Camera *Camera;
|
||||
extern rw::Camera *SubCameras[4];
|
||||
|
||||
void CreateCameras(rw::World *world);
|
||||
void DestroyCameras(rw::World *world);
|
||||
void UpdateSubRasters(rw::Camera *mainCamera, rw::int32 mainWidth, rw::int32 mainHeight);
|
||||
|
||||
extern rw::V3d Xaxis;
|
||||
extern rw::V3d Yaxis;
|
||||
extern rw::V3d Zaxis;
|
||||