1 //----------------------------------------------------------------------------- 2 // Render + OpenGL Driver support 3 //----------------------------------------------------------------------------- 4 5 #ifndef __RENDER_H__ 6 #define __RENDER_H__ 7 8 #include "cake.h" 9 #include "camera.h" 10 11 /** 12 * Interface with OpenGL states. 13 * Records the current state. This class can be seen as an OpenGL states 14 * interface. 15 */ 16 class State 17 { 18 public: 19 20 // there is only a current state, thus all the members are static 21 static void SetInitialState(int multitexture); 22 23 /** 24 * Set to default state 25 * @todo Terminate this ! 26 */ 27 static void SetDefaultState(void); 28 29 /** 30 * Binds the texture of the given layer 31 * @param l layer to bind texture to 32 * @param unit texturing unit on the 3d card (be careful with this 33 * because currently the only card that supports 4 texturing 34 * units is the geforce 35 * @test It is incredible how much time does the engine spend here! 36 */ 37 static void BindTexture(Layer *l, int unit); 38 39 /** 40 * Set the appropriate state to render the layer. 41 * @test check all redundant state changes ??? 42 */ 43 static void setState(Layer *l); 44 45 /** 46 * Active shader states. 47 */ 48 static void SetupShader(void); 49 50 /** 51 * Evaluates a deform function. 52 * @param p a parameters table 53 * @return the function result 54 */ 55 static float Eval(float *p); 56 57 // input related 58 static Shader * curr_shader; 59 static Shader * curr_effect; 60 static int curr_depthFunc; 61 static int curr_depthWrite; 62 static int curr_blendsrc; 63 static int curr_blenddst; 64 static int curr_culling; 65 static int curr_alphaFunc; 66 static int curr_polygonmode; 67 68 static int curr_texture[MAX_TEXTURE_UNITS]; 69 70 static int skipping; 71 72 static int curr_lightmap; 73 74 static int last_tcgen[MAX_TEXTURE_UNITS]; 75 76 static int pass; // output related 77 78 // Following functions change manually an opengl state 79 static void setDepthFunc(int val); 80 static void setDepthWrite(int val); 81 static void setBlend(int src, int dst); 82 static void setCulling(int val); 83 static void setAlphaFunc(int func, float funcref = 0); 84 static void setPolygonMode(int val); 85 }; 86 87 /** 88 * Vertex buffer used for arrays generation. 89 */ 90 typedef struct 91 { 92 int st_content; /**< vertex texture coordinates */ 93 float* st; /**< 2 texture coordinates */ 94 int c_content; /**< vertex color */ 95 byte* c; /**< 4 colors */ 96 } Buffer; 97 98 /** 99 * Structure used to communicate triangles to graphic card. 100 */ 101 typedef struct 102 { 103 int numelems; 104 unsigned int * elems; /**< elements buffer */ 105 106 int numverts; 107 float* xyz; /**< 4 coordinates for a vertice */ 108 float* tex_st; /**< 2 texture coordinates */ 109 float* lm_st; /**< 2 lightmap coordinates */ 110 float* normal; /**< 4 coordinates for the normal */ 111 byte* c; /**< 4 colors */ 112 #if MODIF_FOG 113 cplane_t** fog; /**< fog plane */ 114 #else 115 float* fog; /**< 5 fog parameters (normal, dist and type) */ 116 #endif 117 } Input; 118 119 typedef void (APIENTRY *swapcommand_t) (void); 120 121 /** 122 * Render class. 123 * The render is a class that interacts with OpenGL driver. All faces are 124 * sent to the OpenGL API through the render. 125 * For now, the render supposes that we use GLUT in the main program for 126 * window management. 127 * This has to consequence that some 3D graphic cards shouldn't work 128 * correctly with the engine, especially the cards which need dynamic drivers 129 * (3Dfx voodoo based cards for example). For these cards, we should rewrite 130 * the driver and use GLS.H instead of GLUT.H and GL.H. 131 * <pre> 132 * Notes on the Quake 3 axis system : 133 * ______________________________________ 134 * | | 135 * | | 136 * | Z /|\ _ Y | This represents the orientation 137 * | | /| _____ | of axis in the engine for a 138 * | | / / /| | camera angle of (90 0 0). 139 * | | / /____ / | O O | 140 * | | / | | | /|\ \|/ | (by default, the camera has a 141 * | | / | | / | | | pitch = 90, otherwise, the 142 * | | / |_____|/ / \ / \ | camera looks to the ground) 143 * | |/ \ | 144 * | --+----------------------- X | 145 * | /| O / | 146 * | | 147 * |______________________________________| 148 * 149 * The Quake3 axis system is similar to OpenGL system (right hand system). 150 * On the above figure, the pitch of camera is 90. This explains why Z axis 151 * is going up. 152 * In fact, the engine considers Oxy plane as ground and Oz vector as up 153 * vector. 154 * In the engine, XYZ axis can be viewed using the grid display. The x, y 155 * and z axis are respectively displayed in red, green and blue colors. 156 * They have a length of 1000 and are centered at position (0,0,0). 157 * </pre> 158 * The global principle of render work is to push triangles that have same 159 * shader on a stack, and then to send all the stack to the graphic card 160 * using <code>glDrawElements</code>. A state system is used to store 161 * texture and shader parameters of the triangles. 162 * @see State 163 * @todo Resolve the display problem: the first top line of the screen 164 * doesn't displays correctly. If r_clear == 1, the first line of 165 * the screen manifestly appears incorrect. 166 * @bug Check that camera is defined for each part that require the camera pointer. 167 */ 168 class Render 169 { 170 private: 171 int state; 172 Input input; 173 Buffer buffer[MAX_TEXTURE_UNITS]; 174 175 /** 176 * Increases the buffer size. 177 * @param newsize the new buffer size. 178 */ 179 void IncreaseBuffer(unsigned int newsize); 180 181 /** 182 * Increases the elems size. 183 * @param newsize the new elems size. 184 */ 185 void IncreaseElems(unsigned int newsize); 186 187 protected: 188 bool ext_swapControl; 189 swapcommand_t swapbuffersfunc; 190 191 public: 192 Camera* current_camera; /**< current camera used for rendering */ 193 194 int ready; /**< inform if render is ready */ 195 int windowIndex; /**< window index */ 196 197 texinfo fogtexture; /**< fog texture */ 198 199 int gridpass; /**< grid related */ 200 201 unsigned long num_flush; /**< number of flush calls */ 202 unsigned long num_tris; /**< number of triangles rendered */ 203 unsigned long num_verts; /**< number of vertices */ 204 unsigned long num_apicalls; /**< number of gl api calls */ 205 206 Render(void); 207 ~Render(void); 208 209 /** 210 * Indicates we are beginning a new frame. 211 */ 212 int BeginFrame(void); 213 214 /** 215 * Indicates the frame is finished and the render can flush all unflushed triangles. 216 */ 217 int EndFrame(void); 218 219 /** 220 * Reset window size and automatically recalculate the console background size. 221 * @param w the new width size 222 * @param h the new height size 223 * @param c the new color bit 224 * @param f the new frequency 225 */ 226 void SetWindowSettings(GLsizei w = -1, GLsizei h = -1, GLint c = -1, GLint f = -1); 227 228 229 /** 230 * Initialize the render. 231 * @param func a pointer to function used for buffers swap 232 * @return 1 if initialization succeeded, 0 if not 233 */ 234 int Init(swapcommand_t func); 235 236 /** 237 * Shuts down the render. 238 */ 239 void Shut(void); 240 241 242 /** 243 * Gets the window width. 244 * @return the window width 245 */ 246 int GetWidth(void); 247 248 /** 249 * Gets the window height. 250 * @return the window height 251 */ 252 int GetHeight(void); 253 254 /** 255 * Gets the window left position. 256 * @return the window left position 257 */ 258 int GetLeft(void); 259 260 /** 261 * Gets the window top position. 262 * @return the window top position 263 */ 264 int GetTop(void); 265 266 /** 267 * Gets a report of the current OpenGL states. 268 */ 269 void DumpGLState(void); 270 271 /** 272 * Check for GL error and update gl function counter 273 * The function depends on enableGLChecks constant. If enabled, 274 * the function reports the error in console for release mode and 275 * generates a break in debug mode. 276 * @param ncalls The number of api calls 277 */ 278 void CheckGLError(int ncalls = 1); 279 280 /** 281 * Determines if an extension is supported. 282 * The function must be called after a valid context has been created. 283 */ 284 bool CheckExtension(char *extName); 285 286 // TODO: Comment those functions. 287 int RegisterTexInfo(texinfo *tex, int flags); 288 void UnregisterTexInfo(texinfo *tex); 289 void SetRenderState(Shader *s, int lightmap = ~0, Shader *e = NULL); 290 void InitializeViewPort(void); 291 void PushTriangles(Surface *surf, int *visible = NULL); 292 void Flush(void); 293 294 /** 295 * Force the flushing. 296 */ 297 void ForceFlush(void); 298 299 // Flushing functions 300 void FlushMtxCVA(void); 301 void FlushMtx(void); 302 void FlushGenericCVA(void); 303 void FlushGeneric(void); 304 void FlushSingleCVA(void); 305 void FlushSingle(void); 306 void FlushVertexLit(void); 307 void FlushGridCVA(void); 308 void FlushGrid(void); 309 310 void SwapBuffers(void); 311 312 /** 313 * This function looks for and sends tristrips. 314 * Vertexes are in tristrip order where possible. If we can't lock 315 * the vertex arrays (glLockArraysEXT), then it's better to send 316 * tristrips instead of triangles (less transformations). 317 * <br> 318 * Tristrip order elems look like this: 319 * 0 1 2 2 1 3 2 3 4 4 3 5 4 5 7 7 5 6 <-- elems 320 * b a a b b a b a a b b a b a a b b <-- ab pattern 321 * \ 1 / \ 2 / \ 3 / \ 4 / \ 5 / <-- baa/bba groups 322 */ 323 void Stripmine(int numelems, unsigned int *elems); 324 325 /** 326 * Modifiy the vertices coord in function of vertex deformations. 327 * @param s the basis surfaces 328 * @param level the tesselation level for surface 329 * @see Shader 330 * @todo Terminate the autosprite + autosprite2 deformations. 331 * @todo Terminate the normal deformation. 332 */ 333 void SetVertexCoords(Surface *s, int level = 0); 334 335 /** 336 * @todo Save last tcgen and last tcmod to know if we dont have 337 * to recopy the coordinates. 338 */ 339 void SetTextureCoordinates(int tmu, Layer *l); 340 void SetVertexColors(int tmu, Layer *l); 341 342 /** 343 * Generates the perspective matrix. 344 * @param fov the camera fov 345 * @param aspect the aspect ratio 346 * @todo Put that in glutils... 347 * @test Carmack uses vertical fov to deal with 16:9 monitors! 348 */ 349 void Perspective(float fov, float aspect); 350 351 /** 352 * Creates a fog texture. 353 * Current fog version doesn't use any extension. The fog is simulated 354 * with the fog texture. The fog texture is rendered in an additional pass 355 * and texture coordinates are chosen in function of distance between vertex 356 * and camera. See SetTextureCoordinates() function for details on texture 357 * coordinates generation. 358 * @param t The destination texture. 359 */ 360 void CreateFogTexture(texinfo *t); 361 }; 362 363 #endif /* __RENDER_H__ */ 364