2016-09-14 18:01:13 +00:00
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2005-2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
2013-06-23 07:49:34 +00:00
# ifndef __VERTEXBUFFER_H
# define __VERTEXBUFFER_H
# include "tarray.h"
2014-06-14 13:16:33 +00:00
# include "gl/utility/gl_clock.h"
2014-06-14 23:14:41 +00:00
# include "gl/system/gl_interface.h"
2013-06-23 07:49:34 +00:00
struct vertex_t ;
struct secplane_t ;
struct subsector_t ;
struct sector_t ;
2016-09-03 12:01:51 +00:00
enum
{
VATTR_VERTEX_BIT ,
VATTR_TEXCOORD_BIT ,
VATTR_COLOR_BIT ,
VATTR_VERTEX2_BIT ,
VATTR_NORMAL_BIT
} ;
2013-06-23 07:49:34 +00:00
class FVertexBuffer
{
protected :
unsigned int vbo_id ;
public :
2016-04-26 14:26:34 +00:00
FVertexBuffer ( bool wantbuffer = true ) ;
2013-06-23 07:49:34 +00:00
virtual ~ FVertexBuffer ( ) ;
2016-04-26 14:26:34 +00:00
virtual void BindVBO ( ) = 0 ;
2016-09-03 12:01:51 +00:00
void EnableBufferArrays ( int enable , int disable ) ;
2013-06-23 07:49:34 +00:00
} ;
2014-05-10 19:47:07 +00:00
struct FFlatVertex
2013-06-23 07:49:34 +00:00
{
2014-05-10 19:47:07 +00:00
float x , z , y ; // world position
2013-06-23 07:49:34 +00:00
float u , v ; // texture coordinates
void SetFlatVertex ( vertex_t * vt , const secplane_t & plane ) ;
2014-05-12 18:23:54 +00:00
void Set ( float xx , float zz , float yy , float uu , float vv )
{
x = xx ;
z = zz ;
y = yy ;
u = uu ;
v = vv ;
}
2016-08-08 10:13:09 +00:00
} ;
struct FSimpleVertex
{
float x , z , y ; // world position
float u , v ; // texture coordinates
PalEntry color ;
void Set ( float xx , float zz , float yy , float uu = 0 , float vv = 0 , PalEntry col = 0xffffffff )
{
x = xx ;
z = zz ;
y = yy ;
u = uu ;
v = vv ;
color = col ;
}
2013-06-23 07:49:34 +00:00
} ;
# define VTO ((FFlatVertex*)NULL)
2016-08-08 10:13:09 +00:00
# define VSiO ((FSimpleVertex*)NULL)
2013-06-23 07:49:34 +00:00
2016-08-06 22:40:31 +00:00
class FSimpleVertexBuffer : public FVertexBuffer
{
2016-08-08 10:13:09 +00:00
TArray < FSimpleVertex > mBuffer ;
2016-08-06 22:40:31 +00:00
public :
FSimpleVertexBuffer ( )
{
}
void BindVBO ( ) ;
2016-08-08 10:13:09 +00:00
void set ( FSimpleVertex * verts , int count ) ;
2016-08-08 14:18:07 +00:00
void EnableColorArray ( bool on ) ;
2016-08-06 22:40:31 +00:00
} ;
2013-06-23 07:49:34 +00:00
class FFlatVertexBuffer : public FVertexBuffer
{
FFlatVertex * map ;
2014-05-10 19:47:07 +00:00
unsigned int mIndex ;
2014-05-10 23:23:27 +00:00
unsigned int mCurIndex ;
2014-07-27 11:46:35 +00:00
unsigned int mNumReserved ;
2013-06-23 07:49:34 +00:00
void CheckPlanes ( sector_t * sector ) ;
2014-09-17 09:03:05 +00:00
static const unsigned int BUFFER_SIZE = 2000000 ;
static const unsigned int BUFFER_SIZE_TO_USE = 1999500 ;
2014-05-20 22:36:04 +00:00
2013-06-23 07:49:34 +00:00
public :
2016-08-25 20:23:31 +00:00
enum
{
QUAD_INDEX = 0 ,
FULLSCREEN_INDEX = 4 ,
2016-08-25 22:01:51 +00:00
PRESENT_INDEX = 8 ,
STENCILTOP_INDEX = 12 ,
STENCILBOTTOM_INDEX = 16 ,
NUM_RESERVED = 20
2016-08-25 20:23:31 +00:00
} ;
2014-06-14 23:14:41 +00:00
TArray < FFlatVertex > vbo_shadowdata ; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x
2013-06-23 07:49:34 +00:00
2016-08-08 12:24:48 +00:00
FFlatVertexBuffer ( int width , int height ) ;
2013-06-23 07:49:34 +00:00
~ FFlatVertexBuffer ( ) ;
2016-09-16 00:53:19 +00:00
void OutputResized ( int width , int height ) ;
2016-04-26 14:26:34 +00:00
void BindVBO ( ) ;
2014-05-10 19:47:07 +00:00
void CreateVBO ( ) ;
void CheckUpdate ( sector_t * sector ) ;
2014-05-10 23:23:27 +00:00
FFlatVertex * GetBuffer ( )
{
return & map [ mCurIndex ] ;
}
2016-08-22 12:00:25 +00:00
FFlatVertex * Alloc ( int num , int * poffset )
2014-05-10 23:23:27 +00:00
{
2016-08-22 12:00:25 +00:00
FFlatVertex * p = GetBuffer ( ) ;
* poffset = mCurIndex ;
mCurIndex + = num ;
if ( mCurIndex > = BUFFER_SIZE_TO_USE ) mCurIndex = mIndex ;
return p ;
}
2014-06-14 23:14:41 +00:00
2016-08-22 12:00:25 +00:00
unsigned int GetCount ( FFlatVertex * newptr , unsigned int * poffset )
{
2014-05-13 10:00:11 +00:00
unsigned int newofs = ( unsigned int ) ( newptr - map ) ;
2014-05-10 23:23:27 +00:00
unsigned int diff = newofs - mCurIndex ;
* poffset = mCurIndex ;
mCurIndex = newofs ;
2014-07-26 08:23:07 +00:00
if ( mCurIndex > = BUFFER_SIZE_TO_USE ) mCurIndex = mIndex ;
2014-05-10 23:23:27 +00:00
return diff ;
}
2014-05-20 20:37:38 +00:00
# ifdef __GL_PCH_H // we need the system includes for this but we cannot include them ourselves without creating #define clashes. The affected files wouldn't try to draw anyway.
2014-06-14 23:14:41 +00:00
void RenderArray ( unsigned int primtype , unsigned int offset , unsigned int count )
{
2014-07-13 21:14:28 +00:00
drawcalls . Clock ( ) ;
2016-08-06 10:03:16 +00:00
glDrawArrays ( primtype , offset , count ) ;
2014-07-13 21:14:28 +00:00
drawcalls . Unclock ( ) ;
2014-06-14 23:14:41 +00:00
}
2014-06-14 13:16:33 +00:00
void RenderCurrent ( FFlatVertex * newptr , unsigned int primtype , unsigned int * poffset = NULL , unsigned int * pcount = NULL )
2014-05-20 20:37:38 +00:00
{
unsigned int offset ;
unsigned int count = GetCount ( newptr , & offset ) ;
2014-06-14 23:14:41 +00:00
RenderArray ( primtype , offset , count ) ;
2014-06-14 13:16:33 +00:00
if ( poffset ) * poffset = offset ;
if ( pcount ) * pcount = count ;
2014-05-20 20:37:38 +00:00
}
2014-06-14 23:14:41 +00:00
2014-05-20 20:37:38 +00:00
# endif
2014-05-10 23:23:27 +00:00
void Reset ( )
{
mCurIndex = mIndex ;
}
2016-08-29 08:43:03 +00:00
void Map ( ) ;
void Unmap ( ) ;
2014-05-10 19:47:07 +00:00
private :
2013-06-23 07:49:34 +00:00
int CreateSubsectorVertices ( subsector_t * sub , const secplane_t & plane , int floor ) ;
int CreateSectorVertices ( sector_t * sec , const secplane_t & plane , int floor ) ;
int CreateVertices ( int h , sector_t * sec , const secplane_t & plane , int floor ) ;
void CreateFlatVBO ( ) ;
void UpdatePlaneVertices ( sector_t * sec , int plane ) ;
} ;
2014-06-13 23:24:28 +00:00
struct FSkyVertex
{
float x , y , z , u , v ;
PalEntry color ;
2014-06-14 08:38:30 +00:00
void Set ( float xx , float zz , float yy , float uu = 0 , float vv = 0 , PalEntry col = 0xffffffff )
{
x = xx ;
z = zz ;
y = yy ;
u = uu ;
v = vv ;
color = col ;
}
2016-08-06 09:47:03 +00:00
void SetXYZ ( float xx , float yy , float zz , float uu = 0 , float vv = 0 , PalEntry col = 0xffffffff )
{
x = xx ;
y = yy ;
z = zz ;
u = uu ;
v = vv ;
color = col ;
}
2014-06-13 23:24:28 +00:00
} ;
class FSkyVertexBuffer : public FVertexBuffer
{
public :
static const int SKYHEMI_UPPER = 1 ;
static const int SKYHEMI_LOWER = 2 ;
enum
{
SKYMODE_MAINLAYER = 0 ,
SKYMODE_SECONDLAYER = 1 ,
SKYMODE_FOGLAYER = 2
} ;
private :
TArray < FSkyVertex > mVertices ;
TArray < unsigned int > mPrimStart ;
int mRows , mColumns ;
2016-08-04 10:16:53 +00:00
// indices for sky cubemap faces
int mFaceStart [ 7 ] ;
int mSideStart ;
2014-06-13 23:24:28 +00:00
void SkyVertex ( int r , int c , bool yflip ) ;
void CreateSkyHemisphere ( int hemi ) ;
void CreateDome ( ) ;
2014-06-14 13:16:33 +00:00
void RenderRow ( int prim , int row ) ;
2014-06-13 23:24:28 +00:00
public :
FSkyVertexBuffer ( ) ;
virtual ~ FSkyVertexBuffer ( ) ;
void RenderDome ( FMaterial * tex , int mode ) ;
2016-04-26 14:26:34 +00:00
void BindVBO ( ) ;
2016-08-04 10:16:53 +00:00
int FaceStart ( int i )
{
if ( i > = 0 & & i < 7 ) return mFaceStart [ i ] ;
else return mSideStart ;
}
2014-06-13 23:24:28 +00:00
} ;
# define VSO ((FSkyVertex*)NULL)
2014-06-15 19:56:37 +00:00
struct FModelVertex
{
float x , y , z ; // world position
float u , v ; // texture coordinates
2016-10-03 14:09:32 +00:00
unsigned packedNormal ; // normal vector as GL_INT_2_10_10_10_REV.
2014-06-15 19:56:37 +00:00
void Set ( float xx , float yy , float zz , float uu , float vv )
{
x = xx ;
y = yy ;
z = zz ;
u = uu ;
v = vv ;
}
2014-06-19 15:06:26 +00:00
void SetNormal ( float nx , float ny , float nz )
{
2016-10-03 14:09:32 +00:00
/*
int inx = int ( nx * 512 ) ;
int iny = int ( ny * 512 ) ;
int inz = int ( nz * 512 ) ;
packedNormal = 0x40000000 | ( ( inx & 1023 ) < < 20 ) | ( ( iny & 1023 ) < < 10 ) | ( inz & 1023 ) ;
*/
packedNormal = 0 ; // Per-pixel lighting for models isn't implemented yet so leave this at 0 for now.
2014-06-19 15:06:26 +00:00
}
2014-06-15 19:56:37 +00:00
} ;
class FModelVertexBuffer : public FVertexBuffer
{
int mIndexFrame [ 2 ] ;
2016-05-03 11:10:00 +00:00
FModelVertex * vbo_ptr ;
uint32_t ibo_id ;
2014-06-15 19:56:37 +00:00
public :
2016-05-03 11:10:00 +00:00
FModelVertexBuffer ( bool needindex , bool singleframe ) ;
2014-06-15 19:56:37 +00:00
~ FModelVertexBuffer ( ) ;
2014-10-24 09:43:25 +00:00
FModelVertex * LockVertexBuffer ( unsigned int size ) ;
void UnlockVertexBuffer ( ) ;
unsigned int * LockIndexBuffer ( unsigned int size ) ;
void UnlockIndexBuffer ( ) ;
2016-05-03 11:10:00 +00:00
unsigned int SetupFrame ( unsigned int frame1 , unsigned int frame2 , unsigned int size ) ;
2016-04-26 14:26:34 +00:00
void BindVBO ( ) ;
2014-06-15 19:56:37 +00:00
} ;
# define VMO ((FModelVertex*)NULL)
2014-06-13 23:24:28 +00:00
2013-06-23 07:49:34 +00:00
# endif