# HG changeset patch # User sheepluva # Date 1402753784 -7200 # Node ID 7e40820b7ed695f8e262de2d342a7b5b59e4f444 # Parent f726e36c3e2499ee4312cbab5588fb7d0248d7ab fix gl2 build, further rendering cleanup WIP, also new chat command: /debugvl diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/hwengine.pas Sat Jun 14 15:49:44 2014 +0200 @@ -32,7 +32,7 @@ uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler , uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions , SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted - , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers, uTextures + , uPhysFSLayer, uCursor, uRandom, ArgParsers, uVisualGearsHandlers, uTextures, uRender {$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF} {$IFDEF USE_TOUCH_INTERFACE}, uTouch {$ENDIF} {$IFDEF ANDROID}, GLUnit{$ENDIF} @@ -479,6 +479,7 @@ uSound.initModule; uStats.initModule; uStore.initModule; + uRender.initModule; uTeams.initModule; uVisualGears.initModule; uVisualGearsHandlers.initModule; @@ -507,6 +508,7 @@ uCollisions.freeModule; //stub uChat.freeModule; uAmmos.freeModule; + uRender.freeModule; uStore.freeModule; // closes SDL {$IFDEF USE_VIDEO_RECORDING}uVideoRec.freeModule;{$ENDIF} {$IFDEF USE_TOUCH_INTERFACE}uTouch.freeModule;{$ENDIF} //stub diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/uChat.pas --- a/hedgewars/uChat.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/uChat.pas Sat Jun 14 15:49:44 2014 +0200 @@ -288,7 +288,7 @@ if (s[1] = '/') then begin // These 3 are same as above, only are to make the hedgehog say it on next attack - if (copy(s, 1, 5) = '/hsa ') then + if (copy(s, 2, 4) = 'hsa ') then begin if CurrentTeam^.ExtDriven then ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) @@ -297,7 +297,7 @@ exit end; - if (copy(s, 1, 5) = '/hta ') then + if (copy(s, 2, 4) = 'hta ') then begin if CurrentTeam^.ExtDriven then ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) @@ -306,7 +306,7 @@ exit end; - if (copy(s, 1, 5) = '/hya ') then + if (copy(s, 2, 4) = 'hya ') then begin if CurrentTeam^.ExtDriven then ParseCommand('/say ' + copy(s, 6, Length(s)-5), true) @@ -315,18 +315,27 @@ exit end; - if (copy(s, 1, 6) = '/team ') and (length(s) > 6) then + if (copy(s, 2, 5) = 'team ') and (length(s) > 6) then begin ParseCommand(s, true); exit end; - if (copy(s, 1, 4) = '/me ') then + if (copy(s, 2, 3) = 'me ') then begin ParseCommand('/say ' + s, true); exit end; + // debugging commands + if (copy(s, 2, 7) = 'debugvl') then + begin + cViewLimitsDebug:= (not cViewLimitsDebug); + UpdateViewLimits(); + exit + end; + end; + if (not CurrentTeam^.ExtDriven) and (CurrentTeam^.Hedgehogs[0].BotLevel = 0) then begin for i:= Low(TWave) to High(TWave) do @@ -343,7 +352,6 @@ exit end; end - end else ParseCommand('/say ' + s, true); end; diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/uRender.pas --- a/hedgewars/uRender.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/uRender.pas Sat Jun 14 15:49:44 2014 +0200 @@ -23,7 +23,10 @@ interface -uses SDLh, uTypes, GLunit, uConsts{$IFDEF GL2}, uMatrix{$ENDIF}; +uses SDLh, uTypes, GLunit; + +procedure initModule; +procedure freeModule; procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); @@ -48,11 +51,13 @@ procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); -procedure DrawFillRect (r: TSDL_Rect); +procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); procedure DrawScreenWidget (widget: POnScreenWidget); procedure DrawWaterBody (pVertexBuffer: Pointer); +procedure RenderClear (); +procedure RenderSetClearColor (r, g, b, a: real); procedure Tint (r, g, b, a: Byte); inline; procedure Tint (c: Longword); inline; procedure untint(); inline; @@ -67,6 +72,10 @@ procedure SetScale(f: GLfloat); procedure UpdateViewLimits(); +procedure RenderSetup(); + +// TODO everything below this should not need a public interface + procedure EnableTexture(enable:Boolean); procedure SetTexCoordPointer(p: Pointer;n: Integer); @@ -86,7 +95,8 @@ implementation -uses uVariables; +uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uVariables, uUtils, uConsts + {$IFDEF GL2}, uMatrix, uConsole{$ENDIF}; {$IFDEF USE_TOUCH_INTERFACE} const @@ -94,6 +104,12 @@ MOVE_ANIM_TIME = 500; {$ENDIF} +{$IFDEF GL2} +var + shaderMain: GLuint; + shaderWater: GLuint; +{$ENDIF} + var LastTint: LongWord = 0; function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; @@ -115,6 +131,292 @@ isDyAreaOffscreen:= 0; end; +procedure RenderClear(); +begin + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); +end; + +procedure RenderSetClearColor(r, g, b, a: real); +begin + glClearColor(r, g, b, a); +end; + +{$IFDEF GL2} +function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; +var + shader: GLuint; + f: Textfile; + source, line: AnsiString; + sourceA: Pchar; + lengthA: GLint; + compileResult: GLint; + logLength: GLint; + log: PChar; +begin + Assign(f, PathPrefix + cPathz[ptShaders] + '/' + shaderFile); + filemode:= 0; // readonly + Reset(f); + if IOResult <> 0 then + begin + AddFileLog('Unable to load ' + shaderFile); + halt(-1); + end; + + source:=''; + while not eof(f) do + begin + ReadLn(f, line); + source:= source + line + #10; + end; + + Close(f); + + WriteLnToConsole('Compiling shader: ' + PathPrefix + cPathz[ptShaders] + '/' + shaderFile); + + sourceA:=PChar(source); + lengthA:=Length(source); + + shader:=glCreateShader(shaderType); + glShaderSource(shader, 1, @sourceA, @lengthA); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, @compileResult); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, @logLength); + + if logLength > 1 then + begin + log := GetMem(logLength); + glGetShaderInfoLog(shader, logLength, nil, log); + WriteLnToConsole('========== Compiler log =========='); + WriteLnToConsole(shortstring(log)); + WriteLnToConsole('==================================='); + FreeMem(log, logLength); + end; + + if compileResult <> GL_TRUE then + begin + WriteLnToConsole('Shader compilation failed, halting'); + halt(-1); + end; + + CompileShader:= shader; +end; + +function CompileProgram(shaderName: string): GLuint; +var + program_: GLuint; + vs, fs: GLuint; + linkResult: GLint; + logLength: GLint; + log: PChar; +begin + program_:= glCreateProgram(); + vs:= CompileShader(shaderName + '.vs', GL_VERTEX_SHADER); + fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER); + glAttachShader(program_, vs); + glAttachShader(program_, fs); + + glBindAttribLocation(program_, aVertex, PChar('vertex')); + glBindAttribLocation(program_, aTexCoord, PChar('texcoord')); + glBindAttribLocation(program_, aColor, PChar('color')); + + glLinkProgram(program_); + glDeleteShader(vs); + glDeleteShader(fs); + + glGetProgramiv(program_, GL_LINK_STATUS, @linkResult); + glGetProgramiv(program_, GL_INFO_LOG_LENGTH, @logLength); + + if logLength > 1 then + begin + log := GetMem(logLength); + glGetProgramInfoLog(program_, logLength, nil, log); + WriteLnToConsole('========== Compiler log =========='); + WriteLnToConsole(shortstring(log)); + WriteLnToConsole('==================================='); + FreeMem(log, logLength); + end; + + if linkResult <> GL_TRUE then + begin + WriteLnToConsole('Linking program failed, halting'); + halt(-1); + end; + + CompileProgram:= program_; +end; +{$ENDIF} + +procedure RenderSetup(); +var AuxBufNum: LongInt = 0; + tmpstr: ansistring; + tmpint: LongInt; + tmpn: LongInt; +begin + // suppress hint/warning + AuxBufNum:= AuxBufNum; + + // get the max (h and v) size for textures that the gpu can support + glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); + if MaxTextureSize <= 0 then + begin + MaxTextureSize:= 1024; + AddFileLog('OpenGL Warning - driver didn''t provide any valid max texture size; assuming 1024'); + end + else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then + begin + cReducedQuality := cReducedQuality or rqNoBackground; + AddFileLog('Texture size too small for backgrounds, disabling.'); + end; + // everyone loves debugging + // find out which gpu we are using (for extension compatibility maybe?) + AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); + AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR)))); + AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); + AddFileLog(' |----- Texture Size: ' + inttostr(MaxTextureSize)); +{$IFDEF USE_VIDEO_RECORDING} + glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum); + AddFileLog(' |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum)); +{$ENDIF} +{$IFNDEF PAS2C} + AddFileLog(' \----- Extensions: '); + + // fetch extentions and store them in string + tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS))); + tmpn := WordCount(tmpstr, [' ']); + tmpint := 1; + + repeat + begin + // print up to 3 extentions per row + // ExtractWord will return empty string if index out of range + AddFileLog(TrimRight( + ExtractWord(tmpint, tmpstr, [' ']) + ' ' + + ExtractWord(tmpint+1, tmpstr, [' ']) + ' ' + + ExtractWord(tmpint+2, tmpstr, [' ']) + )); + tmpint := tmpint + 3; + end; + until (tmpint > tmpn); +{$ENDIF} + AddFileLog(''); + + defaultFrame:= 0; + +{$IFDEF USE_VIDEO_RECORDING} + if GameType = gmtRecord then + begin + if glLoadExtension('GL_EXT_framebuffer_object') then + begin + CreateFramebuffer(defaultFrame, depthv, texv); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame); + AddFileLog('Using framebuffer for video recording.'); + end + else if AuxBufNum > 0 then + begin + glDrawBuffer(GL_AUX0); + glReadBuffer(GL_AUX0); + AddFileLog('Using auxiliary buffer for video recording.'); + end + else + begin + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.'); + end; + end; +{$ENDIF} + +{$IFDEF GL2} + +{$IFDEF PAS2C} + err := glewInit(); + if err <> GLEW_OK then + begin + WriteLnToConsole('Failed to initialize GLEW.'); + halt; + end; +{$ENDIF} + +{$IFNDEF PAS2C} + if not Load_GL_VERSION_2_0 then + halt; +{$ENDIF} + + shaderWater:= CompileProgram('water'); + glUseProgram(shaderWater); + glUniform1i(glGetUniformLocation(shaderWater, pchar('tex0')), 0); + uWaterMVPLocation:= glGetUniformLocation(shaderWater, pchar('mvp')); + + shaderMain:= CompileProgram('default'); + glUseProgram(shaderMain); + glUniform1i(glGetUniformLocation(shaderMain, pchar('tex0')), 0); + uMainMVPLocation:= glGetUniformLocation(shaderMain, pchar('mvp')); + uMainTintLocation:= glGetUniformLocation(shaderMain, pchar('tint')); + + uCurrentMVPLocation:= uMainMVPLocation; + + Tint(255, 255, 255, 255); + UpdateModelviewProjection; +{$ENDIF} + +{$IFNDEF USE_S3D_RENDERING} + if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then + begin + // prepare left and right frame buffers and associated textures + if glLoadExtension('GL_EXT_framebuffer_object') then + begin + CreateFramebuffer(framel, depthl, texl); + CreateFramebuffer(framer, depthr, texr); + + // reset + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) + end + else + cStereoMode:= smNone; + end; +{$ENDIF} + +// set view port to whole window +glViewport(0, 0, cScreenWidth, cScreenHeight); + +{$IFDEF GL2} + uMatrix.initModule; + hglMatrixMode(MATRIX_MODELVIEW); + // prepare default translation/scaling + hglLoadIdentity(); + hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); + hglTranslatef(0, -cScreenHeight / 2, 0); + + EnableTexture(True); + + glEnableVertexAttribArray(aVertex); + glEnableVertexAttribArray(aTexCoord); + glGenBuffers(1, @vBuffer); + glGenBuffers(1, @tBuffer); + glGenBuffers(1, @cBuffer); +{$ELSE} + glMatrixMode(GL_MODELVIEW); + // prepare default translation/scaling + glLoadIdentity(); + glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); + glTranslatef(0, -cScreenHeight / 2, 0); + + // disable/lower perspective correction (will not need it anyway) + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + // disable dithering + glDisable(GL_DITHER); + // enable common states by default as they save a lot + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); +{$ENDIF} + + // enable alpha blending + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // disable/lower perspective correction (will not need it anyway) +end; + procedure openglLoadIdentity(); inline; begin {$IFDEF GL2} @@ -285,11 +587,25 @@ tmp:= cScreenHeight / cScaleFactor; ViewBottomY:= round(tmp) + cScreenHeight div 2; // ceil could make more sense ViewTopY:= round(-tmp) + cScreenHeight div 2; // floor could make more sense + + // visual debugging fun :D + if cViewLimitsDebug then + begin + // some margin on each side + tmp:= min(cScreenWidth, cScreenHeight) div 2 / cScaleFactor; + ViewLeftX := ViewLeftX + trunc(tmp); + ViewRightX := ViewRightX - trunc(tmp); + ViewBottomY:= ViewBottomY - trunc(tmp); + ViewTopY := ViewTopY + trunc(tmp); + end; + + ViewWidth := ViewRightX - ViewLeftX + 1; + ViewHeight:= ViewBottomY - ViewTopY + 1; end; procedure SetScale(f: GLfloat); begin -// leave immediately if scale factor did not change + // leave immediately if scale factor did not change if f = cScaleFactor then exit; @@ -303,7 +619,7 @@ openglPushMatrix; // save default scaling in matrix openglLoadIdentity(); openglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); - openglTranslatef(0, -cScreenHeight / 2, 0); + openglTranslatef(0, -cScreenHeight div 2, 0); end; cScaleFactor:= f; @@ -337,11 +653,16 @@ if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then exit; +{if isDxAreaOffscreen(X, W) <> 0 then + exit; +if isDyAreaOffscreen(Y, H) <> 0 then + exit;} + // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) -if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then +{if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then exit; if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then - exit; + exit;} rr.x:= X; rr.y:= Y; @@ -357,13 +678,13 @@ if Dir < 0 then begin - VertexBuffer[0].X:= X + rr.w/2; + VertexBuffer[0].X:= X + rr.w div 2; VertexBuffer[0].Y:= Y; - VertexBuffer[1].X:= X - rr.w/2; + VertexBuffer[1].X:= X - rr.w div 2; VertexBuffer[1].Y:= Y; - VertexBuffer[2].X:= X - rr.w/2; + VertexBuffer[2].X:= X - rr.w div 2; VertexBuffer[2].Y:= rr.h + Y; - VertexBuffer[3].X:= X + rr.w/2; + VertexBuffer[3].X:= X + rr.w div 2; VertexBuffer[3].Y:= rr.h + Y; end else @@ -402,16 +723,16 @@ openglPushMatrix; openglTranslatef(X, Y, 0); -openglScalef(Scale, Scale, 1); + +if Scale <> 1.0 then + openglScalef(Scale, Scale, 1); glBindTexture(GL_TEXTURE_2D, Texture^.id); SetVertexPointer(@Texture^.vb, Length(Texture^.vb)); SetTexCoordPointer(@Texture^.tb, Length(Texture^.vb)); -{$IFDEF GL2} UpdateModelviewProjection; -{$ENDIF} glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); openglPopMatrix; @@ -457,11 +778,17 @@ hw, hh, nx, ny: LongInt; VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; begin + +if isDxAreaOffscreen(X, w) <> 0 then + exit; +if isDyAreaOffscreen(Y, h) <> 0 then + exit; + // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) -if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then +{if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then exit; if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then - exit; + exit;} openglPushMatrix; @@ -558,11 +885,17 @@ procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); var VertexBuffer: array [0..3] of TVertex2f; begin + +if isDxAreaOffscreen(X, 2 * hw) <> 0 then + exit; +if isDyAreaOffscreen(Y, 2 * hh) <> 0 then + exit; + // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) -if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then +{if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then exit; if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then - exit; + exit;} openglPushMatrix; openglTranslatef(X, Y, 0); @@ -647,12 +980,20 @@ procedure DrawTextureCentered(X, Top: LongInt; Source: PTexture); var scale: GLfloat; + left : LongInt; begin + // scale down if larger than screen if (Source^.w + 20) > cScreenWidth then - scale:= cScreenWidth / (Source^.w + 20) + begin + scale:= cScreenWidth / (Source^.w + 20); + DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale); + end else - scale:= 1.0; - DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale) + begin + left:= X - Source^.w div 2; + if (not isAreaOffscreen(left, Top, Source^.w, Source^.h)) then + DrawTexture(left, Top, Source); + end; end; procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; @@ -690,31 +1031,36 @@ glDisable(GL_LINE_SMOOTH); end; -procedure DrawFillRect(r: TSDL_Rect); +procedure DrawRect(rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); var VertexBuffer: array [0..3] of TVertex2f; begin // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) - -if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then +{if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then exit; if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then - exit; + exit;} EnableTexture(False); -Tint($00, $00, $00, $80); +Tint(r, g, b, a); -VertexBuffer[0].X:= r.x; -VertexBuffer[0].Y:= r.y; -VertexBuffer[1].X:= r.x + r.w; -VertexBuffer[1].Y:= r.y; -VertexBuffer[2].X:= r.x + r.w; -VertexBuffer[2].Y:= r.y + r.h; -VertexBuffer[3].X:= r.x; -VertexBuffer[3].Y:= r.y + r.h; +with rect do +begin + VertexBuffer[0].X:= x; + VertexBuffer[0].Y:= y; + VertexBuffer[1].X:= x + w; + VertexBuffer[1].Y:= y; + VertexBuffer[2].X:= x + w; + VertexBuffer[2].Y:= y + h; + VertexBuffer[3].X:= x; + VertexBuffer[3].Y:= y + h; +end; SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer)); -glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); +if Fill then + glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)) +else + glDrawArrays(GL_LINE_LOOP, 0, Length(VertexBuffer)); untint; @@ -953,4 +1299,18 @@ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); end; +procedure initModule; +begin +end; + +procedure freeModule; +begin +{$IFDEF GL2} + glDeleteProgram(shaderMain); + glDeleteProgram(shaderWater); + glDeleteBuffers(1, @vBuffer); + glDeleteBuffers(1, @tBuffer); + glDeleteBuffers(1, @cBuffer); +{$ENDIF} +end; end. diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/uStore.pas Sat Jun 14 15:49:44 2014 +0200 @@ -21,7 +21,7 @@ unit uStore; interface -uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat; +uses SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat; procedure initModule; procedure freeModule; @@ -62,20 +62,13 @@ procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; procedure SetSkyColor(r, g, b: real); -{$IFDEF GL2} -var - shaderMain: GLuint; - shaderWater: GLuint; -{$ENDIF} - implementation uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands, uPhysFSLayer, uDebug - {$IFDEF GL2}, uMatrix{$ENDIF} {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF} {$IF NOT DEFINED(SDL2) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF}; -var MaxTextureSize: LongInt; +var {$IFDEF SDL2} SDLwindow: PSDL_Window; SDLGLcontext: PSDL_GLContext; @@ -792,118 +785,8 @@ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // prefer hw rendering end; -{$IFDEF GL2} -function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; -var - shader: GLuint; - f: Textfile; - source, line: AnsiString; - sourceA: Pchar; - lengthA: GLint; - compileResult: GLint; - logLength: GLint; - log: PChar; -begin - Assign(f, PathPrefix + cPathz[ptShaders] + '/' + shaderFile); - filemode:= 0; // readonly - Reset(f); - if IOResult <> 0 then - begin - AddFileLog('Unable to load ' + shaderFile); - halt(-1); - end; - - source:=''; - while not eof(f) do - begin - ReadLn(f, line); - source:= source + line + #10; - end; - - Close(f); - - WriteLnToConsole('Compiling shader: ' + PathPrefix + cPathz[ptShaders] + '/' + shaderFile); - - sourceA:=PChar(source); - lengthA:=Length(source); - - shader:=glCreateShader(shaderType); - glShaderSource(shader, 1, @sourceA, @lengthA); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, @compileResult); - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, @logLength); - - if logLength > 1 then - begin - log := GetMem(logLength); - glGetShaderInfoLog(shader, logLength, nil, log); - WriteLnToConsole('========== Compiler log =========='); - WriteLnToConsole(shortstring(log)); - WriteLnToConsole('==================================='); - FreeMem(log, logLength); - end; - - if compileResult <> GL_TRUE then - begin - WriteLnToConsole('Shader compilation failed, halting'); - halt(-1); - end; - - CompileShader:= shader; -end; - -function CompileProgram(shaderName: string): GLuint; -var - program_: GLuint; - vs, fs: GLuint; - linkResult: GLint; - logLength: GLint; - log: PChar; -begin - program_:= glCreateProgram(); - vs:= CompileShader(shaderName + '.vs', GL_VERTEX_SHADER); - fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER); - glAttachShader(program_, vs); - glAttachShader(program_, fs); - - glBindAttribLocation(program_, aVertex, PChar('vertex')); - glBindAttribLocation(program_, aTexCoord, PChar('texcoord')); - glBindAttribLocation(program_, aColor, PChar('color')); - - glLinkProgram(program_); - glDeleteShader(vs); - glDeleteShader(fs); - - glGetProgramiv(program_, GL_LINK_STATUS, @linkResult); - glGetProgramiv(program_, GL_INFO_LOG_LENGTH, @logLength); - - if logLength > 1 then - begin - log := GetMem(logLength); - glGetProgramInfoLog(program_, logLength, nil, log); - WriteLnToConsole('========== Compiler log =========='); - WriteLnToConsole(shortstring(log)); - WriteLnToConsole('==================================='); - FreeMem(log, logLength); - end; - - if linkResult <> GL_TRUE then - begin - WriteLnToConsole('Linking program failed, halting'); - halt(-1); - end; - - CompileProgram:= program_; -end; - -{$ENDIF} - procedure SetupOpenGL; var buf: array[byte] of char; - AuxBufNum: LongInt = 0; - tmpstr: ansistring; - tmpint: LongInt; - tmpn: LongInt; begin {$IFDEF SDL2} @@ -913,8 +796,6 @@ AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')'); {$ENDIF} - AuxBufNum:= AuxBufNum; - {$IFDEF MOBILE} // TODO: this function creates an opengles1.1 context // un-comment below and add proper logic to support opengles2.0 @@ -926,165 +807,7 @@ SDL_GL_SetSwapInterval(1); {$ENDIF} - // get the max (h and v) size for textures that the gpu can support - glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); - if MaxTextureSize <= 0 then - begin - MaxTextureSize:= 1024; - AddFileLog('OpenGL Warning - driver didn''t provide any valid max texture size; assuming 1024'); - end - else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then - begin - cReducedQuality := cReducedQuality or rqNoBackground; - AddFileLog('Texture size too small for backgrounds, disabling.'); - end; - // everyone loves debugging - // find out which gpu we are using (for extension compatibility maybe?) - AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); - AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR)))); - AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); - AddFileLog(' |----- Texture Size: ' + inttostr(MaxTextureSize)); -{$IFDEF USE_VIDEO_RECORDING} - glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum); - AddFileLog(' |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum)); -{$ENDIF} -{$IFNDEF PAS2C} - AddFileLog(' \----- Extensions: '); - - // fetch extentions and store them in string - tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS))); - tmpn := WordCount(tmpstr, [' ']); - tmpint := 1; - - repeat - begin - // print up to 3 extentions per row - // ExtractWord will return empty string if index out of range - AddFileLog(TrimRight( - ExtractWord(tmpint, tmpstr, [' ']) + ' ' + - ExtractWord(tmpint+1, tmpstr, [' ']) + ' ' + - ExtractWord(tmpint+2, tmpstr, [' ']) - )); - tmpint := tmpint + 3; - end; - until (tmpint > tmpn); -{$ENDIF} - AddFileLog(''); - - defaultFrame:= 0; -{$IFDEF USE_VIDEO_RECORDING} - if GameType = gmtRecord then - begin - if glLoadExtension('GL_EXT_framebuffer_object') then - begin - CreateFramebuffer(defaultFrame, depthv, texv); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame); - AddFileLog('Using framebuffer for video recording.'); - end - else if AuxBufNum > 0 then - begin - glDrawBuffer(GL_AUX0); - glReadBuffer(GL_AUX0); - AddFileLog('Using auxiliary buffer for video recording.'); - end - else - begin - glDrawBuffer(GL_BACK); - glReadBuffer(GL_BACK); - AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.'); - end; - end; -{$ENDIF} - -{$IFDEF GL2} - -{$IFDEF PAS2C} - err := glewInit(); - if err <> GLEW_OK then - begin - WriteLnToConsole('Failed to initialize GLEW.'); - halt; - end; -{$ENDIF} - -{$IFNDEF PAS2C} - if not Load_GL_VERSION_2_0 then - halt; -{$ENDIF} - - shaderWater:= CompileProgram('water'); - glUseProgram(shaderWater); - glUniform1i(glGetUniformLocation(shaderWater, pchar('tex0')), 0); - uWaterMVPLocation:= glGetUniformLocation(shaderWater, pchar('mvp')); - - shaderMain:= CompileProgram('default'); - glUseProgram(shaderMain); - glUniform1i(glGetUniformLocation(shaderMain, pchar('tex0')), 0); - uMainMVPLocation:= glGetUniformLocation(shaderMain, pchar('mvp')); - uMainTintLocation:= glGetUniformLocation(shaderMain, pchar('tint')); - - uCurrentMVPLocation:= uMainMVPLocation; - - Tint(255, 255, 255, 255); - UpdateModelviewProjection; -{$ENDIF} - -{$IFNDEF USE_S3D_RENDERING} - if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then - begin - // prepare left and right frame buffers and associated textures - if glLoadExtension('GL_EXT_framebuffer_object') then - begin - CreateFramebuffer(framel, depthl, texl); - CreateFramebuffer(framer, depthr, texr); - - // reset - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) - end - else - cStereoMode:= smNone; - end; -{$ENDIF} - -// set view port to whole window -glViewport(0, 0, cScreenWidth, cScreenHeight); - -{$IFDEF GL2} - uMatrix.initModule; - hglMatrixMode(MATRIX_MODELVIEW); - // prepare default translation/scaling - hglLoadIdentity(); - hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); - hglTranslatef(0, -cScreenHeight / 2, 0); - - EnableTexture(True); - - glEnableVertexAttribArray(aVertex); - glEnableVertexAttribArray(aTexCoord); - glGenBuffers(1, @vBuffer); - glGenBuffers(1, @tBuffer); - glGenBuffers(1, @cBuffer); -{$ELSE} - glMatrixMode(GL_MODELVIEW); - // prepare default translation/scaling - glLoadIdentity(); - glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); - glTranslatef(0, -cScreenHeight / 2, 0); - - // disable/lower perspective correction (will not need it anyway) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - // disable dithering - glDisable(GL_DITHER); - // enable common states by default as they save a lot - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -{$ENDIF} - - // enable alpha blending - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // disable/lower perspective correction (will not need it anyway) + RenderSetup(); end; (* @@ -1133,7 +856,7 @@ TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true); - glClear(GL_COLOR_BUFFER_BIT); + RenderClear(); if Step < numsquares then r.x:= 0 else @@ -1370,7 +1093,7 @@ glutHideWindow(); // we do not need to set this callback, but it is required for GLUT3 compat glutDisplayFunc(@SwapBuffers); - SetupOpenGL(); + SetupRenderer(); end; {$ENDIF} // SDL2 {$ENDIF} // USE_VIDEO_RECORDING @@ -1509,7 +1232,7 @@ if reinit then begin // clean the window from any previous content - glClear(GL_COLOR_BUFFER_BIT); + RenderClear(); if SuddenDeathDmg then SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255) else if ((cReducedQuality and rqNoBackground) = 0) then @@ -1550,7 +1273,7 @@ procedure SetSkyColor(r, g, b: real); begin - glClearColor(r, g, b, 0.99) + RenderSetClearColor(r, g, b, 0.99) end; procedure initModule; @@ -1586,13 +1309,6 @@ procedure freeModule; begin -{$IFDEF GL2} - glDeleteProgram(shaderMain); - glDeleteProgram(shaderWater); - glDeleteBuffers(1, @vBuffer); - glDeleteBuffers(1, @tBuffer); - glDeleteBuffers(1, @cBuffer); -{$ENDIF} StoreRelease(false); TTF_Quit(); {$IFDEF SDL2} diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/uVariables.pas Sat Jun 14 15:49:44 2014 +0200 @@ -212,7 +212,10 @@ WorldDy: LongInt; // for tracking the limits of the visible grid based on cScaleFactor - ViewLeftX, ViewRightX, ViewBottomY, ViewTopY: LongInt; + ViewLeftX, ViewRightX, ViewBottomY, ViewTopY, ViewWidth, ViewHeight: LongInt; + + // for debugging the view limits visually + cViewLimitsDebug: boolean; dirtyLandTexCount: LongInt; @@ -226,6 +229,8 @@ mobileRecord: TMobileRecord; + MaxTextureSize: LongInt; + ///////////////////////////////////// //Buttons {$IFDEF USE_TOUCH_INTERFACE} @@ -2634,6 +2639,8 @@ UIDisplay:= uiAll; LocalMessage:= 0; + + cViewLimitsDebug:= false; end; procedure freeModule; diff -r f726e36c3e24 -r 7e40820b7ed6 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Sat Jun 14 07:12:22 2014 +0200 +++ b/hedgewars/uWorld.pas Sat Jun 14 15:49:44 2014 +0200 @@ -1854,6 +1854,16 @@ end end; +// debug stuff +if cViewLimitsDebug then + begin + r.x:= ViewLeftX; + r.y:= ViewTopY; + r.w:= ViewWidth; + r.h:= ViewHeight; + DrawRect(r, 255, 0, 0, 128, false); + end; + isFirstFrame:= false end;