FREESCAPE: refactoring detection code and first attempt to render cubes

This commit is contained in:
neuromancer
2022-11-06 21:59:39 +01:00
committed by Eugene Sandulenko
parent 5fa47a0188
commit 8bdfd73559
8 changed files with 184 additions and 202 deletions
+19 -23
View File
@@ -92,34 +92,30 @@ Area::~Area() {
}*/
void Area::draw(Freescape::Renderer *gfx) {
Graphics::PixelBuffer *palette;
if (gfx->_palette)
palette = gfx->_palette;
else if (raw_palette) {
palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO);
*palette = raw_palette->data();
}
// Graphics::PixelBuffer *palette;
// if (gfx->_palette)
// palette = gfx->_palette;
// else if (raw_palette) {
// palette = new Graphics::PixelBuffer(gfx->_palettePixelFormat, 16, DisposeAfterUse::NO);
// *palette = raw_palette->data();
// }
gfx->selectTargetWindow(nullptr, false, true);
debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
//Common::Rect view(20, 30, 305, 110);
Common::Rect view = gfx->rviewport();
Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
uint8 r, g, b;
palette->getRGBAt(skyColor, r, g, b);
debug("color: %d %x%x%x", skyColor, g, b);
gfx->drawRect2D(sky, 255, r, g, b);
//gfx->selectTargetWindow(nullptr, false, true);
// debug("w: %d, h: %d", gfx->kOriginalWidth, gfx->kOriginalHeight);
// //Common::Rect view(20, 30, 305, 110);
// Common::Rect view = gfx->rviewport();
// Common::Rect sky(view.left, view.top, view.right, view.bottom-view.height()/2);
//debug("color: %d %x%x%x", skyColor, g, b);
gfx->drawSky(skyColor);
Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
palette->getRGBAt(groundColor, r, g, b);
debug("color: %d %x%x%x", groundColor, g, b);
gfx->drawRect2D(ground, 255, r, g, b);
// Common::Rect ground(view.left, view.top+view.height()/2, view.right, view.bottom);
// palette->getRGBAt(groundColor, r, g, b);
// debug("color: %d %x%x%x", groundColor, g, b);
// gfx->drawRect2D(ground, 255, r, g, b);
//gfx->drawTriange(); // I have no idea why?
for (Common::Array<Object *>::iterator iterator = drawableObjects.begin(); iterator != drawableObjects.end(); iterator++) {
(*iterator)->draw(gfx);
}
gfx->flipBuffer();
g_system->updateScreen();
}
+1 -1
View File
@@ -25,7 +25,7 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_NO_FLAGS,
GUIO1(GUIO_NOMIDI)},
{"3Dkit",
{"3dkit",
"One cube in scene",
AD_ENTRY1s("CUBE.RUN", "3b7930be0f646b98885cfb70c26c89a2", 66138),
Common::EN_ANY,
+36 -17
View File
@@ -36,10 +36,10 @@ FreescapeEngine::FreescapeEngine(OSystem *syst)
_hasReceivedTime = false;
_rotation = Vector3d(0.f, 0.f, 0.f);
_position = Vector3d(1000.0f, 0.0f, 1000.0f);
_position = Vector3d(4000.f, 30.f, 4000.f);
_velocity = Vector3d(0.0f, 0.0f, 0.0f);
_front = Vector3d(0.0f, 0.0f, 0.0f);
_right = Vector3d(0.0f, 0.0f, 0.0f);
_cameraFront = Vector3d(0.0f, 0.0f, 0.0f);
_cameraRight = Vector3d(0.0f, 0.0f, 0.0f);
_yaw = 90.0f;
_pitch = 0.0f;
@@ -146,15 +146,32 @@ Common::Error FreescapeEngine::run() {
area = (*_areasByAreaID)[_startArea];
assert(area);
//_gfx->renderPalette(area->raw_palette, binary.ncolors);
drawBorder();
//drawBorder();
}
debug("FreescapeEngine::init");
// Simple main event loop
Common::Event event;
Common::Point lastMousePos(0, 0);
float lastFrame = 0.f;
float nearClipPlane = 1.f;
float farClipPlane;
if (_binaryBits == 16) {
// create a projection matrix; the 16-bit kit permits the range 0-8192 to
// be used along all three axes and from that comes the far plane distance
// of 14189.
farClipPlane = 14189.0f;
} else {
error("Unknown farClipPlane");
}
g_system->lockMouse(true);
while (!shouldQuit()) {
_gfx->updateProjectionMatrix(40.0, nearClipPlane, farClipPlane);
_gfx->positionCamera(_position, _position + _cameraFront);
//_gfx->selectTargetWindow(nullptr, true, false);
//_gfx->updateMatrices();
area->draw(_gfx);
float currentFrame = g_system->getMillis();
float deltaTime = currentFrame - lastFrame;
@@ -193,6 +210,8 @@ Common::Error FreescapeEngine::run() {
}
}
_gfx->flipBuffer();
g_system->updateScreen();
g_system->delayMillis(10);
}
@@ -211,10 +230,10 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
_pitch += yoffset;
// Make sure that when pitch is out of bounds, screen doesn't get flipped
if (_pitch > 89.0f)
_pitch = 89.0f;
if (_pitch < -89.0f)
_pitch = -89.0f;
if (_pitch > 180.0f)
_pitch = 180.0f;
if (_pitch < -180.0f)
_pitch = -180.0f;
Vector3d v;
float x = cos(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
@@ -222,34 +241,34 @@ void FreescapeEngine::rotate(Common::Point lastMousePos, Common::Point mousePos)
float z = sin(_yaw * M_PI / 180.0) * cos(_pitch * M_PI / 180.0);
v.set(x, y, z);
v.normalize();
_front = v;
_cameraFront = v;
// _right = _front x _up;
// // _right = _front x _up;
Vector3d up(0, 1, 0); // this should be const
v = Math::Vector3d::crossProduct(_front, up);
v = Math::Vector3d::crossProduct(_cameraFront, up);
v.normalize();
_right = v;
_cameraRight = v;
}
void FreescapeEngine::move(CameraMovement direction, float deltaTime) {
float velocity = _movementSpeed * deltaTime;
switch (direction) {
case FORWARD:
_position = _position + _front * velocity;
_position = _position + _cameraFront * velocity;
break;
case BACKWARD:
_position = _position - _front * velocity;
_position = _position - _cameraFront * velocity;
break;
case RIGHT:
_position = _position + _right * velocity;
_position = _position + _cameraRight * velocity;
break;
case LEFT:
_position = _position - _right * velocity;
_position = _position - _cameraRight * velocity;
break;
}
// Make sure the user stays at the ground level
// this one-liner keeps the user at the ground level (xz plane)
_position.set(_position.x(), 0, _position.z());
_position.set(_position.x(), 60., _position.z());
}
bool FreescapeEngine::hasFeature(EngineFeature f) const {
+2 -1
View File
@@ -86,7 +86,8 @@ public:
// Camera options
float _mouseSensitivity;
float _movementSpeed;
Vector3d _front, _right;
Vector3d _cameraFront, _cameraUp, _cameraRight;
// Spacial attributes
Vector3d _position, _rotation, _velocity;
+13 -74
View File
@@ -69,39 +69,6 @@ Graphics::Surface *Renderer::convertFromPalette(Graphics::PixelBuffer *rawsurf)
return surf;
}
void Renderer::renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors) {
Graphics::PixelBuffer *palette;
if (_palette)
palette = _palette;
else if (raw_palette) {
palette = new Graphics::PixelBuffer(_palettePixelFormat, 16, DisposeAfterUse::NO);
*palette = raw_palette->data();
} else
error("No palette to show");
selectTargetWindow(nullptr, false, true);
Common::Rect view = viewport();
uint8 r, g, b;
uint16 c;
uint16 top = view.top;
uint16 size = kOriginalHeight/ncolors;
uint16 bottom = size;
for (c = 0; c < ncolors; c++) {
view = Common::Rect(view.left, top, view.right, bottom);
palette->getRGBAt(c, r, g, b);
debug("color: %d %x %x %x", c, r, g, b);
drawRect2D(view, 255, r, g, b);
bottom = bottom + size;
top = top + size;
}
flipBuffer();
g_system->updateScreen();
}
Common::Rect Renderer::getFontCharacterRect(uint8 character) {
uint index = 0;
@@ -153,34 +120,6 @@ void Renderer::computeScreenViewport() {
//}
}
Math::Matrix4 Renderer::makeProjectionMatrix(float fov) const {
static const float nearClipPlane = 1.0;
static const float farClipPlane = 10000.0;
float aspectRatio = kOriginalWidth / (float) kFrameHeight;
float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
float ymaxValue = xmaxValue / aspectRatio;
return Math::makeFrustumMatrix(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
}
void Renderer::setupCameraPerspective(float pitch, float heading, float fov) {
_projectionMatrix = makeProjectionMatrix(fov);
_modelViewMatrix = Math::Matrix4(180.0f - heading, pitch, 0.0f, Math::EO_YXZ);
Math::Matrix4 proj = _projectionMatrix;
Math::Matrix4 model = _modelViewMatrix;
proj.transpose();
model.transpose();
_mvpMatrix = proj * model;
_frustum.setup(_mvpMatrix);
_mvpMatrix.transpose();
}
Renderer *createRenderer(OSystem *system) {
Common::String rendererConfig = ConfMan.get("renderer");
Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
@@ -232,22 +171,22 @@ Renderer *createRenderer(OSystem *system) {
}
void Renderer::renderDrawable(Drawable *drawable, Window *window) {
if (drawable->isConstrainedToWindow()) {
selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
} else {
selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
}
drawable->draw();
// if (drawable->isConstrainedToWindow()) {
// selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
// } else {
// selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
// }
// drawable->draw();
}
void Renderer::renderDrawableOverlay(Drawable *drawable, Window *window) {
// Overlays are always 2D
if (drawable->isConstrainedToWindow()) {
selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
} else {
selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
}
drawable->drawOverlay();
// // Overlays are always 2D
// if (drawable->isConstrainedToWindow()) {
// selectTargetWindow(window, drawable->is3D(), drawable->isScaled());
// } else {
// selectTargetWindow(nullptr, drawable->is3D(), drawable->isScaled());
// }
// drawable->drawOverlay();
}
void Renderer::renderWindow(Window *window) {
+4 -12
View File
@@ -121,11 +121,6 @@ public:
Graphics::Surface *convertFromPalette(Graphics::PixelBuffer *rawsurf);
/**
* Show palette on screen
*/
void renderPalette(Common::Array<uint8> *raw_palette, uint16 ncolors);
virtual void init() = 0;
virtual void clear() = 0;
@@ -147,7 +142,7 @@ public:
virtual void draw2DText(const Common::String &text, const Common::Point &position) = 0;
virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) = 0;
virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) = 0;
virtual void drawSky(uint8 color) = 0;
/** Render a Drawable in the specified window */
void renderDrawable(Drawable *drawable, Window *window);
@@ -170,11 +165,9 @@ public:
*
* This also sets the viewport
*/
virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) = 0;
void setupCameraPerspective(float pitch, float heading, float fov);
bool isCubeFaceVisible(uint face);
virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) = 0;
virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) = 0;
Math::Matrix4 getMvpMatrix() const { return _mvpMatrix; }
@@ -204,8 +197,7 @@ protected:
Math::AABB _cubeFacesAABB[6];
Common::Rect getFontCharacterRect(uint8 character);
Math::Matrix4 makeProjectionMatrix(float fov) const;
Math::Matrix4 makeProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) const;
};
/**
+106 -72
View File
@@ -74,7 +74,7 @@ void TinyGLRenderer::init() {
tglLoadIdentity();
tglDisable(TGL_LIGHTING);
tglEnable(TGL_TEXTURE_2D);
tglDisable(TGL_TEXTURE_2D);
tglEnable(TGL_DEPTH_TEST);
}
@@ -83,58 +83,6 @@ void TinyGLRenderer::clear() {
tglColor3f(1.0f, 1.0f, 1.0f);
}
void TinyGLRenderer::selectTargetWindow(Window *window, bool is3D, bool scaled) {
// NOTE: tinyGL viewport implementation needs to be checked as it doesn't behave the same as openGL
if (!window) {
// No window found ...
if (scaled) {
// ... in scaled mode draw in the original game screen area
Common::Rect vp = viewport();
tglViewport(vp.left, vp.top, vp.width(), vp.height());
//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
} else {
// ... otherwise, draw on the whole screen
tglViewport(0, 0, _system->getWidth(), _system->getHeight());
}
} else {
// Found a window, draw inside it
Common::Rect vp = window->getPosition();
tglViewport(vp.left, vp.top, vp.width(), vp.height());
//tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
}
if (is3D) {
tglMatrixMode(TGL_PROJECTION);
tglLoadMatrixf(_projectionMatrix.getData());
tglMatrixMode(TGL_MODELVIEW);
tglLoadMatrixf(_modelViewMatrix.getData());
} else {
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
if (!window) {
if (scaled) {
tglOrtho(0.0, kOriginalWidth, kOriginalHeight, 0.0, -1.0, 1.0);
} else {
tglOrtho(0.0, _system->getWidth(), _system->getHeight(), 0.0, -1.0, 1.0);
}
} else {
if (scaled) {
Common::Rect originalRect = window->getOriginalPosition();
tglOrtho(0.0, originalRect.width(), originalRect.height(), 0.0, -1.0, 1.0);
} else {
Common::Rect vp = window->getPosition();
tglOrtho(0.0, vp.width(), vp.height(), 0.0, -1.0, 1.0);
}
}
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
}
}
void TinyGLRenderer::drawRect2D(const Common::Rect &rect, uint8 a, uint8 r, uint8 g, uint8 b) {
tglDisable(TGL_TEXTURE_2D);
tglColor3ub(r, g, b);
@@ -225,33 +173,119 @@ void TinyGLRenderer::draw2DText(const Common::String &text, const Common::Point
tglDepthMask(TGL_TRUE);
}
void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
debug("with size %f, %f, %f", size.x(), size.y(), size.z());
drawFace(origin, size.x(), size.y(), 0, (*colours)[0]);
void TinyGLRenderer::updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) {
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
float aspectRatio = kOriginalWidth / (float) kFrameHeight;
float xmaxValue = nearClipPlane * tan(fov * M_PI / 360.0);
float ymaxValue = xmaxValue / aspectRatio;
//debug("max values: %f %f", xmaxValue, ymaxValue);
tglFrustum(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClipPlane, farClipPlane);
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
}
void TinyGLRenderer::drawFace(const Math::Vector3d &origin, float xs, float ys, float zs, uint8 color) {
debug("Face at %f, %f, %f", origin.x(), origin.y(), origin.z());
debug("with size %f, %f, %f", xs, ys, zs);
assert(_palette);
void TinyGLRenderer::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) {
Math::Vector3d up_vec(0, 1, 0);
Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
tglMultMatrixf(lookMatrix.getData());
tglTranslatef(-pos.x(), -pos.y(), -pos.z());
}
void TinyGLRenderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
//debug("Rendering cube at %f, %f, %f", origin.x(), origin.y(), origin.z());
//debug("with size %f, %f, %f", size.x(), size.y(), size.z());
uint8 r, g, b;
_palette->getRGBAt(color, r, g, b);
debug("with colour %d (%d, %d, %d)", color, r, g, b);
_palette->getRGBAt((*colours)[0], r, g, b);
tglDisable(TGL_TEXTURE_2D);
tglColor3ub(r, g, b);
// Face 0
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
tglEnd();
// Face 1
_palette->getRGBAt((*colours)[1], r, g, b);
tglColor3ub(r, g, b);
// First triangle
tglVertex3f(origin.x(), origin.y(), origin.z());
tglVertex3f(origin.x() + xs, origin.y(), origin.z());
tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
// Second triangle
tglVertex3f(origin.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y() - ys, origin.z());
tglVertex3f(origin.x() + xs, origin.y() - ys, origin.z());
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y(), origin.z());
tglEnd();
// Face 2
_palette->getRGBAt((*colours)[2], r, g, b);
tglColor3ub(r, g, b);
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
tglEnd();
// Face 3
_palette->getRGBAt((*colours)[3], r, g, b);
tglColor3ub(r, g, b);
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
tglEnd();
_palette->getRGBAt((*colours)[4], r, g, b);
tglColor3ub(r, g, b);
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y(), origin.z());
tglVertex3f(origin.x(), origin.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y(), origin.z());
tglEnd();
_palette->getRGBAt((*colours)[5], r, g, b);
tglColor3ub(r, g, b);
tglBegin(TGL_TRIANGLES);
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x(), origin.y() + size.y(), origin.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z() + size.z());
tglVertex3f(origin.x() + size.x(), origin.y() + size.y(), origin.z());
tglEnd();
}
void TinyGLRenderer::drawSky(uint8 color) {
uint8 r, g, b;
_palette->getRGBAt(color, r, g, b);
tglClearColor(r / 255., g / 255., b / 255., 1.0);
tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
}
void TinyGLRenderer::flipBuffer() {
+3 -2
View File
@@ -39,7 +39,8 @@ public:
virtual void init() override;
virtual void clear() override;
virtual void selectTargetWindow(Window *window, bool is3D, bool scaled) override;
virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest) override;
virtual void updateProjectionMatrix(float fov, float nearClipPlane, float farClipPlane) override;
Texture *createTexture(const Graphics::Surface *surface) override;
void freeTexture(Texture *texture) override;
@@ -51,7 +52,7 @@ public:
virtual void renderCube(const Math::Vector3d &position, const Math::Vector3d &size, Common::Array<uint8> *colours) override;
virtual void flipBuffer() override;
virtual void drawFace(const Math::Vector3d &position, float xs, float ys, float zs, uint8 color) override;
virtual void drawSky(uint8 color) override;
private:
TinyGL::FrameBuffer *_fb;