program BothScreens3D; {$mode objfpc} uses ctypes, nds9; procedure renderCube(angle: cint); begin glPushMatrix(); glTranslatef(0, 0, -4); glRotatef32i(degreesToAngle(angle), inttof32(1), inttof32(1), inttof32(1)); glBegin(GL_QUADS); glColor3b(255,0,0); glVertex3f(-1.0, 1.0, 1.0); glColor3b(0,255,0); glVertex3f( 1.0, 1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, 1.0); glColor3b(255,255,0); glVertex3f(-1.0, -1.0, 1.0); glColor3b(255,0,0); glVertex3f(-1.0, 1.0, -1.0); glColor3b(0,255,0); glVertex3f( 1.0, 1.0, -1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, -1.0); glColor3b(255,255,0); glVertex3f(-1.0, -1.0, -1.0); glColor3b(255,0,0); glVertex3f(-1.0, 1.0, 1.0); glColor3b(0,255,0); glVertex3f( 1.0, 1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, 1.0, -1.0); glColor3b(255,255,0); glVertex3f(-1.0, 1.0, -1.0); glColor3b(255,0,0); glVertex3f(-1.0, -1.0, 1.0); glColor3b(0,255,0); glVertex3f( 1.0, -1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, -1.0); glColor3b(255,255,0); glVertex3f(-1.0, -1.0, -1.0); glColor3b(255,0,0); glVertex3f( 1.0, 1.0, -1.0); glColor3b(0,255,0); glVertex3f( 1.0, 1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0,-1.0, 1.0); glColor3b(255,255,0); glVertex3f( 1.0,-1.0, -1.0); glColor3b(255,0,0); glVertex3f(-1.0, 1.0, -1.0); glColor3b(0,255,0); glVertex3f(-1.0, 1.0, 1.0); glColor3b(0,0,255); glVertex3f(-1.0,-1.0, 1.0); glColor3b(255,255,0); glVertex3f(-1.0,-1.0, -1.0); glEnd(); glPopMatrix(1); end; procedure renderPyramid(angle: cint); begin glPushMatrix(); glTranslatef(0, 0, -4); glRotatef32i(degreesToAngle(angle), inttof32(1),inttof32(1),inttof32(1)); glBegin(GL_QUADS); glColor3b(255,0,0); glVertex3f(-1.0, -1.0, 1.0); glColor3b(0,255,0); glVertex3f( 1.0, -1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, -1.0); glColor3b(255,255,0); glVertex3f(-1.0, -1.0, -1.0); glEnd(); glBegin(GL_TRIANGLES); glColor3b(255,0,0); glVertex3f( 0.0, 1.0, 0.0); glColor3b(0,255,0); glVertex3f(-1.0, -1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, 1.0); glColor3b(255,0,0); glVertex3f( 0.0, 1.0, 0.0); glColor3b(0,255,0); glVertex3f(-1.0, -1.0, -1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, -1.0); glColor3b(255,0,0); glVertex3f( 0.0, 1.0, 0.0); glColor3b(0,255,0); glVertex3f(-1.0, -1.0, 1.0); glColor3b(0,0,255); glVertex3f(-1.0, -1.0, -1.0); glColor3b(255,0,0); glVertex3f( 0.0, 1.0, 0.0); glColor3b(0,255,0); glVertex3f( 1.0, -1.0, 1.0); glColor3b(0,0,255); glVertex3f( 1.0, -1.0, -1.0); glEnd(); glPopMatrix(1); end; var angle: cshort = 0; procedure renderScene(top: boolean); begin if (top) then renderCube(angle) else renderPyramid(angle); inc(angle); end; //------------------------------------------------------- // set up a 2D layer construced of bitmap sprites // this holds the image when rendering to the top screen //------------------------------------------------------- procedure initSubSprites(); var x: integer; y: integer; id: integer; offset: pcuint16; begin oamInit(oamSub, SpriteMapping_Bmp_2D_256, false); x := 0; y := 0; //set up a 4x3 grid of 64x64 sprites to cover the screen for y := 0 to 2 do for x := 0 to 3 do begin // offset := pcuint16(@SPRITE_GFX_SUB[(x * 64) + (y * 64 * 256)]); // oamSet(oamSub, x + y * 4, x * 64, y * 64, 0, 15, SpriteSize_64x64, // SpriteColorFormat_Bmp, offset, -1, false,false,false,false,false); oamSub.oamMemory[id].attribute[0] := ATTR0_BMP or ATTR0_SQUARE or (64 * y); oamSub.oamMemory[id].attribute[1] := ATTR1_SIZE_64 or (64 * x); oamSub.oamMemory[id].attribute[2] := ATTR2_ALPHA(1) or (8 * 32 * y) or (8 * x); inc(id); end; swiWaitForVBlank(); oamUpdate(oamSub); end; var top: boolean = true; begin videoSetMode(MODE_0_3D); videoSetModeSub(MODE_5_2D); glInit(); // sub sprites hold the bottom image when 3D directed to top initSubSprites(); // sub background holds the top image when 3D directed to bottom bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0); //------------------------------------------------------- // Setup gl //------------------------------------------------------- glEnable(GL_ANTIALIAS); glClearColor(0,0,0,31); glClearPolyID(63); glClearDepth($7FFF); glViewport(0,0,255,191); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(70, 256.0 / 192.0, 0.1, 100); glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE); //------------------------------------------------------- // main loop //------------------------------------------------------- while true do begin // wait for capture unit to be ready while (REG_DISPCAPCNT^ and DCAP_ENABLE) <> 0 do; //------------------------------------------------------- // Switch render targets //------------------------------------------------------- top := not top; if (top) then begin lcdMainOnBottom(); vramSetBankC(VRAM_C_LCD); vramSetBankD(VRAM_D_SUB_SPRITE); REG_DISPCAPCNT^ := DCAP_BANK(2) or DCAP_ENABLE or DCAP_SIZE(3); end else begin lcdMainOnTop(); vramSetBankD(VRAM_D_LCD); vramSetBankC(VRAM_C_SUB_BG); REG_DISPCAPCNT^ := DCAP_BANK(3) or DCAP_ENABLE or DCAP_SIZE(3); end; //------------------------------------------------------- // Render the scene //------------------------------------------------------- glMatrixMode(GL_MODELVIEW); renderScene(top); glFlush(0); end; end.