diff --git a/changelog.md b/changelog.md index 826d4af..c8ee30d 100644 --- a/changelog.md +++ b/changelog.md @@ -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 diff --git a/src/engine/platform/win_qgl.c b/src/engine/platform/win_qgl.c index 3199280..2e4627f 100644 --- a/src/engine/platform/win_qgl.c +++ b/src/engine/platform/win_qgl.c @@ -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 ; diff --git a/src/engine/renderer/qgl.h b/src/engine/renderer/qgl.h index ec63110..8d5a23a 100644 --- a/src/engine/renderer/qgl.h +++ b/src/engine/renderer/qgl.h @@ -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); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 8f06d4d..066b43b 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -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 ); + /* ============================================================= diff --git a/src/engine/renderer/tr_shade.c b/src/engine/renderer/tr_shade.c index 1f63005..522fe28 100644 --- a/src/engine/renderer/tr_shade.c +++ b/src/engine/renderer/tr_shade.c @@ -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++ ) { diff --git a/src/engine/renderer/tr_sky.c b/src/engine/renderer/tr_sky.c index 2e2cde3..60536fc 100644 --- a/src/engine/renderer/tr_sky.c +++ b/src/engine/renderer/tr_sky.c @@ -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,31 +526,28 @@ 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++ ) - { - tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth ); - tess.numIndexes++; - tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth ); - tess.numIndexes++; - tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth ); - tess.numIndexes++; + for ( t = 0; t < tHeight-1; t++ ) + { + for ( s = 0; s < sWidth-1; s++ ) + { + tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth ); + tess.numIndexes++; + tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth ); + tess.numIndexes++; + tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth ); + tess.numIndexes++; - tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth ); - tess.numIndexes++; - tess.indexes[tess.numIndexes] = vertexStart + s + 1 + ( t + 1 ) * ( sWidth ); - tess.numIndexes++; - tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth ); - tess.numIndexes++; - } + tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth ); + tess.numIndexes++; + tess.indexes[tess.numIndexes] = vertexStart + s + 1 + ( t + 1 ) * ( sWidth ); + tess.numIndexes++; + tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth ); + tess.numIndexes++; } } } -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 ); - - qglPushMatrix (); + 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); + 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 diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 0436df3..10a5a29 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -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[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] }; - 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) diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index 73d80c4..4a5bc43 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -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;