--- /dev/null
+2c45b18d41b6b7abd7d7013cf126ed9dbc852835 0 iEYEABECAAYFAkvwQE4ACgkQvCkUtBccqkqlBACgvkql8deTM/JVjlxyZaSN9m7xB2QAoLjYZ8niqpaRQEWGLTQJbyBCcpwH
+a117f6eeffe2ea0591b83b3da4f76b17ca182d6e 0 iEYEABECAAYFAkvwQm0ACgkQvCkUtBccqkpkKACcCWqhpf+Th/x8dFXGjpvQDNA72cIAoIgnFi3cWppe8T2TTrX4IGe+f+zB
+308aeba396559bd925a192b491141a6413d32d43 0 iEYEABECAAYFAkvwTMUACgkQvCkUtBccqkp3FgCfexqbHcBeO9NCC4Bb5CKXWHcXF+AAnArGHvXmPcn3XO+XTnqC39wGtDeT
+cb8570a4c328dcccda31fce4958cea8f5fac748c 0 iEYEABECAAYFAkvwUU8ACgkQvCkUtBccqkoylgCeKkaH+UpP8HC2IM2XowP7TkRseHEAoIYLhHVj3XQzgrMiqPHIpNf49Pn8
+e22c5c02ba45c5392a9e5a1f48b3c1f3123ab806 0 iEYEABECAAYFAkvwU/UACgkQvCkUtBccqkprdwCgrj1L7BHYA66jWWicQn+GAuv/sSYAnjGwWAuF8M0x8GCTK2rKdeSAnC7O
+38fd6c455d143f6167cf7a1037d87846b88b7449 0 iEYEABECAAYFAkvwWgwACgkQvCkUtBccqkqJ2wCeIWGrWuK+4ReIIgmEqXucl6nxFboAnicyYk42m88+QPE263JlkDkKTKfg
+9b260ab4978b283d853000fa17d30d32c25376dd 0 iEYEABECAAYFAkvwdT4ACgkQvCkUtBccqkoWdwCgmjRiRb/Zq+JO6avdBlQZd8+CAzAAnjABDfXj7AFQOWw9/Fv7ni1/oWoW
${SRCDIR}/openal_wrapper.cpp
${SRCDIR}/WinInput.cpp
${SRCDIR}/Settings.cpp
+ ${SRCDIR}/Stereo.cpp
)
set(LUGARU_H
${SRCDIR}/private.h
${SRCDIR}/unpack_private.h
${SRCDIR}/Settings.h
+ ${SRCDIR}/Stereo.h
)
if(UNIX)
Attack key:
mouse1
Chat key:
-unknown
\ No newline at end of file
+unknown
+StereoMode:
+0
+StereoSeparation:
+0.05
+StereoReverse:
+0
#include "binio.h"
#include <fstream>
#include "gamegl.h"
+#include "Stereo.h"
extern GLuint rabbittexture;
void LoadingScreen();
void FadeLoadingScreen(float howmuch);
void Dispose();
- int DrawGLScene(void);
+ int DrawGLScene(StereoSide side);
void Tick();
void TickOnce();
void TickOnceAfter();
//return 1111111111111111;
}
-int Game::DrawGLScene(void)
+int Game::DrawGLScene(StereoSide side)
{
static float texcoordwidth,texcoordheight;
static float texviewwidth, texviewheight;
lastcheck+=multiplier;
- glColorMask( 1.0, 1.0, 1.0, 1.0 );
-
+ if ( stereomode == stereoAnaglyph ) {
+ switch(side) {
+ case stereoLeft: glColorMask( 0.0, 1.0, 1.0, 1.0 ); break;
+ case stereoRight: glColorMask( 1.0, 0.0, 0.0, 1.0 ); break;
+ }
+ } else {
+ glColorMask( 1.0, 1.0, 1.0, 1.0 );
+
+ if ( stereomode == stereoHorizontalInterlaced || stereomode == stereoVerticalInterlaced ) {
+ glStencilFunc(side == stereoLeft ? GL_NOTEQUAL : GL_EQUAL, 0x01, 0x01);
+ }
+ }
if(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted)){
tempmult=multiplier;
glMatrixMode (GL_MODELVIEW);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glLoadIdentity ();
+
+ // Move the camera for the current eye's point of view.
+ // Reverse the movement if we're reversing stereo
+ glTranslatef((stereoseparation/2) * side * (stereoreverse ? -1 : 1), 0, 0);
+
if(!cameramode&&!freeze&&!winfreeze){
glRotatef(float(Random()%100)/10*camerashake/*+(woozy*woozy)/10*/,0,0,1);
glRotatef(rotation2+sin(woozy/2)*(player[0].damage/player[0].damagetolerance)*5,1,0,0);
/*if(mainmenu!=0)*/oldmainmenu=mainmenu;
- if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==119||mainmenu==13||mainmenu==17){
+ if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==119||mainmenu==13||mainmenu==17||mainmenu==18){
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.001f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
if(mainmenu==3){
- nummenuitems=12;
+ nummenuitems=13;
if((float)newscreenwidth>(float)newscreenheight*1.61||(float)newscreenwidth<(float)newscreenheight*1.59)sprintf (menustring[0], "Resolution: %d*%d",(int)newscreenwidth,(int)newscreenheight);
else sprintf (menustring[0], "Resolution: %d*%d (widescreen)",(int)newscreenwidth,(int)newscreenheight);
startx[0]=10+20;
movex[7]=0;
movey[7]=0;
+ sprintf (menustring[12], "-Configure Stereo -");
+ startx[12]=10+15;
+ starty[12]=60;
+ endx[12]=startx[12]+strlen(menustring[7])*10;
+ endy[12]=starty[12]+20;
+ movex[12]=0;
+ movey[12]=0;
+
if(newdetail==detail&&newscreenheight==(int)screenheight&&newscreenwidth==(int)screenwidth)sprintf (menustring[8], "Back");
else sprintf (menustring[8], "Back (some changes take effect next time Lugaru is opened)");
startx[8]=10;
movex[7]=0;
movey[7]=0;*/
}
+ if (mainmenu==18) {
+ nummenuitems=4;
+ sprintf (menustring[0], "Stereo mode: %s", StereoModeName(newstereomode));
+ startx[0]=70;
+ starty[0]=400;
+ endx[0]=startx[0]+strlen(menustring[0])*10;
+ endy[0]=starty[0]+20;
+ movex[0]=0;
+ movey[0]=0;
+
+ sprintf (menustring[1], "Stereo separation: %.3f", stereoseparation);
+ startx[1]=10;
+ starty[1]=360;
+ endx[1]=startx[1]+strlen(menustring[1])*10;
+ endy[1]=starty[1]+20;
+ movex[1]=0;
+ movey[1]=0;
+
+ sprintf (menustring[2], "Reverse stereo: %s", stereoreverse ? "Yes" : "No");
+ startx[2]=40;
+ starty[2]=320;
+ endx[2]=startx[2]+strlen(menustring[2])*10;
+ endy[2]=starty[2]+20;
+ movex[2]=0;
+ movey[2]=0;
+
+ sprintf (menustring[3], "Back");
+ startx[3]=10;
+ endx[3]=startx[3]+strlen(menustring[3])*10;
+ starty[3]=10;
+ endy[3]=starty[3]+20;
+ movex[3]=0;
+ movey[3]=0;
+ }
}
if(mainmenu==13){
}
}
- if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==11||mainmenu==13||mainmenu==17)
+ if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==11||mainmenu==13||mainmenu==17||mainmenu==18)
for(i=0;i<nummenuitems;i++){
if((mousecoordh/screenwidth*640)>startx[i]&&(mousecoordh/screenwidth*640)<endx[i]&&480-(mousecoordv/screenheight*480)>starty[i]&&480-(mousecoordv/screenheight*480)<endy[i]){
if(mainmenu!=5)selected=i;
}
}
}
- if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==11||mainmenu==13||mainmenu==17)
+ if(mainmenu==3||mainmenu==4||mainmenu==5||mainmenu==6||mainmenu==7||mainmenu==8||mainmenu==9||mainmenu==10||mainmenu==11||mainmenu==13||mainmenu==17||mainmenu==18)
{
if(mainmenu!=5||j<6)
{
if(mainmenu==10)text.glPrint(startx[j]-((float)i)+offsetx[j]*((float)i)/4/*-((((float)i)/70)*strlen(menustring[j]))*3*/,starty[j]/*-i*1/2*/+offsety[j]*((float)i)/4,menustring[j],0,1+((float)i)/70,640,480);
if(mainmenu==17)text.glPrint(startx[j]-((float)i)+offsetx[j]*((float)i)/4/*-((((float)i)/70)*strlen(menustring[j]))*3*/,starty[j]/*-i*1/2*/+offsety[j]*((float)i)/4,menustring[j],0,1+((float)i)/70,640,480);
if(mainmenu==13&&j!=1)text.glPrint(startx[j]-((float)i)+offsetx[j]*((float)i)/4/*-((((float)i)/70)*strlen(menustring[j]))*3*/,starty[j]/*-i*1/2*/+offsety[j]*((float)i)/4,menustring[j],0,1+((float)i)/70,640,480);
+ if(mainmenu==18)text.glPrint(startx[j]-((float)i)+offsetx[j]*((float)i)/4/*-((((float)i)/70)*strlen(menustring[j]))*3*/,starty[j]/*-i*1/2*/+offsety[j]*((float)i)/4,menustring[j],0,1+((float)i)/70,640,480);
/*else{
if(displayblink){
sprintf (string, "_");
if(flashamount>0)
{
+ //printf("Flash amount: %f, delay %i\n", flashamount, flashdelay);
if(flashamount>1)flashamount=1;
if(flashdelay<=0)flashamount-=multiplier;
flashdelay--;
//glFlush();
- if(drawmode!=motionblurmode||mainmenu){
-
- swap_gl_buffers();
- }
+ if ( side == stereoRight || side == stereoCenter ) {
+ if(drawmode!=motionblurmode||mainmenu){
+ swap_gl_buffers();
+ }
+ }
//myassert(glGetError() == GL_NO_ERROR);
glDrawBuffer(GL_BACK);
static bool mainmenutogglekeydown;
+
+ if (IsKeyDown(theKeyMap, MAC_F6_KEY) && !freezetogglekeydown) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoreverse=true;
+ } else {
+ stereoreverse=false;
+ }
+
+ if (stereoreverse) {
+ printf("Stereo reversed\n");
+ } else {
+ printf("Stereo unreversed\n");
+ }
+ freezetogglekeydown=1;
+ }
+
+ if (IsKeyDown(theKeyMap, MAC_F7_KEY)) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoseparation -= 0.001;
+ } else {
+ stereoseparation -= 0.010;
+ }
+
+ printf("Stereo decreased increased to %f\n", stereoseparation);
+ }
+
+ if (IsKeyDown(theKeyMap, MAC_F8_KEY)) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoseparation += 0.001;
+ } else {
+ stereoseparation += 0.010;
+ }
+
+ printf("Stereo separation increased to %f\n", stereoseparation);
+ }
+
+
if(!console){
if(mainmenu&&endgame==1)mainmenu=10;
if(IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)&&!mainmenutogglekeydown&&(mainmenu==7&&entername)){
mainmenu=4;
keyselect=-1;
}
+ if(Button() && !oldbutton && selected == 12) {
+ flashr=1;
+ flashg=0;
+ flashb=0;
+ flashamount=1;
+ flashdelay=1;
+
+ newstereomode = stereomode;
+ mainmenu=18;
+ keyselect = -1;
+ }
if(Button()&&!oldbutton&&selected==8){
float gLoc[3]={0,0,0};
float vel[3]={0,0,0};
if(Button())oldbutton=1;
else oldbutton=0;
}
+ if (mainmenu==18) {
+ if(Button()&&!oldbutton) {
+ printf("Button %i pressed\n", selected);
+ }
+
+ if(Button()&&!oldbutton&&selected==0) {
+ newstereomode = (StereoMode)(newstereomode + 1);
+ while(!CanInitStereo(newstereomode)) {
+ printf("Failed to initialize mode %s (%i)\n", StereoModeName(newstereomode), newstereomode);
+ newstereomode = (StereoMode)(newstereomode + 1);
+ if ( newstereomode >= stereoCount ) {
+ newstereomode = stereoNone;
+ }
+ }
+ }
+
+ if(buttons[0]&&!oldbutton&&selected==1) {
+ stereoseparation+=0.001;
+ }
+ if(buttons[1]&&!oldbutton&&selected==1) {
+ stereoseparation-=0.001;
+ }
+
+ if(Button()&&!oldbutton&&selected==2) {
+ stereoreverse =! stereoreverse;
+ }
+
+ if(Button()&&!oldbutton&&selected==3) {
+ flashr=1;
+ flashg=0;
+ flashb=0;
+ flashamount=1;
+ flashdelay=1;
+
+ stereomode = newstereomode;
+ InitStereo(stereomode);
+
+ mainmenu=3;
+ }
+
+ if(Button() || buttons[1])oldbutton=1;
+ else oldbutton=0;
+ }
- if(Button())oldbutton=1;
+ if(Button()||buttons[1])oldbutton=1;
else oldbutton=0;
if(IsKeyDown(theKeyMap, MAC_Q_KEY)&&IsKeyDown(theKeyMap, MAC_COMMAND_KEY)){
#include "Person.h"
#include "TGALoader.h"
#include "openal_wrapper.h"
+#include "Stereo.h"
#include "Constants.h"
//TextureList textures;
+StereoMode stereomode = stereoNone;
+StereoMode newstereomode = stereoNone;
+float stereoseparation = 0.05;
+bool stereoreverse = false;
\ No newline at end of file
void DrawGL (Game & game)
{
- game.DrawGLScene();
+ if ( stereomode == stereoNone ) {
+ game.DrawGLScene(stereoCenter);
+ } else {
+ game.DrawGLScene(stereoLeft);
+ game.DrawGLScene(stereoRight);
+ }
}
SDL_ShowCursor(0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
+
if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL)
{
fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
glDisable( GL_FOG);
glDisable( GL_LIGHTING);
glDisable( GL_LOGIC_OP);
- glDisable( GL_STENCIL_TEST);
glDisable( GL_TEXTURE_1D);
glDisable( GL_TEXTURE_2D);
glPixelTransferi( GL_MAP_COLOR, GL_FALSE);
game.newscreenwidth=screenwidth;
game.newscreenheight=screenheight;
+ if ( CanInitStereo(stereomode) ) {
+ InitStereo(stereomode);
+ } else {
+ fprintf(stderr, "Failed to initialize stereo, disabling.\n");
+ stereomode = stereoNone;
+ }
+
game.InitGame();
return true;
opstream << KeyToChar(game.attackkey);
opstream << "\nChat key:\n";
opstream << KeyToChar(game.chatkey);
+ opstream << "\nStereoMode:\n";
+ opstream << stereomode;
+ opstream << "\nStereoSeparation:\n";
+ opstream << stereoseparation;
+ opstream << "\nStereoReverse:\n";
+ opstream << stereoreverse;
+
opstream.close();
}
} else if ( !strncmp(setting, "Chat key", 8) ) {
ipstream >> string;
game.chatkey = CharToKey(string);
+ } else if ( !strncmp(setting, "StereoMode", 10) ) {
+ int i;
+ ipstream >> i;
+ stereomode = (StereoMode)i;
+ } else if ( !strncmp(setting, "StereoSeparation", 16) ) {
+ ipstream >> stereoseparation;
+ } else if ( !strncmp(setting, "StereoReverse", 13) ) {
+ ipstream >> stereoreverse;
} else {
ipstream >> string;
fprintf(stderr, "Unknown config option '%s' with value '%s'. Ignoring.\n", setting, string);
--- /dev/null
+
+#include "Game.h"
+#include "Stereo.h"
+
+
+extern int kContextWidth;
+extern int kContextHeight;
+
+bool CanInitStereo(StereoMode mode) {
+ GLint stencilbits = 0;
+
+ switch(mode) {
+ case stereoNone:
+ return true;
+ break;
+ case stereoAnaglyph:
+ return true;
+ break;
+ case stereoHorizontalInterlaced:
+ case stereoVerticalInterlaced:
+ glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
+ if ( stencilbits < 1 ) {
+ fprintf(stderr, "Failed to get a stencil buffer, interlaced stereo not available.\n");
+ return false;
+ } else {
+ fprintf(stderr, "Stencil buffer has %i bits, good.\n", stencilbits);
+ }
+ return true;
+ break;
+ default:
+ return false;
+ }
+
+}
+
+void InitStereo(StereoMode mode) {
+ switch(mode) {
+ case stereoNone:
+ glDisable( GL_STENCIL_TEST);
+ return;
+ case stereoAnaglyph:
+ glDisable( GL_STENCIL_TEST);
+ return;
+ case stereoHorizontalInterlaced:
+ case stereoVerticalInterlaced:
+
+ fprintf(stderr, "Screen width is %i, height is %i\n", kContextWidth, kContextHeight);
+
+ // Setup stencil buffer
+ glDisable( GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+
+ glEnable( GL_STENCIL_TEST);
+ glClearStencil(0);
+ glClear( GL_STENCIL_BUFFER_BIT );
+ glStencilFunc(GL_ALWAYS, 0x1, 0x1);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
+ // Setup viewport
+ glViewport(0,0, kContextWidth, kContextHeight);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho((GLdouble)0, (GLdouble)kContextWidth, (GLdouble)kContextHeight, 0, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
+ glDisable(GL_LINE_SMOOTH);
+
+ // Add 0.5 to the coordinates, because OpenGL considers a pixel should be
+ // turned on when a line passes through the center of it.
+ if ( mode == stereoHorizontalInterlaced ) {
+ for(int y=0;y<kContextHeight;y+=2) {
+ glBegin(GL_LINES);
+ glVertex3f(0.5, y+0.5, 0);
+ glVertex3f(kContextWidth+0.5, y+0.5, 0);
+ glEnd();
+ }
+ } else {
+ for(int x=0;x<kContextWidth;x+=2) {
+ glBegin(GL_LINES);
+ glVertex3f(x+0.5, 0.5, 0);
+ glVertex3f(x+0.5, kContextHeight+0.5, 0);
+ glEnd();
+ }
+ }
+
+ glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
+
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glStencilFunc(GL_NOTEQUAL, 0x01, 0x01);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glEnable( GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_TEXTURE_2D);
+
+ }
+
+}
+
+const char* StereoModeName(StereoMode mode) {
+ switch(mode) {
+ case stereoNone: return "None"; break;
+ case stereoAnaglyph: return "Anaglyph"; break;
+ case stereoHorizontalInterlaced: return "Horizontal interlacing"; break;
+ case stereoVerticalInterlaced: return "Vertical interlacing"; break;
+ case stereoHorizontalSplit: return "Horizontal split"; break;
+ case stereoVerticalSplit: return "Vertical split"; break;
+ case stereoOpenGL: return "OpenGL"; break;
+ default: return "(error)"; break;
+ }
+}
\ No newline at end of file
--- /dev/null
+
+#ifndef STEREO_H_
+#define STEREO_H_
+
+enum StereoMode {
+ stereoNone,
+ stereoAnaglyph, /* red/cyan */
+ stereoHorizontalInterlaced, /* some 3D monitors */
+ stereoVerticalInterlaced,
+ stereoHorizontalSplit, /* cross-eyed view */
+ stereoVerticalSplit,
+ stereoOpenGL, /* Whatever OpenGL does, if supported */
+ stereoCount /* must be last element */
+};
+
+
+enum StereoSide {
+ // Code multiplies by StereoSide to calculate camera offsets
+ stereoLeft = -1,
+ stereoCenter = 0,
+ stereoRight = 1
+};
+
+extern StereoMode stereomode;
+extern StereoMode newstereomode;
+extern float stereoseparation;
+extern bool stereoreverse;
+
+bool CanInitStereo(StereoMode mode);
+void InitStereo(StereoMode mode);
+const char* StereoModeName(StereoMode mode);
+
+#endif
\ No newline at end of file