Skybox rendering.

This commit is contained in:
Artem Kharytoniuk 2017-04-19 18:44:21 +03:00
parent ab32f499f8
commit 07f4d33492
8 changed files with 119 additions and 70 deletions

View File

@ -1,6 +1,7 @@
Removed cvars:
* r_allowExtensions (always use extensions if available)
* r_allowSoftwareGL
* r_clear
* r_colorbits (use desktop color depth)
* r_ext_multitexture (required)
* r_finish

View File

@ -92,7 +92,6 @@ void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalform
void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y);
void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
void ( APIENTRY * qglVertex3fv )(const GLfloat *v);
@ -152,7 +151,6 @@ static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint inter
static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param);
static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z);
static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y);
static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z);
static void ( APIENTRY * dllVertex3fv )(const GLfloat *v);
@ -593,11 +591,6 @@ static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset,
SIG( "glTexSubImage2D" );
dllTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels );
}
static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z)
{
SIG( "glTranslatef" );
dllTranslatef( x, y, z );
}
static void APIENTRY logVertex2f(GLfloat x, GLfloat y)
{
SIG( "glVertex2f" );
@ -694,7 +687,6 @@ void QGL_Shutdown( void )
qglTexParameterf = NULL;
qglTexParameterfv = NULL;
qglTexSubImage2D = NULL;
qglTranslatef = NULL;
qglVertex2f = NULL;
qglVertex3f = NULL;
qglVertex3fv = NULL;
@ -787,7 +779,6 @@ qboolean QGL_Init( const char *dllname )
qglTexParameterf = dllTexParameterf = (decltype(dllTexParameterf))GPA("glTexParameterf");
qglTexParameterfv = dllTexParameterfv = (decltype(dllTexParameterfv))GPA("glTexParameterfv");
qglTexSubImage2D = dllTexSubImage2D = (decltype(dllTexSubImage2D))GPA("glTexSubImage2D");
qglTranslatef = dllTranslatef = (decltype(dllTranslatef))GPA("glTranslatef");
qglVertex2f = dllVertex2f = (decltype(dllVertex2f))GPA("glVertex2f");
qglVertex3f = dllVertex3f = (decltype(dllVertex3f))GPA("glVertex3f");
qglVertex3fv = dllVertex3fv = (decltype(dllVertex3fv))GPA("glVertex3fv");
@ -904,7 +895,6 @@ void QGL_EnableLogging( qboolean enable )
qglTexParameterf = logTexParameterf ;
qglTexParameterfv = logTexParameterfv ;
qglTexSubImage2D = logTexSubImage2D ;
qglTranslatef = logTranslatef ;
qglVertex2f = logVertex2f ;
qglVertex3f = logVertex3f ;
qglVertex3fv = logVertex3fv ;
@ -970,7 +960,6 @@ void QGL_EnableLogging( qboolean enable )
qglTexParameterf = dllTexParameterf ;
qglTexParameterfv = dllTexParameterfv ;
qglTexSubImage2D = dllTexSubImage2D ;
qglTranslatef = dllTranslatef ;
qglVertex2f = dllVertex2f ;
qglVertex3f = dllVertex3f ;
qglVertex3fv = dllVertex3fv ;

View File

@ -113,7 +113,6 @@ extern void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint inte
extern void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
extern void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
extern void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
extern void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y);
extern void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
extern void ( APIENTRY * qglVertex3fv )(const GLfloat *v);

View File

@ -1351,9 +1351,7 @@ SKIES
============================================================
*/
void R_BuildCloudData( shaderCommands_t *shader );
void R_InitSkyTexCoords( float cloudLayerHeight );
void RB_ClipSkyPolygons( shaderCommands_t *shader );
/*
============================================================
@ -1408,7 +1406,6 @@ ANIMATED MODELS
=============================================================
*/
void R_MakeAnimModel( model_t *model );
void R_AddAnimSurfaces( trRefEntity_t *ent );
void RB_SurfaceAnim( md4Surface_t *surfType );
@ -1442,6 +1439,8 @@ void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors );
void RB_CalcSpecularAlpha( unsigned char *alphas );
void RB_CalcDiffuseColor( unsigned char *colors );
void myGlMultMatrix( const float *a, const float *b, float *out );
/*
=============================================================

View File

@ -792,7 +792,11 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
static void RB_IterateStagesGeneric( shaderCommands_t *input )
{
// VULKAN
vk_bind_resources_shared_between_stages(input->numPasses);
extern FILE* vk_log_file;
if (r_logFile->integer)
fprintf(vk_log_file, "vk_draw (passes %d, vert %d, inds %d)\n", input->numPasses, tess.numVertexes, tess.numIndexes);
vk_bind_resources_shared_between_stages();
for ( int stage = 0; stage < MAX_SHADER_STAGES; stage++ )
{

View File

@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define HALF_SKY_SUBDIVISIONS (SKY_SUBDIVISIONS/2)
static float s_cloudTexCoords[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
static float s_cloudTexP[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1];
/*
===================================================================================
@ -450,11 +449,58 @@ static void DrawSkyBox( shader_t *shader )
DrawSkySide( shader->sky.outerbox[sky_texorder[i]],
sky_mins_subd,
sky_maxs_subd );
// VULKAN
glState.vk_current_images[0] = shader->sky.outerbox[sky_texorder[i]];
tess.numVertexes = 0;
tess.numIndexes = 0;
for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t < sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ )
{
for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s < sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ )
{
int ndx = tess.numVertexes;
tess.indexes[ tess.numIndexes ] = ndx;
tess.indexes[ tess.numIndexes + 1 ] = ndx + 1;
tess.indexes[ tess.numIndexes + 2 ] = ndx + 2;
tess.indexes[ tess.numIndexes + 3 ] = ndx + 2;
tess.indexes[ tess.numIndexes + 4 ] = ndx + 1;
tess.indexes[ tess.numIndexes + 5 ] = ndx + 3;
tess.numIndexes += 6;
VectorCopy(s_skyPoints[t][s], tess.xyz[ndx]);
tess.svars.texcoords[0][ndx][0] = s_skyTexCoords[t][s][0];
tess.svars.texcoords[0][ndx][1] = s_skyTexCoords[t][s][1];
VectorCopy(s_skyPoints[t + 1][s], tess.xyz[ndx + 1]);
tess.svars.texcoords[0][ndx + 1][0] = s_skyTexCoords[t + 1][s][0];
tess.svars.texcoords[0][ndx + 1][1] = s_skyTexCoords[t + 1][s][1];
VectorCopy(s_skyPoints[t][s + 1], tess.xyz[ndx + 2]);
tess.svars.texcoords[0][ndx + 2][0] = s_skyTexCoords[t][s + 1][0];
tess.svars.texcoords[0][ndx + 2][1] = s_skyTexCoords[t][s + 1][1];
VectorCopy(s_skyPoints[t + 1][s + 1], tess.xyz[ndx + 3]);
tess.svars.texcoords[0][ndx + 3][0] = s_skyTexCoords[t + 1][s + 1][0];
tess.svars.texcoords[0][ndx + 3][1] = s_skyTexCoords[t + 1][s + 1][1];
tess.numVertexes += 4;
}
}
Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
vk_bind_resources_shared_between_stages();
vk_bind_stage_specific_resources(vk.skybox_pipeline, false, true);
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
glState.vk_dirty_attachments = true;
vk.xyz_elements += tess.numVertexes;
}
}
static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean addIndexes )
static void FillCloudySkySide( const int mins[2], const int maxs[2] )
{
int s, t;
int vertexStart = tess.numVertexes;
@ -480,8 +526,6 @@ static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean ad
}
}
// only add indexes for one pass, otherwise it would draw multiple times for each pass
if ( addIndexes ) {
for ( t = 0; t < tHeight-1; t++ )
{
for ( s = 0; s < sWidth-1; s++ )
@ -502,9 +546,8 @@ static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean ad
}
}
}
}
static void FillCloudBox( int stage )
static void FillCloudBox()
{
for ( int i = 0; i < 5; i++ )
{
@ -566,7 +609,7 @@ static void FillCloudBox( int stage )
}
// only add indexes for first stage
FillCloudySkySide( sky_mins_subd, sky_maxs_subd, (qboolean) ( stage == 0 ) );
FillCloudySkySide( sky_mins_subd, sky_maxs_subd);
}
}
@ -575,7 +618,6 @@ static void FillCloudBox( int stage )
*/
void R_BuildCloudData( shaderCommands_t *input )
{
int i;
shader_t *shader;
shader = input->shader;
@ -589,15 +631,9 @@ void R_BuildCloudData( shaderCommands_t *input )
tess.numIndexes = 0;
tess.numVertexes = 0;
if ( input->shader->sky.cloudHeight )
if ( input->shader->sky.cloudHeight && tess.xstages[0] )
{
for ( i = 0; i < MAX_SHADER_STAGES; i++ )
{
if ( !tess.xstages[i] ) {
break;
}
FillCloudBox( i );
}
FillCloudBox();
}
}
@ -643,8 +679,6 @@ void R_InitSkyTexCoords( float heightCloud )
2 * SQR( skyVec[2] ) * radiusWorld * heightCloud +
SQR( skyVec[2] ) * SQR( heightCloud ) ) );
s_cloudTexP[i][t][s] = p;
// compute intersection point based on p
VectorScale( skyVec, p, v );
v[2] += radiusWorld;
@ -692,15 +726,25 @@ void RB_StageIteratorSky( void ) {
// draw the outer skybox
if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) {
qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
float modelMatrix_original[16];
Com_Memcpy(modelMatrix_original, backEnd.or.modelMatrix, sizeof(float[16]));
float skybox_translate[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2], 1
};
myGlMultMatrix(skybox_translate, modelMatrix_original, backEnd.or.modelMatrix);
qglPushMatrix ();
GL_State( 0 );
qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
qglPushMatrix ();
qglLoadMatrixf(backEnd.or.modelMatrix);
DrawSkyBox( tess.shader );
qglPopMatrix();
Com_Memcpy(backEnd.or.modelMatrix, modelMatrix_original, sizeof(float[16]));
}
// generate the vertexes for all the clouds, which will be drawn

View File

@ -324,6 +324,8 @@ static VkRenderPass create_render_pass(VkDevice device, VkFormat color_format, V
return render_pass;
}
VkPipeline create_pipeline(const Vk_Pipeline_Desc&);
bool vk_initialize(HWND hwnd) {
try {
auto& g = vk;
@ -546,6 +548,19 @@ bool vk_initialize(HWND hwnd) {
vk.index_buffer_ptr = (byte*)data;
}
//
// Skybox pipeline.
//
{
Vk_Pipeline_Desc desc;
desc.shader_type = Vk_Shader_Type::single_texture;
desc.state_bits = 0;
desc.face_culling = CT_FRONT_SIDED;
desc.polygon_offset = false;
vk.skybox_pipeline = create_pipeline(desc);
}
} catch (const std::exception&) {
return false;
}
@ -579,6 +594,7 @@ void vk_deinitialize() {
vkDestroyPipelineLayout(vk.device, vk.pipeline_layout, nullptr);
vkDestroyBuffer(vk.device, vk.vertex_buffer, nullptr);
vkDestroyBuffer(vk.device, vk.index_buffer, nullptr);
vkDestroyPipeline(vk.device, vk.skybox_pipeline, nullptr);
vkDestroySwapchainKHR(g.device, g.swapchain, nullptr);
vkDestroyDevice(g.device, nullptr);
@ -1121,27 +1137,22 @@ void vk_get_mvp_transform(float mvp[16]) {
// update q3's proj matrix (opengl) to vulkan conventions: z - [0, 1] instead of [-1, 1] and invert y direction
float zNear = r_znear->value;
float zFar = tr.viewParms.zFar;
float p10 = -zFar / (zFar - zNear);
float p14 = -zFar*zNear / (zFar - zNear);
float p5 = -p[5];
float P10 = -zFar / (zFar - zNear);
float P14 = -zFar*zNear / (zFar - zNear);
float P5 = -p[5];
float proj[16] = {
p[0], p[1], p[2], p[3],
p[4], p5, p[6], p[7],
p[8], p[9], p10, p[11],
p[12], p[13], p14, p[15]
p[4], P5, p[6], p[7],
p[8], p[9], P10, p[11],
p[12], p[13], P14, p[15]
};
extern void myGlMultMatrix( const float *a, const float *b, float *out );
myGlMultMatrix(backEnd.or.modelMatrix, proj, mvp);
}
}
void vk_bind_resources_shared_between_stages(int num_passes) {
extern FILE* vk_log_file;
if (r_logFile->integer)
fprintf(vk_log_file, "render_tess (passes %d, vert %d, inds %d)\n", num_passes, tess.numVertexes, tess.numIndexes);
void vk_bind_resources_shared_between_stages() {
// xyz
{
if ((vk.xyz_elements + tess.numVertexes) * sizeof(vec4_t) > XYZ_SIZE)

View File

@ -18,7 +18,7 @@ void vk_destroy_resources();
VkRect2D vk_get_viewport_rect();
void vk_get_mvp_transform(float mvp[16]);
void vk_bind_resources_shared_between_stages(int num_passes);
void vk_bind_resources_shared_between_stages();
void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bool sky);
void vk_begin_frame();
@ -116,6 +116,8 @@ struct Vulkan_Instance {
VkDeviceMemory index_buffer_memory = VK_NULL_HANDLE;
byte* index_buffer_ptr = nullptr; // pointer to mapped index buffer
VkDeviceSize index_buffer_offset = 0;
VkPipeline skybox_pipeline = VK_NULL_HANDLE;
};
const int MAX_VK_PIPELINES = 1024;