This file is indexed.

/usr/include/crystalspace-2.0/ivideo/graph3d.h is in libcrystalspace-dev 2.0+dfsg-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
/*
    Copyright (C) 1998-2001 by Jorrit Tyberghein
                       2004 by Marten Svanfeldt
    Written by Jorrit Tyberghein, Dan Ogles, and Gary Clark.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_IVIDEO_GRAPH3D_H__
#define __CS_IVIDEO_GRAPH3D_H__

/**\file
 * 3D graphics interface
 */

/**
 * \addtogroup gfx3d
 * @{ */
 
#include "csutil/scf.h"

#include "csgeom/matrix4.h"
#include "csgeom/transfrm.h"
#include "csutil/flags.h"
#include "csutil/strset.h"

#include "ivideo/rndbuf.h"

struct iClipper2D;
struct iGraphics2D;
struct iHalo;
struct iRenderBuffer;
struct iShader;
struct iShaderVariableContext;
struct iTextureHandle;
struct iTextureManager;

class csRect;
class csPlane3;
class csShaderVariable;
class csVector2;
class csVector3;
class csVector4;

namespace CS
{
  namespace Graphics
  {
    struct CoreRenderMesh;
    struct RenderMeshModes;
  } // namespace Graphics
} // namespace CS
class csRenderBufferHolder;
class csShaderVariableStack;


/**\name iGraphics3D::BeginDraw() flags
 * @{ */
/// We're going to draw 2D graphics
#define CSDRAW_2DGRAPHICS   0x00000001
/// We're going to draw 3D graphics
#define CSDRAW_3DGRAPHICS   0x00000002
/// Clear Z-buffer ?
#define CSDRAW_CLEARZBUFFER 0x00000010
/// Clear frame buffer ?
#define CSDRAW_CLEARSCREEN  0x00000020
/// Ignore clipping rectangle when clearing?
#define CSDRAW_NOCLIPCLEAR  0x00000040
/**
 * Trigger a read back of the render target once drawing is finished.
 * The read back data must be retrieved with iTextureHandle::Readback().
 * Has no effect if no render target is set.
 */
#define CSDRAW_READBACK     0x00000080
/** @} */

/**\name Type of clipper (for iGraphics3D::SetClipper())
 * @{ */
/**
 * There is no clipper.
 */
#define CS_CLIPPER_NONE -1
/**
 * Clipper is optional.
 */
#define CS_CLIPPER_OPTIONAL 0
/**
 * Clipper is top-level.
 */
#define CS_CLIPPER_TOPLEVEL 1
/**
 * Clipper is required.
 */
#define CS_CLIPPER_REQUIRED 2
/** @} */

/**\name Clipping requirement for DrawTriangleMesh
 * @{ */
/**
 * No clipping required.
 * (setting for clip_portal, clip_plane, or clip_z_plane).
 */
#define CS_CLIP_NOT 0
/**
 * Clipping may be needed. Depending on the type of the clipper
 * (one of the CS_CLIPPER_??? flags) the renderer has to clip or
 * not. (setting for clip_portal, clip_plane, or clip_z_plane).
 */
#define CS_CLIP_NEEDED 1
/** @} */

/// Z-buffer modes
enum csZBufMode
{
  /// Don't test or write
  CS_ZBUF_NONE     = 0x00000000,
  /// Write unconditionally
  CS_ZBUF_FILL     = 0x00000001,
  /// Test only
  CS_ZBUF_TEST     = 0x00000002,
  /// Test, write if successful
  CS_ZBUF_USE      = 0x00000003,
  /// Test if equal
  CS_ZBUF_EQUAL    = 0x00000004,
  /// Inverted test
  CS_ZBUF_INVERT   = 0x00000005,
  
  /// Use the z mode of the render mesh (NOTE: NOT VALID AS MESH ZMODE)
  CS_ZBUF_MESH     = 0x80000000,
  /**
   * Use a "pass 2" z mode depending on the render mesh zmode.
   * The mesh zmode is used a to choose a zmode that makes sure only pixels
   * that are changed by the mesh zmode can be touched, e.g. if the mesh has a
   * zmode of "zuse", zmesh2 will resolve to "ztest". This is useful for multi-
   * pass stuff.
   * (NOTE: NOT VALID AS MESH ZMODE)
   */
  CS_ZBUF_MESH2    = 0x80000001
};

// @@@ Keep in sync with values below
// \todo Document me!
#define CS_VATTRIB_SPECIFIC_FIRST    0
#define CS_VATTRIB_SPECIFIC_LAST    15
#define CS_VATTRIB_SPECIFIC_NUM     \
  (CS_VATTRIB_SPECIFIC_LAST - CS_VATTRIB_SPECIFIC_FIRST + 1)
#define CS_VATTRIB_GENERIC_FIRST   100
#define CS_VATTRIB_GENERIC_LAST    (CS_VATTRIB_GENERIC_FIRST + 15)
#define CS_VATTRIB_GENERIC_NUM     \
  (CS_VATTRIB_GENERIC_LAST - CS_VATTRIB_GENERIC_FIRST + 1)
#define CS_IATTRIB_FIRST           200 
#define CS_IATTRIB_LAST            (CS_IATTRIB_FIRST + 0) 
#define CS_IATTRIB_NUM             \
  (CS_IATTRIB_LAST - CS_IATTRIB_FIRST + 1)


#define CS_VATTRIB_IS_GENERIC(va)   \
  ((va >= CS_VATTRIB_GENERIC_FIRST) && (va <=CS_VATTRIB_GENERIC_LAST))
#define CS_VATTRIB_IS_SPECIFIC(va)   \
  ((va >= CS_VATTRIB_SPECIFIC_FIRST) && (va <=CS_VATTRIB_SPECIFIC_LAST))

/**
 * Vertex attributes.
 */
enum csVertexAttrib
{
  /**
   * An attribute is valid, but unused by a shader program and can be 
   * discarded */
  CS_VATTRIB_UNUSED	      = -2,
  /// Invalid attribute
  CS_VATTRIB_INVALID	      = -1,
  /// Position vertex attribute
  CS_VATTRIB_POSITION	      = CS_VATTRIB_SPECIFIC_FIRST + 0,
  /// Vertex weight attribute
  CS_VATTRIB_WEIGHT	      = CS_VATTRIB_SPECIFIC_FIRST + 1,
  /// Normal attribute
  CS_VATTRIB_NORMAL	      = CS_VATTRIB_SPECIFIC_FIRST + 2,
  /// Primary color attribute
  CS_VATTRIB_COLOR	      = CS_VATTRIB_SPECIFIC_FIRST + 3,
  /// Primary color attribute
  CS_VATTRIB_PRIMARY_COLOR    = CS_VATTRIB_SPECIFIC_FIRST + 3,
  /// Secondary color attribute
  CS_VATTRIB_SECONDARY_COLOR  = CS_VATTRIB_SPECIFIC_FIRST + 4,
  /// Fog coordinate attribute
  CS_VATTRIB_FOGCOORD	      = CS_VATTRIB_SPECIFIC_FIRST + 5,
  /// TU 0 texture coordinates
  CS_VATTRIB_TEXCOORD	      = CS_VATTRIB_SPECIFIC_FIRST + 8,
  /// TU 0 texture coordinates
  CS_VATTRIB_TEXCOORD0	      = CS_VATTRIB_SPECIFIC_FIRST + 8,
  /// TU 1 texture coordinates
  CS_VATTRIB_TEXCOORD1	      = CS_VATTRIB_SPECIFIC_FIRST + 9,
  /// TU 2 texture coordinates
  CS_VATTRIB_TEXCOORD2	      = CS_VATTRIB_SPECIFIC_FIRST + 10,
  /// TU 3 texture coordinates
  CS_VATTRIB_TEXCOORD3	      = CS_VATTRIB_SPECIFIC_FIRST + 11,
  /// TU 4 texture coordinates
  CS_VATTRIB_TEXCOORD4	      = CS_VATTRIB_SPECIFIC_FIRST + 12,
  /// TU 5 texture coordinates
  CS_VATTRIB_TEXCOORD5	      = CS_VATTRIB_SPECIFIC_FIRST + 13,
  /// TU 6 texture coordinates
  CS_VATTRIB_TEXCOORD6	      = CS_VATTRIB_SPECIFIC_FIRST + 14,
  /// TU 7 texture coordinates
  CS_VATTRIB_TEXCOORD7	      = CS_VATTRIB_SPECIFIC_FIRST + 15,
  //@{
  /**
  * General vertex attribute
  */
  CS_VATTRIB_0	= CS_VATTRIB_GENERIC_FIRST + 0,
  CS_VATTRIB_1	= CS_VATTRIB_GENERIC_FIRST + 1,
  CS_VATTRIB_2	= CS_VATTRIB_GENERIC_FIRST + 2,
  CS_VATTRIB_3	= CS_VATTRIB_GENERIC_FIRST + 3,
  CS_VATTRIB_4	= CS_VATTRIB_GENERIC_FIRST + 4,
  CS_VATTRIB_5	= CS_VATTRIB_GENERIC_FIRST + 5,
  CS_VATTRIB_6	= CS_VATTRIB_GENERIC_FIRST + 6,
  CS_VATTRIB_7	= CS_VATTRIB_GENERIC_FIRST + 7,
  CS_VATTRIB_8	= CS_VATTRIB_GENERIC_FIRST + 8,
  CS_VATTRIB_9	= CS_VATTRIB_GENERIC_FIRST + 9,
  CS_VATTRIB_10 = CS_VATTRIB_GENERIC_FIRST + 10,
  CS_VATTRIB_11 = CS_VATTRIB_GENERIC_FIRST + 11,
  CS_VATTRIB_12 = CS_VATTRIB_GENERIC_FIRST + 12,
  CS_VATTRIB_13 = CS_VATTRIB_GENERIC_FIRST + 13,
  CS_VATTRIB_14 = CS_VATTRIB_GENERIC_FIRST + 14,
  CS_VATTRIB_15 = CS_VATTRIB_GENERIC_FIRST + 15,
  //@}

  /// Pseudo-instancing attribute: object-to-world matrix 
  CS_IATTRIB_OBJECT2WORLD = CS_IATTRIB_FIRST + 0
};

/**\name Mix mode: Types
 * The mix mode specifies how a shaded fragment (denoted as \c SRC) is mixed 
 * (or \e blended) with the framebuffer fragment (\c DST).
 * @{ */
/**
 * Automatic blending mode. Whether the texture is alpha-blended or not is 
 * taken from csRenderMesh::alphaMode and whether the alpha part of the
 * mixmode is non-zero.
 */
#define CS_MIXMODE_TYPE_AUTO (0x00000000)
/**
 * Blend with a blending operation.
 * The fragment value written to the framebuffer is computed from the 
 * formula \c SRC * \c srcFactor + \c DST * \c dstFactor. 
 * \c srcFactor and \c dstFactor are one of 
 * \link #CS_MIXMODE_FACT_ZERO CS_MIXMODE_FACT_xxx \endlink, encoded into
 * the mixmode specifier with #CS_MIXMODE_BLEND.
 */
#define CS_MIXMODE_TYPE_BLENDOP (0x40000000)
/**
 * When blending with a blending operation, signinify that separate factors
 * for the alpha channel are present.
 */
#define CS_MIXMODE_FLAG_BLENDOP_ALPHA (0x08000000)
/**
 * Use the mix mode of the mesh mix mode.
 * \warning NOT VALID AS MESH MIXMODE - only for shader pass mixmodes.
 */
#define CS_MIXMODE_TYPE_MESH (0x80000000)

/// Bit mask to extract the type from a mixmode specifier.
#define CS_MIXMODE_TYPE_MASK (0xc0000000)
/** @} */

/// Mix mode: Blending op factors
enum
{
  /// 0
  CS_MIXMODE_FACT_ZERO		= 0x0,
  /// -(e^(i*Pi))
  CS_MIXMODE_FACT_ONE		= 0x1,
  /// Source fragment (R,G,B,A) components
  CS_MIXMODE_FACT_SRCCOLOR	= 0x2,
  /// Source fragment (1-R,1-G,1-B,-1A) components
  CS_MIXMODE_FACT_SRCCOLOR_INV	= 0x3,
  /// Destination fragment (R,G,B,A) components
  CS_MIXMODE_FACT_DSTCOLOR	= 0x4,
  /// Destination fragment (1-R,1-G,1-B,-1A) components
  CS_MIXMODE_FACT_DSTCOLOR_INV	= 0x5,
  /// Source fragment alpha
  CS_MIXMODE_FACT_SRCALPHA	= 0x6,
  /// Source fragment 1-alpha
  CS_MIXMODE_FACT_SRCALPHA_INV	= 0x7,
  /// Destination fragment alpha
  CS_MIXMODE_FACT_DSTALPHA	= 0x8,
  /// Destination fragment 1-alpha
  CS_MIXMODE_FACT_DSTALPHA_INV	= 0x9,
  
  /// Number of available mixmodes
  CS_MIXMODE_FACT_COUNT		= 0xa,
  
  /// Mask to extract factors
  CS_MIXMODE_FACT_MASK		= 0xf
};

/**\name Mix mode: Alpha test flags
 * Enabled alpha test (or <i>binary alpha</i>) means that a fragment is only
 * drawn when its alpha component is above a certain threshold, and discarded
 * otherwise.
 * @{ */
/**
 * Automatic alpha test. Whether the texture is alpha-blended binarily is 
 * taken from csRenderMesh::alphaMode and whether the alpha part of the
 * mixmode is non-zero.
 */
#define CS_MIXMODE_ALPHATEST_AUTO (0x00000000)
/// Unconditionally enable alpha test.
#define CS_MIXMODE_ALPHATEST_ENABLE (0x10000000)
/// Unconditionally disable alpha test.
#define CS_MIXMODE_ALPHATEST_DISABLE (0x20000000)
  
/// Bit mask to extract the alpha test flag from a mixmode specifier.
#define CS_MIXMODE_ALPHATEST_MASK (0x30000000)
/** @} */

/**\name Mix mode: Blending mode helpers
 * @{ */
/**
 * Helper macro to construct a blending operation mixmode
 * \a Src and \a Dst are 
 * \link #CS_MIXMODE_FACT_ZERO blending op factors \endlink, however sans the
 * CS_MIXMODE_FACT_ prefix. E.g.:
 * \code
 * uint mixmode = CS_MIXMODE_BLEND(SRCALPHA, SRCALPHA_INV);
 * \endcode
 * will generate a blending operation for alpha blending.
 */
#define CS_MIXMODE_BLEND(Src, Dst)					\
  (CS_MIXMODE_TYPE_BLENDOP 						\
  | (CS_MIXMODE_FACT_ ## Src << 20) | (CS_MIXMODE_FACT_ ## Dst << 16))
/// Helper macro to extract the \c srcFactor from a blending op mixmode.
#define CS_MIXMODE_BLENDOP_SRC(mode)	((mode >> 20) & CS_MIXMODE_FACT_MASK)
/// Helper macro to extract the \c dstFactor from a blending op mixmode.
#define CS_MIXMODE_BLENDOP_DST(mode)	((mode >> 16) & CS_MIXMODE_FACT_MASK)

/**
 * Helper macro to construct alpha factoes for a blending operation mixmode
 * \a Src and \a Dst are 
 * \link #CS_MIXMODE_FACT_ZERO blending op factors \endlink, however sans the
 * CS_MIXMODE_FACT_ prefix. E.g.:
 * \code
 * uint mixmode = CS_MIXMODE_BLEND(SRCALPHA, SRCALPHA_INV)
 *   | CS_MIXMODE_BLEND_ALPHA(ONE, SRCALPHA_INV);
 * \endcode
 * will generate a blending operation for alpha blending with the written
 * destination alpha values suitable for use for premultiplied alpha blending.
 */
#define CS_MIXMODE_BLEND_ALPHA(Src, Dst)				\
  (CS_MIXMODE_FLAG_BLENDOP_ALPHA					\
  | (CS_MIXMODE_FACT_ ## Src << 12) | (CS_MIXMODE_FACT_ ## Dst << 8))
/// Helper macro to extract the alpha \c srcFactor from a blending op mixmode.
#define CS_MIXMODE_BLENDOP_ALPHA_SRC(mode)	((mode >> 12) & CS_MIXMODE_FACT_MASK)
/// Helper macro to extract the alpha \c dstFactor from a blending op mixmode.
#define CS_MIXMODE_BLENDOP_ALPHA_DST(mode)	((mode >> 8) & CS_MIXMODE_FACT_MASK)
/** @} */

/**\name Mix mode: Default modes
 * A set of commonly used mix modes.
 * @{ */
/**
 * This mixmode uses alpha smooth blending, binary blending (ie enabled
 * alpha test) and no blending depending on the contents of 
 * csRenderMesh::alphaMode.
 * \remarks For a "true" copy mixmode that just writes the source fragment
 *   color to the frame buffer, you can use:
 *   \code
 *   CS_MIXMODE_BLEND(ONE, ZERO) | CS_MIXMODE_ALPHATEST_DISABLE
 *   \endcode
 */
#define CS_FX_COPY (CS_MIXMODE_TYPE_AUTO | CS_MIXMODE_ALPHATEST_AUTO)
/// Multiplicative blending. Formula: <tt>=SRC*DST</tt>
#define CS_FX_MULTIPLY \
    (CS_MIXMODE_BLEND(DSTCOLOR, ZERO) | CS_MIXMODE_ALPHATEST_DISABLE)
/// Multiplicative doubling blending. Formula: <tt>=2*SRC*DST</tt>
#define CS_FX_MULTIPLY2 \
    (CS_MIXMODE_BLEND(DSTCOLOR, SRCCOLOR) | CS_MIXMODE_ALPHATEST_DISABLE)
/// Additive blending. Formula: <tt>=SRC+DST</tt>
#define CS_FX_ADD \
    (CS_MIXMODE_BLEND(ONE, ONE) | CS_MIXMODE_ALPHATEST_DISABLE)
/** 
 * Alpha blending. Formula: <tt>=srcAlpha*SRC + (1-srcAlpha)*DST</tt>
 * \remarks Usually used with a non-zero alpha part.
 *  \see CS_FX_MASK_ALPHA, \see CS_FX_SETALPHA
 */
#define CS_FX_ALPHA \
    (CS_MIXMODE_BLEND(SRCALPHA, SRCALPHA_INV) \
    | CS_MIXMODE_BLEND_ALPHA(ONE, SRCALPHA_INV) | CS_MIXMODE_ALPHATEST_DISABLE)
/**
 * Transparent blending (keep framebuffer unmodified). 
 * Formula: <tt>=DST</tt>
 * \remarks The Z buffer will still be modified!
 */
#define CS_FX_TRANSPARENT \
    (CS_MIXMODE_BLEND(ZERO, ONE) | CS_MIXMODE_ALPHATEST_DISABLE)
/** 
 * Multiply source color with destination alpha and add.
 * Formula: <tt>=(dstalpha)*SRC + DST</tt>
 */
#define CS_FX_DESTALPHAADD \
    (CS_MIXMODE_BLEND(DSTALPHA, ONE) | CS_MIXMODE_ALPHATEST_DISABLE)
/** 
 * Multiply source color with source alpha and add.
 * Formula: <tt>=(srcalpha)*SRC + DST</tt>
 */
#define CS_FX_SRCALPHAADD \
    (CS_MIXMODE_BLEND(SRCALPHA, ONE) | CS_MIXMODE_ALPHATEST_DISABLE)
/** 
 * Multiply destination color with inverse source alpha and add source color.
 * Formula: <tt>=SRC + DST*(1-srcalpha)</tt>
 * \remarks When the \c SRC alpha component was multiplied into the source
 *  color, this acts like alpha blending; if it was not, it acts like
 *  additive blending. Hence, this mixmode can be used to use both additive
 *  and alpha blending on the same triangle even and interpolate between
 *  those two "extremes" by appropriate choice of the color and alpha values.
 */
#define CS_FX_PREMULTALPHA \
    (CS_MIXMODE_BLEND(ONE, SRCALPHA_INV) | \
    CS_MIXMODE_BLEND_ALPHA(ONE, SRCALPHA_INV) | CS_MIXMODE_ALPHATEST_DISABLE)
/**
 * Use the mix mode of the mesh mix mode.
 * \warning NOT VALID AS MESH MIXMODE - only for shader pass mixmodes.
 */
#define CS_FX_MESH (CS_MIXMODE_TYPE_MESH)
  
/// Flat shading flag.
#define CS_FX_FLAT (0x04000000)
/**
 * Mixmode alpha part. 
 * Values range from 0(opaque) to 255 (transparent) (note that this is the
 * reverse of the "common" alpha meaning). When this part is non-null, the
 * renderer will scale the incoming color buffer alpha components by the
 * (inverse of) this value.
 * \remarks The scaling may be relatively expensive, it is recommended to
 *  scale the vertex alpha by other means, e.g. through a vertex program.
 */
#define CS_FX_MASK_ALPHA (0x000000FF)
  
/**
 * Bit mask for bits relevant to mix mode comparison; contains type, alpha
 * test flags and blending op factors.
 */
#define CS_FX_MASK_MIXMODE (0xf8ffff00)
/** @} */

/**\name Mix mode: alpha helpers
 * @{ */
/// Macro for setting of alpha bits into mixmode (alpha between 0 and 1).
#define CS_FX_SETALPHA(alpha) \
  (CS_FX_ALPHA | uint ((alpha) * CS_FX_MASK_ALPHA))
/// Macro for setting of alpha bits into mixmode (alpha between 0 and 255).
#define CS_FX_SETALPHA_INT(alpha) \
  (CS_FX_ALPHA | uint ((alpha) & CS_FX_MASK_ALPHA))
/** @} */

/**
 * Describes how to deal with alpha values in textures.
 */
struct csAlphaMode
{
  /// How to handle alpha
  enum AlphaType
  {
    /// Ignore alpha
    alphaNone = 1,
    /// Binary alpha (alpha test is used)
    alphaBinary,
    /// 'Smooth' alpha (colors are mixed based on a pixel's alpha value)
    alphaSmooth
  };
  /// Whether 'automatic alpha mode' should be used.
  bool autoAlphaMode;
  union
  {
    /// Alpha mode to use when autoAlphaMode is \p false
    AlphaType alphaType;
    /** 
     * String ID for texture to retrieve the alpha mode from when autoAlphaMode
     * is \p true
     */
    CS::StringIDValue autoModeTexture;
  };
};
/** @} */

/**\name Shadow states
 * @{ */
/// Clear stencil.
#define CS_SHADOW_VOLUME_BEGIN 1
/// Setup for pass 1.
#define CS_SHADOW_VOLUME_PASS1 2
/// Setup for pass 2.
#define CS_SHADOW_VOLUME_PASS2 3
/// Setup for carmack's reverse pass 1.
#define CS_SHADOW_VOLUME_FAIL1 4
/// Setup for carmack's reverse pass 2.
#define CS_SHADOW_VOLUME_FAIL2 5
/// Setup for shadow masking.
#define CS_SHADOW_VOLUME_USE 6
/// Restore states.
#define CS_SHADOW_VOLUME_FINISH 7
/** @} */

/// Graphics3D render state options
enum G3D_RENDERSTATEOPTION
{
  /// Enable/disable edge drawing (debugging) (parameter is a bool)
  G3DRENDERSTATE_EDGES
};

/// Information about 3d renderer capabilities.
struct csGraphics3DCaps
{
  /// Minimum texture dimensions
  int minTexHeight, minTexWidth;
  /// Maximum texture dimensions
  int maxTexHeight, maxTexWidth;
  /**
   * Whether point sprites are supported. If \a true, geometry of the type
   * CS_MESHTYPE_POINT_SPRITES can be drawn.
   */
  bool SupportsPointSprites;
  /**
   * Mixmodes utilizing destination alpha are properly supported.
   */
  bool DestinationAlpha;
  /**
   * Enough stencil bits for stencil shadows are available.
   */
  bool StencilShadows;
  /**
   * The number of supported render target color buffer attachment points.
   * Does not include the depth/stencil attachment point.
   */
  int MaxRTColorAttachments;
};

/// Primitive type of a mesh
enum csRenderMeshType
{
  /// Triangles.
  CS_MESHTYPE_TRIANGLES,
  /// Quads.
  CS_MESHTYPE_QUADS,
  /**
   * Triangle strip.
   * The OpenGL spec describes it pretty well:
   * "A triangle strip is a series of triangles connected along shared edges. 
   * A triangle strip is specified by giving a series of defining vertices 
   * [...]. In this case, the first three vertices define the first triangle 
   * [...]. Each subsequent  vertex defines a new triangle using that point 
   * along with two vertices from the previous triangle."
   */
  CS_MESHTYPE_TRIANGLESTRIP,
  /**
   * Triangle fan.
   * Similar to a triangle strip, however, a triangle is always defined with
   * the first, previously added and the recently added vertex.
   */
  CS_MESHTYPE_TRIANGLEFAN,
  /**
   * Points.
   */
  CS_MESHTYPE_POINTS,
  /**
   * Point sprites. 
   * Note: only supported if the \a SupportsPointSprites member of the 
   * \a csGraphics3DCaps structure for this renderer is true.
   */
  CS_MESHTYPE_POINT_SPRITES,
  /**
   * Lines.
   */
  CS_MESHTYPE_LINES,
  /**
   * Line strip.
   * A line is defined from the prebviously and recently added vertex.
   */
  CS_MESHTYPE_LINESTRIP
};

/**
 * Flags to influence the behaviour of DrawSimpleMesh().
 */
enum csSimpleMeshFlags
{
  /**
   * Ignore the object2camera transform in the csSimpleRenderMesh struct and
   * replace it with a transformation that effectively lets you specify the
   * vertices in screen space. The Z components of the mesh vertices should be
   * set to 0 when this flag is specified.
   */
  csSimpleMeshScreenspace = 0x01
};

/**
 * Flags to inform the renderer about properties of a portal when
 * calling OpenPortal(). 
 */
enum csOpenPortalFlags
{
  /**
   * If this flag is set then renderer must do a Z-fill after rendering
   * the portal contents. This is mainly useful for floating portals
   * where it is possible that there is geometry in the same sector
   * that will be rendered behind the portal (and does could accidently
   * get written in the portal sector because the Z-buffer cannot
   * be trusted).
   */
  CS_OPENPORTAL_ZFILL = 0x00000004,
  /**
   * If this flag is set then this portal mirrors space (changes order
   * of the vertices of polygons).
   */
  CS_OPENPORTAL_MIRROR = 0x00000010,
  /**
   * If this flag is used then the portal must use possible available
   * stencil buffer on the hardware to do good clipping. This flag should
   * be used if you have a portal that is not at the boundary of the sector
   * and that can be covered (or itself covers) other objects. It is usually
   * used in combination with CS_OPENPORTAL_ZFILL.
   */
  CS_OPENPORTAL_FLOAT = 0x00000040
};

/**
 * A simple render mesh.
 */
struct csSimpleRenderMesh
{
  /// Type of the geometry to draw.
  csRenderMeshType meshtype;

  /// (optional) Number of vertex indices
  uint indexCount;
  /** 
   * (optional) Vertex indices.
   * If this field is 0, \a vertexCount indices are generated with the values
   * 0 to \a vertexCount -1. \a indexCount is ignored in that case.
   * In other words, not specifying indices assumes all vertices are in order
   * and only used once.
   */
  const uint* indices;
  //@{
  /**
   * (optional) Range of indices to draw.
   * If \a indexStart < indexEnd, this range is used. Otherwise,
   * the default range (0..indexCount or all vertices) is used.
   */
  uint indexStart, indexEnd;
  //@}

  /// Number of vertices
  uint vertexCount;
  /**
   * Vertices. Note: you can omit vertices or texcoords, however this 
   * will likely only give useable results if you provide a shader and 
   * shader var context (and transfer vertices and/or texcoords with SVs.)
   */
  const csVector3* vertices;
  /// (Optional) Texture coordinates.
  const csVector2* texcoords;
  /**
   * (Optional) Colors. 
   * Leaving this 0 has the same effect as having all vertex colors set to
   * white.
   */
  const csVector4* colors;
  /**
   * (Optional) Handle to the texture to select. 
   * Leaving this 0 has the same effect as using a white texture.
   */
  iTextureHandle* texture;

  /// (Optional) Shader to use.
  iShader* shader;
  /// (Optional) Shader variable context.
  iShaderVariableContext* dynDomain;
  /// (Optional) Alpha mode. Defaults to "autodetect".
  csAlphaMode alphaType;
  /// (Optional) Z buffer mode. Defaults to CS_ZBUF_NONE.
  csZBufMode z_buf_mode;
  /// (Optional) Mix mode. Defaults to CS_FX_COPY.
  uint mixmode;
  /**
   * (Optional) Transform to apply to the mesh.
   * \remark This transform is initialized to an identity transform.
   *  This effectively means that geometry is drawn in world space.
   *  To draw in screen space, supply the \a csSimpleMeshScreenspace
   *  flag to DrawSimpleMesh(). For anything else supply an appropriate
   *  transformation.
   * \remark Keep in mind that the renderer's world-to-camera transform is in
   *  effect, too.
   */
  csReversibleTransform object2world;
  /// (Optional) Buffer holder with all vertex buffers.
  csRef<csRenderBufferHolder> renderBuffers;

  csSimpleRenderMesh () : indexCount(0), indices(0), indexStart (0),
    indexEnd (0), texcoords(0), colors(0), 
    texture (0), shader (0), dynDomain (0), z_buf_mode (CS_ZBUF_NONE), 
    mixmode (CS_FX_COPY)
  {  
    alphaType.autoAlphaMode = true;
    alphaType.autoModeTexture = csInvalidStringID;
  };
};

/**
 * Render target attachment - selects which result of the rasterization gets
 * output to the given texture when setting a render target.
 */
enum csRenderTargetAttachment
{
  /// Depth
  rtaDepth,
  /// Color 0
  rtaColor0,
  /// Color 1
  rtaColor1,
  /// Color 2
  rtaColor2,
  /// Color 3
  rtaColor3,
  /// Color 4
  rtaColor4,
  /// Color 5
  rtaColor5,
  /// Color 6
  rtaColor6,
  /// Color 7
  rtaColor7,
  /// Color 8
  rtaColor8,
  /// Color 9
  rtaColor9,
  /// Color 10
  rtaColor10,
  /// Color 11
  rtaColor11,
  /// Color 12
  rtaColor12,
  /// Color 13
  rtaColor13,
  /// Color 14
  rtaColor14,
  /// Color 15
  rtaColor15,

  /*
   * We stop at 16 color buffer attachment points since that is the current limit placed
   * on the OpenGL framebuffer extension (as of May 19 2010).
   *
   * http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
   */

  /// Number of supported attachments
  rtaNumAttachments,
  /// Number of supported color attachment points.
  rtaNumColorAttachments = rtaNumAttachments - 1
};

namespace CS
{
  namespace Graphics
  {
    struct TextureComparisonMode
    {
      enum Mode
      {
        compareNone,
        compareR
      };
      Mode mode;
      enum Function
      {
        funcLEqual,
        funcGEqual
      };
      Function function;
      
      TextureComparisonMode() : mode (compareNone), function (funcLEqual) {}
    };
  } // namespace Graphics
} // namespace CS

/**
 * This is the standard 3D graphics interface.
 * All 3D renderers for Crystal Space implement this interface.
 *
 * Main creators of instances implementing this interface:
 * - OpenGL Renderer plugin (crystalspace.graphics3d.opengl)
 * - Null 3D Renderer plugin (crystalspace.graphics3d.null)
 *
 * Main ways to get pointers to this interface:
 * - csQueryRegistry()
 */
struct iGraphics3D : public virtual iBase
{
  SCF_INTERFACE(iGraphics3D, 4, 0, 3);
  
  /// Open the 3D graphics display.
  virtual bool Open () = 0;
  /// Close the 3D graphics display.
  virtual void Close () = 0;

  /**
   * Retrieve the associated canvas.
   * \remarks This will return a valid canvas only after
   *   csInitializer::OpenApplication() has been invoked (and if the canvas
   *   plugin loaded and initialized successfully); otherwise it will return
   *   null.
   */
  virtual iGraphics2D *GetDriver2D () = 0;

  /**
   * Retrieve the texture manager.
   * \remarks This will return a valid texture manager only after
   *   csInitializer::OpenApplication() has been invoked; otherwise it will
   *   return null.
   */
  virtual iTextureManager *GetTextureManager () = 0;

  /**
   * Change the dimensions of the display.
   * \deprecated Deprecated in 1.3. 
   */
  CS_DEPRECATED_METHOD
  virtual void SetDimensions (int width, int height) = 0;
  /// Get drawing buffer width.
  virtual int GetWidth () const = 0;
  /// Get drawing buffer height.
  virtual int GetHeight () const = 0;

  /**
   * Get the current driver's capabilities. Each driver implements their
   * own function.
   */
  virtual const csGraphics3DCaps *GetCaps () const = 0;

  /**
   * Set center of projection for perspective projection.
   * \remarks The coordinates are vertically mirrored in comparison to screen
   *   space, i.e. y=0 is at the bottom of the viewport, y=GetHeight() at the 
   *   top.
   * \deprecated Deprecated in 2.0. Use explicit camera's projection matrix instead
   */
  CS_DEPRECATED_METHOD_MSG("Use explicit projection matrix instead")
  virtual void SetPerspectiveCenter (int x, int y) = 0;

  /**
   * Get perspective center.
   * \remarks The coordinates are vertically mirrored in comparison to screen
   *   space, i.e. y=0 is at the bottom of the viewport, y=GetHeight() at the 
   *   top.
   * \deprecated Deprecated in 2.0. Use explicit camera's projection matrix instead
   */
  CS_DEPRECATED_METHOD_MSG("Use explicit projection matrix instead")
  virtual void GetPerspectiveCenter (int& x, int& y) const = 0;

  /**
   * Set aspect ratio for perspective projection.
   * \deprecated Deprecated in 2.0. Use explicit camera's projection matrix instead
   */
  CS_DEPRECATED_METHOD_MSG("Use explicit projection matrix instead")
  virtual void SetPerspectiveAspect (float aspect) = 0;

  /**
   * Get aspect ratio.
   * \deprecated Deprecated in 2.0. Use explicit camera's projection matrix instead
   */
  CS_DEPRECATED_METHOD_MSG("Use explicit projection matrix instead")
  virtual float GetPerspectiveAspect () const = 0;
 
  /**
   * Set the target of rendering for a certain rasterization result.
   * If all result attachments have a 0 target rendering is performed to the
   * framebuffer (ie main screen). If at least one texture is attached
   * rendering is performed off-screen to the given texture(s).
   * After calling FinishDraw() the targets will automatically be unset. 
   * Note that on some implementions rendering on a texture
   * will overwrite the framebuffer contents. So you should only do this 
   * BEFORE you start rendering your frame.
   *
   * \param persistent If this is true then the current contents of the texture
   *   will be preserved when drawing occurs (in the first call to BeginDraw). 
   *   Otherwise it is assumed that you fully render the texture - untouched 
   *   parts may be undefined. Using persistence may incur a performance
   *   penalty so it's recommended to avoid this flag.
   * \param subtexture this specifies the subtexture index if the texture
   *   is a cubemap or volume texture. It is in the range 0 to 5 for cubemaps
   *   (#iTextureHandle::CS_TEXTURE_CUBE_POS_X et al) or the depth index
   *   for volume textures.
   * \param attachment Specifies to what result of the rasterization the
   *   texture should be attached to.
   * \returns Whether setting the render target was successful. However, even
   *   if 'true' is returned, it may be possible that rendering to the eventual
   *   set of render targets is \em not possible. Only if ValidateRenderTargets
   *   returns 'true' the set of targets can really be used as a render target.
   * \sa UnsetRenderTargets
   */
  virtual bool SetRenderTarget (iTextureHandle* handle,
	bool persistent = false,
	int subtexture = 0,
	csRenderTargetAttachment attachment = rtaColor0) = 0;

  /**
   * Check if the current set of render targets is valid.
   * \returns Whether the current set of render targets is valid and useable. 
   *   Reasons for invalidity/unusability can include:
   *   - The hardware or driver does not support the given attachment with
   *     the given texture or not at all.
   *   - The dimensions of the various attachments don't match.
   */
  virtual bool ValidateRenderTargets () = 0;
	
  /**
   * Check if a texture with the given format can be set as a render target for
   * the given attachment.
   * \remarks Texture formats may be reported as supported even though textures
   *   with that format can't be created.
   */
  virtual bool CanSetRenderTarget (const char* format,
    csRenderTargetAttachment attachment = rtaColor0) = 0;

  /**
   * Get the current render target (0 for screen).
   * \param attachment The attachment for which to return the render target.
   * \param subtexture Optionally returns the subtexture index.
   */
  virtual iTextureHandle* GetRenderTarget (
    csRenderTargetAttachment attachment = rtaColor0,
    int* subtexture = 0) const = 0;
  
  /// Clear render targets for all rasterization result attachments.
  virtual void UnsetRenderTargets() = 0;

  /// Start a new frame (see CSDRAW_XXX bit flags)
  virtual bool BeginDraw (int DrawFlags) = 0;

  /// End the frame and do a page swap.
  virtual void FinishDraw () = 0;

  /**
   * Print the image in backbuffer. The area parameter is only a hint to the
   * renderer. Changes outside the rectangle may or may not be printed as
   * well.
   */
  virtual void Print (csRect const* area) = 0;

  /// Drawroutine. Only way to draw stuff
  virtual void DrawMesh (const CS::Graphics::CoreRenderMesh* mymesh,
                         const CS::Graphics::RenderMeshModes& modes,
                         const csShaderVariableStack& stack) = 0;
  /**
  * Draw a csSimpleRenderMesh on the screen.
  * Simple render meshes are intended for cases where setting up
  * a render mesh and juggling with render buffers would be too much
  * effort - e.g. when you want to draw a single polygon on the screen.
  * <p>
  * DrawSimpleMesh () hides the complexity of csRenderMesh, it cares
  * about setting up render buffers, activating the texture etc.
  * Note that you can still provide shaders and shader variables, but those
  * are optional.
  * \param mesh The mesh to draw.
  * \param flags Drawing flags, a combination of csSimpleMeshFlags values.
  * \remark This operation can also be called from 2D mode. In this case,
  *  the csSimpleMeshScreenspace flag should be specified. If this is not the
  *  case, you are responsible for the mess that is likely created.
  */
  virtual void DrawSimpleMesh (const csSimpleRenderMesh& mesh,
    uint flags = 0) = 0;

  /**
   * Draw a pixmap using a rectangle from given texture.
   * The sx,sy(sw,sh) rectangle defines the screen rectangle within
   * which the drawing is performed (clipping rectangle is also taken
   * into account). The tx,ty(tw,th) rectangle defines a subrectangle
   * from texture which should be painted. If the subrectangle exceeds
   * the actual texture size, texture coordinates are wrapped around
   * (e.g. the texture is tiled). The Alpha parameter defines the
   * transparency of the drawing operation, 0 means opaque, 255 means
   * fully transparent.<p>
   * <b>WARNING: Tiling works only with textures that have power-of-two
   * sizes!</b> That is, both width and height should be a power-of-two,
   * although not neccessarily equal.
   */
  virtual void DrawPixmap (iTextureHandle *hTex, int sx, int sy,
    int sw, int sh, int tx, int ty, int tw, int th, uint8 Alpha = 0) = 0;

  /**
   * Draw a line in camera space. Warning! This is a 2D operation
   * and must be called while in BeginDraw(CSDRAW_2DGRAPHICS)!
   * \deprecated Deprecated in 2.0. Use iGraphics2D::DrawLineProjected() instead
   */
  CS_DEPRECATED_METHOD_MSG("Use iGraphics2D::DrawLineProjected() instead")
  virtual void DrawLine (const csVector3& v1, const csVector3& v2,
    float fov, int color) = 0;

  /**
  * Activate the buffers in the default buffer holder.
  */
  virtual bool ActivateBuffers (csRenderBufferHolder* holder, 
    csRenderBufferName mapping[CS_VATTRIB_SPECIFIC_LAST+1]) = 0;

  /**
  * Activate all given buffers.
  */
  virtual bool ActivateBuffers (csVertexAttrib *attribs,
    iRenderBuffer **buffers, unsigned int count) = 0;

  /**
  * Deactivate all given buffers.
  * If attribs is 0, all buffers are deactivated;
  */
  virtual void DeactivateBuffers (csVertexAttrib *attribs, unsigned int count) = 0;

  /**
  * Activate or deactivate all given textures depending on the value
  * of the entry of \a textures for that unit (i.e. deactivate if 0). 
  * If \a textures itself is 0 all specified units are deactivated.
  */
  virtual void SetTextureState (int* units, iTextureHandle** textures,
    int count) = 0;


  /**
   * Set optional clipper to use. If clipper == null
   * then there is no clipper.
   * Currently only used by DrawTriangleMesh.
   */
  virtual void SetClipper (iClipper2D* clipper, int cliptype) = 0;

  /**
   * Get clipper that was used.
   */
  virtual iClipper2D* GetClipper () = 0;

  /**
   * Return type of clipper.
   */
  virtual int GetClipType () const = 0;

  /**
   * Set near clip plane.
   * The plane is in camera space.
   */
  virtual void SetNearPlane (const csPlane3& pl) = 0;

  /**
   * Reset near clip plane (i.e. disable it).
   */
  virtual void ResetNearPlane () = 0;

  /**
   * Get near clip plane.
   */
  virtual const csPlane3& GetNearPlane () const = 0;

  /**
   * Return true if we have a near plane.
   */
  virtual bool HasNearPlane () const = 0;

  /**
   * Set a renderstate value.
   * \deprecated Deprecated in 2.0. Use SetEdgeDrawing() for sole supported render state.
   */
  CS_DEPRECATED_METHOD_MSG("Use SetEdgeDrawing() for sole supported render state")
  virtual bool SetRenderState (G3D_RENDERSTATEOPTION op, long val) = 0;

  /**
   * Get a renderstate value.
   * \deprecated Deprecated in 2.0. Use SetEdgeDrawing() for sole supported render state.
   */
  CS_DEPRECATED_METHOD_MSG("Use GetEdgeDrawing() for sole supported render state")
  virtual long GetRenderState (G3D_RENDERSTATEOPTION op) const = 0;

  /**
   * Set a renderer specific option. Returns false if renderer doesn't
   * support that option.
   */
  virtual bool SetOption (const char*, const char*) = 0;
  
  /// Set the masking of color and/or alpha values to framebuffer
  virtual void SetWriteMask (bool red, bool green, bool blue, bool alpha) = 0;

  /// Get the masking of color and/or alpha values to framebuffer
  virtual void GetWriteMask (bool &red, bool &green, bool &blue,
	bool &alpha) const = 0;

  /// Set the z buffer write/test mode
  virtual void SetZMode (csZBufMode mode) = 0;

  /// Get the z buffer write/test mode
  virtual csZBufMode GetZMode () = 0;

  /**
   * \deprecated Deprecated in 1.3. Use RenderMeshModes::zoffset instead.
   */
  CS_DEPRECATED_METHOD_MSG("Nonfunctional. Use RenderMeshModes::zoffset instead")
  virtual void EnableZOffset () = 0;

  /**
   * \deprecated Deprecated in 1.3. Use RenderMeshModes::zoffset instead.
   */
  CS_DEPRECATED_METHOD_MSG("Nonfunctional. Use RenderMeshModes::zoffset instead")
  virtual void DisableZOffset () = 0;

  /// Controls shadow drawing
  virtual void SetShadowState (int state) = 0;

   /// Get Z-buffer value at given X,Y position
  virtual float GetZBuffValue (int x, int y) = 0;

  /**
   * Enter a new portal. 
   * If 'flags' contains CS_PORTAL_FLOAT then this routine will restrict
   * all further drawing to the given 2D area and it will also respect
   * the current contents of the Z-buffer so that geometry will only
   * render where the Z-buffer allows it (even if zfill or znone is used).
   * Remember to close a portal later using ClosePortal().
   * Basically this represents a stacked layer of portals. Each subsequent
   * portal must be fully contained in the previous ones.
   */
  virtual void OpenPortal (size_t numVertices, const csVector2* vertices,
    const csPlane3& normal, csFlags flags) = 0;

  /**
   * Close a portal previously opened with OpenPortal().
   * If 'zfill_portal' then the portal area will be zfilled.
   */
  virtual void ClosePortal () = 0;

  /// Create a halo of the specified color and return a handle.
  virtual iHalo *CreateHalo (float iR, float iG, float iB,
    unsigned char *iAlpha, int iWidth, int iHeight) = 0;

  /**
   * Set the world to camera transform.
   * This affects rendering in DrawMesh and DrawSimpleMesh.
   * \remarks 'this' space is world space, 'other' space is camera space
   */
  virtual void SetWorldToCamera (const csReversibleTransform& w2c) = 0;

  /**
   * Perform a system specific exension.<p>
   * The command is a string; any arguments may follow.
   * There is no way to guarantee the uniquiness of
   * commands, so please try to use descriptive command names rather
   * than "a", "b" and so on...
   */
  virtual bool PerformExtension (char const* command, ...) = 0;

  /**
   * Perform a system specific exension.<p>
   * Just like PerformExtension() except that the command arguments are passed
   * as a `va_list'.
   */
  virtual bool PerformExtensionV (char const* command, va_list) = 0;
  
  /**
   * Get the current world to camera transform.
   * \remarks 'this' space is world space, 'other' space is camera space
   */
  virtual const csReversibleTransform& GetWorldToCamera () = 0;
  /**
   * Get the current drawflags
   */
  virtual int GetCurrentDrawFlags() const = 0;
  
  virtual const CS::Math::Matrix4& GetProjectionMatrix() = 0;
  /**
   * Set the projection matrix to use.
   */
  virtual void SetProjectionMatrix (const CS::Math::Matrix4& m) = 0;

  /**
   * Set the texture comparison modes for the given texture units.
   */
  virtual void SetTextureComparisonModes (int* units, 
    CS::Graphics::TextureComparisonMode* texCompare,
    int count) = 0;
  
  /**
   * Copy the contents of the given render target attachments to the specified
   * textures.
   * \param num Number of attachment/texture pairs.
   * \param attachments Array of attachments from which to copy.
   * \param textures Array of texture to copy to.
   * \param subtextures Optional array of subtextures
   *   (cube map faces/volume slices) to copy to. If none is given a
   *   subtexture 0 is assumed for all targets.
   */
  virtual void CopyFromRenderTargets (size_t num, 
    csRenderTargetAttachment* attachments,
    iTextureHandle** textures,
    int* subtextures = 0) = 0;

  /**
   * Draw multiple csSimpleRenderMeshes.
   * \sa DrawSimpleMesh
   */
  virtual void DrawSimpleMeshes (const csSimpleRenderMesh* meshes,
    size_t numMeshes, uint flags = 0) = 0;

  /**\name Occlusion queries
   * @{ */
  /**
   * Initialise a set of occlusion queries.
   */
  virtual void OQInitQueries (unsigned int* queries, int num_queries) = 0;

  /// Delete a set of occlusion queries.
  virtual void OQDelQueries (unsigned int* queries, int num_queries) = 0;

  /**
   * Returns whether an occlusion query has finished.
   */
  virtual bool OQueryFinished (unsigned int occlusion_query) = 0;

  /**
   * Check via occlusion query whether a mesh is visible.
   */
  virtual bool OQIsVisible (unsigned int occlusion_query, unsigned int sampleLimit = 0) = 0;

  /// Start counting unoccluded fragments for a given query.
  virtual void OQBeginQuery (unsigned int occlusion_query) = 0;
  /// End counting unoccluded fragments for current query.
  virtual void OQEndQuery () = 0;
  /** @} */

  virtual void DrawMeshBasic(const CS::Graphics::CoreRenderMesh* mymesh,
							const CS::Graphics::RenderMeshModes& modes) = 0;
  
  /// Enable/disable edge drawing (for debugging purposes)
  virtual void SetEdgeDrawing (bool flag) = 0;
  /// Get state of edge drawing
  virtual bool GetEdgeDrawing () = 0;
};

/** @} */

#endif // __CS_IVIDEO_GRAPH3D_H__