# HG changeset patch # User smaxx # Date 1282156181 -7200 # Node ID 6009d83784228ee8a0fc232de54ed5efb51c403b # Parent 3e9c0634065cab2001876ac6bb2de0141eacf1c5 Engine: * Rewrote stereo rendering * Simplified anaglyph rendering (no longer requires framebuffers) * Added stereo mode selection: Anaglyph (different combinations of red, green, blue and cyan), side-by-side (horizontal and vertical) and alternate frame rendering (AFR) diff -r 3e9c0634065c -r 6009d8378422 QTfrontend/game.cpp --- a/QTfrontend/game.cpp Mon Aug 02 15:05:56 2010 +0200 +++ b/QTfrontend/game.cpp Wed Aug 18 20:29:41 2010 +0200 @@ -288,7 +288,7 @@ arguments << config->netNick().toUtf8().toBase64(); arguments << (config->isMusicEnabled() ? "1" : "0"); arguments << QString::number(config->translateQuality()); - arguments << (config->isStereoEnabled() ? "1" : "0"); + arguments << QString::number(config->stereoMode()); return arguments; } diff -r 3e9c0634065c -r 6009d8378422 QTfrontend/gameuiconfig.cpp --- a/QTfrontend/gameuiconfig.cpp Mon Aug 02 15:05:56 2010 +0200 +++ b/QTfrontend/gameuiconfig.cpp Wed Aug 18 20:29:41 2010 +0200 @@ -48,7 +48,7 @@ Form->ui.pageOptions->CBFrontendFullscreen->setChecked(ffscr); Form->ui.pageOptions->SLQuality->setValue(value("video/quality", 5).toUInt()); - Form->ui.pageOptions->CBEnableStereo->setChecked(value("video/anaglyph", false).toBool()); + Form->ui.pageOptions->CBStereoMode->setCurrentIndex(value("video/stereo", 0).toUInt()); Form->ui.pageOptions->CBFrontendEffects->setChecked(frontendEffects); Form->ui.pageOptions->CBEnableSound->setChecked(value("audio/sound", true).toBool()); Form->ui.pageOptions->CBEnableFrontendSound->setChecked(value("frontend/sound", true).toBool()); @@ -114,7 +114,7 @@ setValue("video/fullscreen", vid_Fullscreen()); setValue("video/quality", Form->ui.pageOptions->SLQuality->value()); - setValue("video/anaglyph", isStereoEnabled()); + setValue("video/stereo", stereoMode()); setValue("frontend/effects", isFrontendEffects()); @@ -263,9 +263,9 @@ return Form->ui.pageOptions->CBAltDamage->isChecked(); } -bool GameUIConfig::isStereoEnabled() const +quint32 GameUIConfig::stereoMode() const { - return Form->ui.pageOptions->CBEnableStereo->isChecked(); + return Form->ui.pageOptions->CBStereoMode->currentIndex(); } bool GameUIConfig::appendDateTimeToRecordName() diff -r 3e9c0634065c -r 6009d8378422 QTfrontend/gameuiconfig.h --- a/QTfrontend/gameuiconfig.h Mon Aug 02 15:05:56 2010 +0200 +++ b/QTfrontend/gameuiconfig.h Wed Aug 18 20:29:41 2010 +0200 @@ -52,7 +52,7 @@ bool isFrontendEffects() const; bool isFrontendFullscreen() const; void resizeToConfigValues(); - bool isStereoEnabled() const; + quint32 stereoMode() const; #ifdef __APPLE__ #ifdef SPARKLE_ENABLED diff -r 3e9c0634065c -r 6009d8378422 QTfrontend/pages.cpp --- a/QTfrontend/pages.cpp Mon Aug 02 15:05:56 2010 +0200 +++ b/QTfrontend/pages.cpp Wed Aug 18 20:29:41 2010 +0200 @@ -573,6 +573,7 @@ QVBoxLayout * GBAlayout = new QVBoxLayout(AGGroupBox); QHBoxLayout * GBAreslayout = new QHBoxLayout(0); + QHBoxLayout * GBAstereolayout = new QHBoxLayout(0); QHBoxLayout * GBAqualayout = new QHBoxLayout(0); CBFrontendFullscreen = new QCheckBox(AGGroupBox); @@ -621,9 +622,24 @@ GBAqualayout->addWidget(SLQuality); GBAlayout->addLayout(GBAqualayout); - CBEnableStereo = new QCheckBox(AGGroupBox); - CBEnableStereo->setText(QCheckBox::tr("Anaglyph rendering (red/cyan)")); - GBAlayout->addWidget(CBEnableStereo); + QLabel * stereo = new QLabel(AGGroupBox); + stereo->setText(QLabel::tr("Stereo rendering")); + GBAstereolayout->addWidget(stereo); + + CBStereoMode = new QComboBox(AGGroupBox); + CBStereoMode->addItem(QComboBox::tr("Disabled")); + CBStereoMode->addItem(QComboBox::tr("Red/Cyan")); + CBStereoMode->addItem(QComboBox::tr("Cyan/Red")); + CBStereoMode->addItem(QComboBox::tr("Red/Blue")); + CBStereoMode->addItem(QComboBox::tr("Blue/Red")); + CBStereoMode->addItem(QComboBox::tr("Red/Green")); + CBStereoMode->addItem(QComboBox::tr("Green/Red")); + CBStereoMode->addItem(QComboBox::tr("Side-by-side (horizontal)")); + CBStereoMode->addItem(QComboBox::tr("Side-by-side (vertical)")); + CBStereoMode->addItem(QComboBox::tr("Alternate frame rendering")); + + GBAstereolayout->addWidget(CBStereoMode); + GBAlayout->addLayout(GBAstereolayout); hr = new QFrame(AGGroupBox); hr->setFrameStyle(QFrame::HLine); diff -r 3e9c0634065c -r 6009d8378422 QTfrontend/pages.h --- a/QTfrontend/pages.h Mon Aug 02 15:05:56 2010 +0200 +++ b/QTfrontend/pages.h Wed Aug 18 20:29:41 2010 +0200 @@ -220,9 +220,9 @@ QComboBox *CBTeamName; IconedGroupBox *AGGroupBox; QComboBox *CBResolution; + QComboBox *CBStereoMode; QCheckBox *CBEnableSound; QCheckBox *CBEnableFrontendSound; - QCheckBox *CBEnableStereo; QCheckBox *CBEnableMusic; QCheckBox *CBEnableFrontendMusic; QCheckBox *CBFullscreen; diff -r 3e9c0634065c -r 6009d8378422 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Mon Aug 02 15:05:56 2010 +0200 +++ b/hedgewars/hwengine.pas Wed Aug 18 20:29:41 2010 +0200 @@ -230,7 +230,7 @@ recordFileName:= gameArgs[8]; val(gameArgs[9], cReducedQuality); - isStereoEnabled:= false; // TODO: Enable anaglyph rendering on iPhone? + cStereoMode:= smNone; // TODO: Enable anaglyph rendering on iPhone? {$ENDIF} initEverything(true); @@ -437,6 +437,7 @@ //////////////////// procedure GetParams; +var i : LongInt; begin case ParamCount of 19: begin @@ -458,7 +459,8 @@ UserNick:= DecodeBase64(ParamStr(16)); isMusicEnabled:= ParamStr(17) = '1'; val(ParamStr(18), cReducedQuality); - isStereoEnabled:= ParamStr(19) = '1'; + val(ParamStr(19), i); + cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), i))); end; 3: begin val(ParamStr(2), ipcPort); diff -r 3e9c0634065c -r 6009d8378422 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Mon Aug 02 15:05:56 2010 +0200 +++ b/hedgewars/uConsts.pas Wed Aug 18 20:29:41 2010 +0200 @@ -141,6 +141,9 @@ TWave = (waveRollup, waveSad, waveWave, waveHurrah, waveLemonade, waveShrug, waveJuggle); + TRenderMode = (rmDefault, rmLeftEye, rmRightEye); + TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical, smAFR); + THHFont = record Handle: PTTF_Font; Height: LongInt; diff -r 3e9c0634065c -r 6009d8378422 hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Mon Aug 02 15:05:56 2010 +0200 +++ b/hedgewars/uMisc.pas Wed Aug 18 20:29:41 2010 +0200 @@ -35,7 +35,8 @@ isSpeed : boolean; isFirstFrame : boolean; - isStereoEnabled : boolean; + //isStereoEnabled : boolean; + cStereoMode : TStereoMode; fastUntilLag : boolean; diff -r 3e9c0634065c -r 6009d8378422 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Mon Aug 02 15:05:56 2010 +0200 +++ b/hedgewars/uStore.pas Wed Aug 18 20:29:41 2010 +0200 @@ -803,7 +803,7 @@ SDL_FreeSurface(MissionIcons); FreeTexture(ropeIconTex); FreeTexture(HHTexture); - if isStereoEnabled then + if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then begin glDeleteTextures(1, @texl); glDeleteRenderbuffersEXT(1, @depthl); @@ -1192,7 +1192,7 @@ cGPUVendor:= gvIntel; //SupportNPOTT:= glLoadExtension('GL_ARB_texture_non_power_of_two'); - if isStereoEnabled then + if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then begin // prepare left and right frame buffers and associated textures glLoadExtension('GL_EXT_framebuffer_object'); diff -r 3e9c0634065c -r 6009d8378422 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Mon Aug 02 15:05:56 2010 +0200 +++ b/hedgewars/uWorld.pas Wed Aug 18 20:29:41 2010 +0200 @@ -22,19 +22,19 @@ interface uses SDLh, uGears, uConsts, uFloat, uRandom; -type TRenderMode = (rmDefault, rmLeftEye, rmRightEye); - var FollowGear: PGear; WindBarWidth: LongInt; bShowAmmoMenu: boolean; bSelected: boolean; bShowFinger: boolean; Frames: Longword; + AFRToggle: Boolean; WaterColor, DeepWaterColor: TSDL_Color; WorldDx: LongInt; WorldDy: LongInt; SkyOffset: LongInt; HorizontOffset: LongInt; + bAFRRight: Boolean; {$IFDEF COUNTTICKS} cntTicks: LongWord; {$ENDIF} @@ -564,13 +564,22 @@ if not isPaused then MoveCamera; - if not isStereoEnabled then - begin + if cStereoMode = smNone then + begin glClear(GL_COLOR_BUFFER_BIT); DrawWorldStereo(Lag, rmDefault) - end - else - begin + end + else if (cStereoMode = smAFR) then + begin + AFRToggle:= not AFRToggle; + glClear(GL_COLOR_BUFFER_BIT); + if AFRToggle then + DrawWorldStereo(Lag, rmLeftEye) + else + DrawWorldStereo(Lag, rmRightEye) + end + else if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then + begin // create left fb glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); @@ -583,56 +592,97 @@ // detatch drawing from fbs glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - glGetFloatv(GL_COLOR_CLEAR_VALUE, @cc); - glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - glClearColor(cc[0], cc[1], cc[2], cc[3]); SetScale(cDefaultZoomLevel); - // enable gl stuff - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - // draw left frame glBindTexture(GL_TEXTURE_2D, texl); - glColor3f(0.0, 1.0, 1.0); glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex2d(cScreenWidth / -2, cScreenHeight); - glTexCoord2f(1.0, 0.0); - glVertex2d(cScreenWidth / 2, cScreenHeight); - glTexCoord2f(1.0, 1.0); - glVertex2d(cScreenWidth / 2, 0); - glTexCoord2f(0.0, 1.0); - glVertex2d(cScreenWidth / -2, 0); + if cStereoMode = smHorizontal then + begin + glTexCoord2f(0.0, 0.0); + glVertex2d(cScreenWidth / -2, cScreenHeight); + glTexCoord2f(1.0, 0.0); + glVertex2d(0, cScreenHeight); + glTexCoord2f(1.0, 1.0); + glVertex2d(0, 0); + glTexCoord2f(0.0, 1.0); + glVertex2d(cScreenWidth / -2, 0); + end + else + begin + glTexCoord2f(0.0, 0.0); + glVertex2d(cScreenWidth / -2, cScreenHeight / 2); + glTexCoord2f(1.0, 0.0); + glVertex2d(cScreenWidth / 2, cScreenHeight / 2); + glTexCoord2f(1.0, 1.0); + glVertex2d(cScreenWidth / 2, 0); + glTexCoord2f(0.0, 1.0); + glVertex2d(cScreenWidth / -2, 0); + end; glEnd(); // draw right frame glBindTexture(GL_TEXTURE_2D, texr); - glColor3f(1.0, 0.0, 0.0); glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex2d(cScreenWidth / -2, cScreenHeight); - glTexCoord2f(1.0, 0.0); - glVertex2d(cScreenWidth / 2, cScreenHeight); - glTexCoord2f(1.0, 1.0); - glVertex2d(cScreenWidth / 2, 0); - glTexCoord2f(0.0, 1.0); - glVertex2d(cScreenWidth / -2, 0); + if cStereoMode = smHorizontal then + begin + glTexCoord2f(0.0, 0.0); + glVertex2d(0, cScreenHeight); + glTexCoord2f(1.0, 0.0); + glVertex2d(cScreenWidth / 2, cScreenHeight); + glTexCoord2f(1.0, 1.0); + glVertex2d(cScreenWidth / 2, 0); + glTexCoord2f(0.0, 1.0); + glVertex2d(0, 0); + end + else + begin + glTexCoord2f(0.0, 0.0); + glVertex2d(cScreenWidth / -2, cScreenHeight); + glTexCoord2f(1.0, 0.0); + glVertex2d(cScreenWidth / 2, cScreenHeight); + glTexCoord2f(1.0, 1.0); + glVertex2d(cScreenWidth / 2, cScreenHeight / 2); + glTexCoord2f(0.0, 1.0); + glVertex2d(cScreenWidth / -2, cScreenHeight / 2); + end; glEnd(); - - // reset - glColor3f(1.0, 1.0, 1.0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); SetScale(zoom); - end + end + else + begin + // clear scene + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + // draw left eye in red channel only + if cStereoMode = smGreenRed then + glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) + else if cStereoMode = smBlueRed then + glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) + else if cStereoMode = smCyanRed then + glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) + else + glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); + DrawWorldStereo(Lag, rmLeftEye); + // draw right eye in selected channel(s) only + if cStereoMode = smRedGreen then + glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) + else if cStereoMode = smRedBlue then + glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) + else if cStereoMode = smRedCyan then + glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) + else + glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); + DrawWorldStereo(Lag, rmRightEye); + end end; procedure ChangeDepth(rm: TRenderMode; d: GLfloat); begin + d:= d / 5; if rm = rmDefault then exit - else if rm = rmRightEye then d:= -d; + else if rm = rmLeftEye then d:= -d; stereoDepth:= stereoDepth + d; glMatrixMode(GL_PROJECTION); glTranslatef(d, 0, 0); @@ -971,7 +1021,7 @@ offsetY:= cOffsetY; // don't increment fps when drawing the right frame -if (RM = rmDefault) or (RM = rmLeftEye) then +if (RM = rmDefault) or (RM = rmRightEye) then begin inc(Frames);