ScummVM API documentation
renderer.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef TWINE_RENDERER_RENDERER_H
23#define TWINE_RENDERER_RENDERER_H
24
25#include "common/endian.h"
26#include "common/rect.h"
27#include "common/scummsys.h"
28#include "twine/parser/bodytypes.h"
29#include "twine/twine.h"
30
31#define POLYGONTYPE_FLAT 0
32#define POLYGONTYPE_TELE 1
33// horizontal color adjustment with changing pattern over the polygon
34#define POLYGONTYPE_COPPER 2
35#define POLYGONTYPE_BOPPER 3
36#define POLYGONTYPE_MARBLE 4
37#define POLYGONTYPE_TRANS 5
38#define POLYGONTYPE_TRAME 6
39#define POLYGONTYPE_GOURAUD 7
40#define POLYGONTYPE_DITHER 8
41#define POLYGONTYPE_OUTLINE 9
42
43#define MAT_TRISTE 0
44#define MAT_PIERRE 1
45#define MAT_COPPER 2
46#define MAT_BOPPER 3
47#define MAT_MARBRE 4
48#define MAT_TRANS 5
49#define MAT_TRAME 6
50#define MAT_FLAT 7
51#define MAT_GRANIT 8
52#define MAT_GOURAUD 9
53#define MAT_DITHER 10
54
55#define TYPE_3D 0
56#define TYPE_ISO 1
57
58namespace TwinE {
59
60class BodyData;
61class TwinEEngine;
62
64 int16 intensity = 0;
65 int16 x = 0;
66 int16 y = 0;
67};
68
69bool isPolygonVisible(const ComputedVertex *vertices);
70
72 uint8 renderType = 0;
73 uint8 numVertices = 0;
74 int16 colorIndex = 0; // intensity
75 // followed by Vertex array
76};
77
78struct IMatrix3x3 {
79 IVec3 row1;
80 IVec3 row2;
81 IVec3 row3;
82};
83
84inline IMatrix3x3 operator*(const IMatrix3x3 &matrix, const IVec3 &vec) {
85 IMatrix3x3 out;
86 out.row1.x = matrix.row1.x * vec.x;
87 out.row1.y = matrix.row1.y * vec.x;
88 out.row1.z = matrix.row1.z * vec.x;
89
90 out.row2.x = matrix.row2.x * vec.y;
91 out.row2.y = matrix.row2.y * vec.y;
92 out.row2.z = matrix.row2.z * vec.y;
93
94 out.row3.x = matrix.row3.x * vec.z;
95 out.row3.y = matrix.row3.y * vec.z;
96 out.row3.z = matrix.row3.z * vec.z;
97 return out;
98}
99
100class Renderer {
101private:
102 TwinEEngine *_engine;
103
104 struct RenderCommand {
105 int16 depth = 0;
106 int16 renderType = 0;
114 uint8 *dataPtr = nullptr;
115 };
116
122 struct CmdRenderLine {
123 uint8 colorIndex = 0;
124 uint8 unk1 = 0;
125 uint8 unk2 = 0;
126 uint8 unk3 = 0;
127 int16 x1 = 0;
128 int16 y1 = 0;
129 int16 x2 = 0;
130 int16 y2 = 0;
131 };
132
138 struct CmdRenderSphere {
139 uint16 color = 0; // color start and end values
140 uint8 polyRenderType = 0;
141 int16 radius = 0;
142 int16 x = 0;
143 int16 y = 0;
144 int16 z = 0;
145 };
146
147 struct ModelData {
148 I16Vec3 computedPoints[800]; // List_Anim_Point
149 I16Vec3 flattenPoints[800];
150 int16 normalTable[500]{0};
151 };
152
153 // this is a member var, because 10k on the stack is not supported by every platform
154 ModelData _modelData;
155
156 // AnimNuage
157 void animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
158 bool computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom);
159 bool renderObjectIso(const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect); // RenderObjetIso
160 IVec3 longInverseRot(int32 x, int32 y, int32 z);
161 inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
162 return longInverseRot(vec.x, vec.y, vec.z);
163 }
164 void rotMatIndex2(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
165 void rotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix, const IVec3 &destPos);
166 void processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
167 void transRotList(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec, const IVec3 &destPos);
168 void translateGroup(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
172 IVec3 rot(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z);
173
174 IVec3 _cameraPos; // CameraX, CameraY, CameraZ
175 IVec3 _projectionCenter{320, 200, 0}; // XCentre, YCentre, IsoScale
176
177 int32 _kFactor = 128;
178 int32 _lFactorX = 1024;
179 int32 _lFactorY = 840;
180
181 IMatrix3x3 _matrixWorld; // LMatriceWorld
182 IMatrix3x3 _matricesTable[30 + 1];
183 IVec3 _normalLight; // NormalXLight, NormalYLight, NormalZLight
184 IVec3 _cameraRot; // CameraXr, CameraYr, CameraZr
185
186 RenderCommand _renderCmds[1000];
191 uint8 _renderCoordinatesBuffer[10000]{0};
192 ComputedVertex _clippedPolygonVertices1[128];
193 ComputedVertex _clippedPolygonVertices2[128];
194
195 int16* _tabVerticG = nullptr;
196 int16* _tabVerticD = nullptr;
197 int16* _tabCoulG = nullptr;
198 int16* _tabCoulD = nullptr;
199 int16* _taby0 = nullptr;
200 int16* _taby1 = nullptr;
201 int16* _tabx0 = nullptr; // also _tabCoulG
202 int16* _tabx1 = nullptr; // also _tabCoulD
203
204 bool _typeProj = TYPE_3D;
205
206 void svgaPolyCopper(int16 vtop, int16 vbottom, uint16 color) const;
207 void svgaPolyBopper(int16 vtop, int16 vbottom, uint16 color) const;
208 void svgaPolyTriste(int16 vtop, int16 vbottom, uint16 color) const;
209 void svgaPolyTele(int16 vtop, int16 vbottom, uint16 color) const;
210 void svgaPolyTrans(int16 vtop, int16 vbottom, uint16 color) const;
211 void svgaPolyTrame(int16 vtop, int16 vbottom, uint16 color) const;
212 void svgaPolyGouraud(int16 vtop, int16 vbottom) const;
213 void svgaPolyDith(int16 vtop, int16 vbottom) const;
214 void svgaPolyMarbre(int16 vtop, int16 vbottom, uint16 color) const;
215 void svgaPolyTriche(int16 vtop, int16 vbottom, uint16 color) const;
216 bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int16 &vtop, int16 &vbottom);
217
218 const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
219 uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
220 uint8 *prepareSpheres(const Common::Array<BodySphere>& spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
221 uint8 *prepareLines(const Common::Array<BodyLine>& lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
222
223 void flipMatrix();
224
225 void fillTextPolyNoClip(int32 top, int32 bottom, const uint8 *holomapImage, uint32 holomapImageSize);
226 void fillHolomapTriangle(int16 *pDest, int32 x1, int32 y1, int32 x2, int32 y2);
227 void fillHolomapTriangles(const ComputedVertex &vertex1, const ComputedVertex &vertex2, const ComputedVertex &texCoord1, const ComputedVertex &texCoord2, int32 &top, int32 &bottom);
228
229 // ClipGauche, ClipDroite, ClipHaut, ClipBas
230 int16 leftClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
231 int16 rightClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
232 int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
233 int16 bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
234 int32 computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices, int16 &vtop, int16 &vbottom);
235public:
236 Renderer(TwinEEngine *engine);
237 ~Renderer();
238
239 void init(int32 w, int32 h);
240
241 void setCameraRotation(int32 x, int32 y, int32 z);
242
249 IVec2 rotate(int32 side, int32 forward, int32 angle) const;
250
251 void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
252 IVec3 longWorldRot(int32 x, int32 y, int32 z);
253
254 IVec3 worldRotatePoint(const IVec3& vec);
255
256 void fillVertices(int16 vtop, int16 vbottom, uint8 renderType, uint16 color);
257 void renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices);
258
259 inline IVec3 projectPoint(const IVec3& pos) { // ProjettePoint
260 return projectPoint(pos.x, pos.y, pos.z);
261 }
262
263 void projIso(IVec3 &pos, int32 x, int32 y, int32 z);
264
265 IVec3 projectPoint(int32 cX, int32 cY, int32 cZ);
266
267 void setFollowCamera(int32 transPosX, int32 transPosY, int32 transPosZ, int32 cameraAlpha, int32 cameraBeta, int32 cameraGamma, int32 cameraZoom);
268 void setPosCamera(int32 x, int32 y, int32 z);
269 IVec3 setAngleCamera(int32 alpha, int32 beta, int32 gamma);
270 IVec3 setInverseAngleCamera(int32 alpha, int32 beta, int32 gamma);
271
272 inline IVec3 setBaseRotation(const IVec3 &rot) {
273 return setAngleCamera(rot.x, rot.y, rot.z);
274 }
275
276 void setProjection(int32 x, int32 y, int32 depthOffset, int32 scaleX, int32 scaleY);
277 void setIsoProjection(int32 x, int32 y, int32 scale);
278
279 bool affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect);
280
281 inline bool renderIsoModel(const IVec3 &pos, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
282 return affObjetIso(pos.x, pos.y, pos.z, angleX, angleY, angleZ, bodyData, modelRect);
283 }
284
288 void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData, RealValue &move);
292 void drawObj3D(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData, RealValue &move);
293
297 void draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom);
298
299 void asmTexturedTriangleNoClip(const ComputedVertex vertexCoordinates[3], const ComputedVertex textureCoordinates[3], const uint8 *holomapImage, uint32 holomapImageSize);
300
301 inline IVec3 getCameraPosition() const {
302 return _cameraPos;
303 }
304
305 inline IVec3 getCameraRotation() const {
306 return _cameraRot;
307 }
308
309 inline int32 getLFactorX() const {
310 return _lFactorX;
311 }
312
313 inline int32 getLFactorY() const {
314 return _lFactorY;
315 }
316};
317
318inline void Renderer::setCameraRotation(int32 x, int32 y, int32 z) {
319 _cameraRot.x = x;
320 _cameraRot.y = y;
321 _cameraRot.z = z;
322}
323
324} // namespace TwinE
325
326#endif
Definition: array.h:52
Definition: body.h:41
Definition: renderer.h:100
IVec2 rotate(int32 side, int32 forward, int32 angle) const
void draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom)
Render an inventory item.
void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData, RealValue &move)
void drawObj3D(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData, RealValue &move)
Definition: twine.h:207
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: rect.h:536
Definition: bodytypes.h:54
Definition: renderer.h:71
Definition: renderer.h:63
Definition: shared.h:100
Definition: renderer.h:78
Definition: shared.h:108
Definition: shared.h:127
Definition: actor.h:40