hedgewars/uStore.pas
changeset 10304 7e40820b7ed6
parent 10302 ea0b0e2efd95
child 10309 e338ccbbe100
equal deleted inserted replaced
10303:f726e36c3e24 10304:7e40820b7ed6
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 {$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
    20 {$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
    21 
    21 
    22 unit uStore;
    22 unit uStore;
    23 interface
    23 interface
    24 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
    24 uses SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
    25 
    25 
    26 procedure initModule;
    26 procedure initModule;
    27 procedure freeModule;
    27 procedure freeModule;
    28 
    28 
    29 procedure StoreLoad(reload: boolean);
    29 procedure StoreLoad(reload: boolean);
    60 procedure WarpMouse(x, y: Word); inline;
    60 procedure WarpMouse(x, y: Word); inline;
    61 {$ENDIF}
    61 {$ENDIF}
    62 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
    62 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
    63 procedure SetSkyColor(r, g, b: real);
    63 procedure SetSkyColor(r, g, b: real);
    64 
    64 
    65 {$IFDEF GL2}
       
    66 var
       
    67     shaderMain: GLuint;
       
    68     shaderWater: GLuint;
       
    69 {$ENDIF}
       
    70 
       
    71 implementation
    65 implementation
    72 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils,
    66 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils,
    73      uCommands, uPhysFSLayer, uDebug
    67      uCommands, uPhysFSLayer, uDebug
    74     {$IFDEF GL2}, uMatrix{$ENDIF}
       
    75     {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}
    68     {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}
    76     {$IF NOT DEFINED(SDL2) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF};
    69     {$IF NOT DEFINED(SDL2) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF};
    77 
    70 
    78 var MaxTextureSize: LongInt;
    71 var
    79 {$IFDEF SDL2}
    72 {$IFDEF SDL2}
    80     SDLwindow: PSDL_Window;
    73     SDLwindow: PSDL_Window;
    81     SDLGLcontext: PSDL_GLContext;
    74     SDLGLcontext: PSDL_GLContext;
    82 {$ELSE}
    75 {$ELSE}
    83     SDLPrimSurface: PSDL_Surface;
    76     SDLPrimSurface: PSDL_Surface;
   790     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);         // no alpha channel
   783     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);         // no alpha channel
   791     SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);       // buffer should be 16
   784     SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);       // buffer should be 16
   792     SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // prefer hw rendering
   785     SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // prefer hw rendering
   793 end;
   786 end;
   794 
   787 
   795 {$IFDEF GL2}
       
   796 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint;
       
   797 var
       
   798     shader: GLuint;
       
   799     f: Textfile;
       
   800     source, line: AnsiString;
       
   801     sourceA: Pchar;
       
   802     lengthA: GLint;
       
   803     compileResult: GLint;
       
   804     logLength: GLint;
       
   805     log: PChar;
       
   806 begin
       
   807     Assign(f, PathPrefix + cPathz[ptShaders] + '/' + shaderFile);
       
   808     filemode:= 0; // readonly
       
   809     Reset(f);
       
   810     if IOResult <> 0 then
       
   811     begin
       
   812         AddFileLog('Unable to load ' + shaderFile);
       
   813         halt(-1);
       
   814     end;
       
   815 
       
   816     source:='';
       
   817     while not eof(f) do
       
   818     begin
       
   819         ReadLn(f, line);
       
   820         source:= source + line + #10;
       
   821     end;
       
   822 
       
   823     Close(f);
       
   824 
       
   825     WriteLnToConsole('Compiling shader: ' + PathPrefix + cPathz[ptShaders] + '/' + shaderFile);
       
   826 
       
   827     sourceA:=PChar(source);
       
   828     lengthA:=Length(source);
       
   829 
       
   830     shader:=glCreateShader(shaderType);
       
   831     glShaderSource(shader, 1, @sourceA, @lengthA);
       
   832     glCompileShader(shader);
       
   833     glGetShaderiv(shader, GL_COMPILE_STATUS, @compileResult);
       
   834     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, @logLength);
       
   835 
       
   836     if logLength > 1 then
       
   837     begin
       
   838         log := GetMem(logLength);
       
   839         glGetShaderInfoLog(shader, logLength, nil, log);
       
   840         WriteLnToConsole('========== Compiler log  ==========');
       
   841         WriteLnToConsole(shortstring(log));
       
   842         WriteLnToConsole('===================================');
       
   843         FreeMem(log, logLength);
       
   844     end;
       
   845 
       
   846     if compileResult <> GL_TRUE then
       
   847     begin
       
   848         WriteLnToConsole('Shader compilation failed, halting');
       
   849         halt(-1);
       
   850     end;
       
   851 
       
   852     CompileShader:= shader;
       
   853 end;
       
   854 
       
   855 function CompileProgram(shaderName: string): GLuint;
       
   856 var
       
   857     program_: GLuint;
       
   858     vs, fs: GLuint;
       
   859     linkResult: GLint;
       
   860     logLength: GLint;
       
   861     log: PChar;
       
   862 begin
       
   863     program_:= glCreateProgram();
       
   864     vs:= CompileShader(shaderName + '.vs', GL_VERTEX_SHADER);
       
   865     fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER);
       
   866     glAttachShader(program_, vs);
       
   867     glAttachShader(program_, fs);
       
   868 
       
   869     glBindAttribLocation(program_, aVertex, PChar('vertex'));
       
   870     glBindAttribLocation(program_, aTexCoord, PChar('texcoord'));
       
   871     glBindAttribLocation(program_, aColor, PChar('color'));
       
   872 
       
   873     glLinkProgram(program_);
       
   874     glDeleteShader(vs);
       
   875     glDeleteShader(fs);
       
   876 
       
   877     glGetProgramiv(program_, GL_LINK_STATUS, @linkResult);
       
   878     glGetProgramiv(program_, GL_INFO_LOG_LENGTH, @logLength);
       
   879 
       
   880     if logLength > 1 then
       
   881     begin
       
   882         log := GetMem(logLength);
       
   883         glGetProgramInfoLog(program_, logLength, nil, log);
       
   884         WriteLnToConsole('========== Compiler log  ==========');
       
   885         WriteLnToConsole(shortstring(log));
       
   886         WriteLnToConsole('===================================');
       
   887         FreeMem(log, logLength);
       
   888     end;
       
   889 
       
   890     if linkResult <> GL_TRUE then
       
   891     begin
       
   892         WriteLnToConsole('Linking program failed, halting');
       
   893         halt(-1);
       
   894     end;
       
   895 
       
   896     CompileProgram:= program_;
       
   897 end;
       
   898 
       
   899 {$ENDIF}
       
   900 
       
   901 procedure SetupOpenGL;
   788 procedure SetupOpenGL;
   902 var buf: array[byte] of char;
   789 var buf: array[byte] of char;
   903     AuxBufNum: LongInt = 0;
       
   904     tmpstr: ansistring;
       
   905     tmpint: LongInt;
       
   906     tmpn: LongInt;
       
   907 begin
   790 begin
   908 
   791 
   909 {$IFDEF SDL2}
   792 {$IFDEF SDL2}
   910     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
   793     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
   911 {$ELSE}
   794 {$ELSE}
   912     buf[0]:= char(0); // avoid compiler hint
   795     buf[0]:= char(0); // avoid compiler hint
   913     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
   796     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')');
   914 {$ENDIF}
   797 {$ENDIF}
   915 
       
   916     AuxBufNum:= AuxBufNum;
       
   917 
   798 
   918 {$IFDEF MOBILE}
   799 {$IFDEF MOBILE}
   919     // TODO: this function creates an opengles1.1 context
   800     // TODO: this function creates an opengles1.1 context
   920     // un-comment below and add proper logic to support opengles2.0
   801     // un-comment below and add proper logic to support opengles2.0
   921     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
   802     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
   924         SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
   805         SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
   925     SDLTry(SDLGLcontext <> nil, true);
   806     SDLTry(SDLGLcontext <> nil, true);
   926     SDL_GL_SetSwapInterval(1);
   807     SDL_GL_SetSwapInterval(1);
   927 {$ENDIF}
   808 {$ENDIF}
   928 
   809 
   929     // get the max (h and v) size for textures that the gpu can support
   810     RenderSetup();
   930     glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize);
       
   931     if MaxTextureSize <= 0 then
       
   932         begin
       
   933         MaxTextureSize:= 1024;
       
   934         AddFileLog('OpenGL Warning - driver didn''t provide any valid max texture size; assuming 1024');
       
   935         end
       
   936     else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then
       
   937         begin
       
   938         cReducedQuality := cReducedQuality or rqNoBackground;
       
   939         AddFileLog('Texture size too small for backgrounds, disabling.');
       
   940         end;
       
   941     // everyone loves debugging
       
   942     // find out which gpu we are using (for extension compatibility maybe?)
       
   943     AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER))));
       
   944     AddFileLog('  |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR))));
       
   945     AddFileLog('  |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION))));
       
   946     AddFileLog('  |----- Texture Size: ' + inttostr(MaxTextureSize));
       
   947 {$IFDEF USE_VIDEO_RECORDING}
       
   948     glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum);
       
   949     AddFileLog('  |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum));
       
   950 {$ENDIF}
       
   951 {$IFNDEF PAS2C}
       
   952     AddFileLog('  \----- Extensions: ');
       
   953 
       
   954     // fetch extentions and store them in string
       
   955     tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS)));
       
   956     tmpn := WordCount(tmpstr, [' ']);
       
   957     tmpint := 1;
       
   958 
       
   959     repeat
       
   960     begin
       
   961         // print up to 3 extentions per row
       
   962         // ExtractWord will return empty string if index out of range
       
   963         AddFileLog(TrimRight(
       
   964             ExtractWord(tmpint, tmpstr, [' ']) + ' ' +
       
   965             ExtractWord(tmpint+1, tmpstr, [' ']) + ' ' +
       
   966             ExtractWord(tmpint+2, tmpstr, [' '])
       
   967         ));
       
   968         tmpint := tmpint + 3;
       
   969     end;
       
   970     until (tmpint > tmpn);
       
   971 {$ENDIF}
       
   972     AddFileLog('');
       
   973 
       
   974     defaultFrame:= 0;
       
   975 {$IFDEF USE_VIDEO_RECORDING}
       
   976     if GameType = gmtRecord then
       
   977     begin
       
   978         if glLoadExtension('GL_EXT_framebuffer_object') then
       
   979         begin
       
   980             CreateFramebuffer(defaultFrame, depthv, texv);
       
   981             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame);
       
   982             AddFileLog('Using framebuffer for video recording.');
       
   983         end
       
   984         else if AuxBufNum > 0 then
       
   985         begin
       
   986             glDrawBuffer(GL_AUX0);
       
   987             glReadBuffer(GL_AUX0);
       
   988             AddFileLog('Using auxiliary buffer for video recording.');
       
   989         end
       
   990         else
       
   991         begin
       
   992             glDrawBuffer(GL_BACK);
       
   993             glReadBuffer(GL_BACK);
       
   994             AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.');
       
   995         end;
       
   996     end;
       
   997 {$ENDIF}
       
   998 
       
   999 {$IFDEF GL2}
       
  1000 
       
  1001 {$IFDEF PAS2C}
       
  1002     err := glewInit();
       
  1003     if err <> GLEW_OK then
       
  1004     begin
       
  1005         WriteLnToConsole('Failed to initialize GLEW.');
       
  1006         halt;
       
  1007     end;
       
  1008 {$ENDIF}
       
  1009 
       
  1010 {$IFNDEF PAS2C}
       
  1011     if not Load_GL_VERSION_2_0 then
       
  1012         halt;
       
  1013 {$ENDIF}
       
  1014 
       
  1015     shaderWater:= CompileProgram('water');
       
  1016     glUseProgram(shaderWater);
       
  1017     glUniform1i(glGetUniformLocation(shaderWater, pchar('tex0')), 0);
       
  1018     uWaterMVPLocation:= glGetUniformLocation(shaderWater, pchar('mvp'));
       
  1019 
       
  1020     shaderMain:= CompileProgram('default');
       
  1021     glUseProgram(shaderMain);
       
  1022     glUniform1i(glGetUniformLocation(shaderMain, pchar('tex0')), 0);
       
  1023     uMainMVPLocation:= glGetUniformLocation(shaderMain, pchar('mvp'));
       
  1024     uMainTintLocation:= glGetUniformLocation(shaderMain, pchar('tint'));
       
  1025 
       
  1026     uCurrentMVPLocation:= uMainMVPLocation;
       
  1027 
       
  1028     Tint(255, 255, 255, 255);
       
  1029     UpdateModelviewProjection;
       
  1030 {$ENDIF}
       
  1031 
       
  1032 {$IFNDEF USE_S3D_RENDERING}
       
  1033     if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
       
  1034     begin
       
  1035         // prepare left and right frame buffers and associated textures
       
  1036         if glLoadExtension('GL_EXT_framebuffer_object') then
       
  1037             begin
       
  1038             CreateFramebuffer(framel, depthl, texl);
       
  1039             CreateFramebuffer(framer, depthr, texr);
       
  1040 
       
  1041             // reset
       
  1042             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame)
       
  1043             end
       
  1044         else
       
  1045             cStereoMode:= smNone;
       
  1046     end;
       
  1047 {$ENDIF}
       
  1048 
       
  1049 // set view port to whole window
       
  1050 glViewport(0, 0, cScreenWidth, cScreenHeight);
       
  1051 
       
  1052 {$IFDEF GL2}
       
  1053     uMatrix.initModule;
       
  1054     hglMatrixMode(MATRIX_MODELVIEW);
       
  1055     // prepare default translation/scaling
       
  1056     hglLoadIdentity();
       
  1057     hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
       
  1058     hglTranslatef(0, -cScreenHeight / 2, 0);
       
  1059 
       
  1060     EnableTexture(True);
       
  1061 
       
  1062     glEnableVertexAttribArray(aVertex);
       
  1063     glEnableVertexAttribArray(aTexCoord);
       
  1064     glGenBuffers(1, @vBuffer);
       
  1065     glGenBuffers(1, @tBuffer);
       
  1066     glGenBuffers(1, @cBuffer);
       
  1067 {$ELSE}
       
  1068     glMatrixMode(GL_MODELVIEW);
       
  1069     // prepare default translation/scaling
       
  1070     glLoadIdentity();
       
  1071     glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
       
  1072     glTranslatef(0, -cScreenHeight / 2, 0);
       
  1073 
       
  1074     // disable/lower perspective correction (will not need it anyway)
       
  1075     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
       
  1076     // disable dithering
       
  1077     glDisable(GL_DITHER);
       
  1078     // enable common states by default as they save a lot
       
  1079     glEnable(GL_TEXTURE_2D);
       
  1080     glEnableClientState(GL_VERTEX_ARRAY);
       
  1081     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  1082 {$ENDIF}
       
  1083 
       
  1084     // enable alpha blending
       
  1085     glEnable(GL_BLEND);
       
  1086     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       
  1087     // disable/lower perspective correction (will not need it anyway)
       
  1088 end;
   811 end;
  1089 
   812 
  1090 (*
   813 (*
  1091 procedure UpdateProjection;
   814 procedure UpdateProjection;
  1092 var
   815 var
  1131         {$ENDIF}
   854         {$ENDIF}
  1132         end;
   855         end;
  1133 
   856 
  1134     TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
   857     TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
  1135 
   858 
  1136     glClear(GL_COLOR_BUFFER_BIT);
   859     RenderClear();
  1137     if Step < numsquares then
   860     if Step < numsquares then
  1138         r.x:= 0
   861         r.x:= 0
  1139     else
   862     else
  1140         r.x:= squaresize;
   863         r.x:= squaresize;
  1141 
   864 
  1368     // we do not need a window, but without this call OpenGL will not initialize
  1091     // we do not need a window, but without this call OpenGL will not initialize
  1369     glutCreateWindow('hedgewars video rendering (glut hidden window)');
  1092     glutCreateWindow('hedgewars video rendering (glut hidden window)');
  1370     glutHideWindow();
  1093     glutHideWindow();
  1371     // we do not need to set this callback, but it is required for GLUT3 compat
  1094     // we do not need to set this callback, but it is required for GLUT3 compat
  1372     glutDisplayFunc(@SwapBuffers);
  1095     glutDisplayFunc(@SwapBuffers);
  1373     SetupOpenGL();
  1096     SetupRenderer();
  1374 end;
  1097 end;
  1375 {$ENDIF} // SDL2
  1098 {$ENDIF} // SDL2
  1376 {$ENDIF} // USE_VIDEO_RECORDING
  1099 {$ENDIF} // USE_VIDEO_RECORDING
  1377 
  1100 
  1378 procedure chFullScr(var s: shortstring);
  1101 procedure chFullScr(var s: shortstring);
  1507     SetupOpenGL();
  1230     SetupOpenGL();
  1508 
  1231 
  1509     if reinit then
  1232     if reinit then
  1510         begin
  1233         begin
  1511         // clean the window from any previous content
  1234         // clean the window from any previous content
  1512         glClear(GL_COLOR_BUFFER_BIT);
  1235         RenderClear();
  1513         if SuddenDeathDmg then
  1236         if SuddenDeathDmg then
  1514             SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255)
  1237             SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255)
  1515         else if ((cReducedQuality and rqNoBackground) = 0) then
  1238         else if ((cReducedQuality and rqNoBackground) = 0) then
  1516             SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255)
  1239             SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255)
  1517         else
  1240         else
  1548 {$ENDIF}
  1271 {$ENDIF}
  1549 end;
  1272 end;
  1550 
  1273 
  1551 procedure SetSkyColor(r, g, b: real);
  1274 procedure SetSkyColor(r, g, b: real);
  1552 begin
  1275 begin
  1553     glClearColor(r, g, b, 0.99)
  1276     RenderSetClearColor(r, g, b, 0.99)
  1554 end;
  1277 end;
  1555 
  1278 
  1556 procedure initModule;
  1279 procedure initModule;
  1557 var ai: TAmmoType;
  1280 var ai: TAmmoType;
  1558     i: LongInt;
  1281     i: LongInt;
  1584     tmpHatSurf:= nil;
  1307     tmpHatSurf:= nil;
  1585 end;
  1308 end;
  1586 
  1309 
  1587 procedure freeModule;
  1310 procedure freeModule;
  1588 begin
  1311 begin
  1589 {$IFDEF GL2}
       
  1590     glDeleteProgram(shaderMain);
       
  1591     glDeleteProgram(shaderWater);
       
  1592     glDeleteBuffers(1, @vBuffer);
       
  1593     glDeleteBuffers(1, @tBuffer);
       
  1594     glDeleteBuffers(1, @cBuffer);
       
  1595 {$ENDIF}
       
  1596     StoreRelease(false);
  1312     StoreRelease(false);
  1597     TTF_Quit();
  1313     TTF_Quit();
  1598 {$IFDEF SDL2}
  1314 {$IFDEF SDL2}
  1599     SDL_GL_DeleteContext(SDLGLcontext);
  1315     SDL_GL_DeleteContext(SDLGLcontext);
  1600     SDL_DestroyWindow(SDLwindow);
  1316     SDL_DestroyWindow(SDLwindow);