void packCommandsForDisplayList() { u32 i; // NOGBA("packing : %d %d",dl_commands_buffer_filled,dl_attributes_buffer_filled); while (dl_commands_buffer_filled < 4) { // NOGBA("NOP"); dl_commands_buffer[dl_commands_buffer_filled] = FIFO_NOP; dl_commands_buffer_filled++; } dl_displayLists[dl_displayLists_filled] = FIFO_COMMAND_PACK(dl_commands_buffer[0], dl_commands_buffer[1], dl_commands_buffer[2], dl_commands_buffer[3]); dl_displayLists_filled++; for (i=0; i<dl_attributes_buffer_filled; i++) { dl_displayLists[dl_displayLists_filled] = dl_attributes_buffer[i]; dl_displayLists_filled++; } dl_commands_buffer_filled = 0; dl_attributes_buffer_filled = 0; if(dl_displayLists_filled > RESERVED_SIZE_DISPLAY_LISTS){NOGBA("overflow in model loading!\n");} }
//------------------------------------------------------------------------------------------------- DisplayList::DisplayList(const VertexBuffer &vertexBuffer, const IndexBuffer &indexBuffer, const Texture &texture) { List<u8> commands; List<u32> commandData; commands.push_back(FIFO_BEGIN); commandData.push_back(GL_TRIANGLES); for(int i = 0; i < indexBuffer.IndexCount(); ++i) { u16 index = indexBuffer[i]; auto& v = vertexBuffer[index]; // Add texture coordinates commands.push_back(FIFO_TEX_COORD); fx4 tu = v.U * texture.Width; fx4 tv = v.V * texture.Height; commandData.push_back(TEXTURE_PACK(tof16(tu), tof16(tv))); // Add normal data commands.push_back(FIFO_NORMAL); commandData.push_back(v.Normal); // Add positional data commands.push_back(FIFO_VERTEX16); commandData.push_back(v.XY); commandData.push_back(v.Z); } // Synthesize the display list int dataCounter = 0; int commandCount = commands.size(); // First entry is the size of the display list int packedCommandCount = commands.size() / 4; // 1 display list entry per 4 packed commands packedCommandCount += (commands.size() % 4 == 0) ? 0 : 1; // If the last packed command is padded, add 1 more displayList.push_back(packedCommandCount + commandData.size()); for(int i = 0; i < commandCount; i+=4) { int remaining = commandCount - i; u32 packedFifoCommand = 0; switch(remaining) { case 1: packedFifoCommand = FIFO_COMMAND_PACK(commands[i], FIFO_NOP, FIFO_NOP, FIFO_NOP); break; case 2: packedFifoCommand = FIFO_COMMAND_PACK(commands[i], commands[i+1], FIFO_NOP, FIFO_NOP); break; case 3: packedFifoCommand = FIFO_COMMAND_PACK(commands[i], commands[i+1], commands[i+2], FIFO_NOP); break; default: packedFifoCommand = FIFO_COMMAND_PACK(commands[i], commands[i+1], commands[i+2], commands[i+3]); break; } displayList.push_back(packedFifoCommand); // Add the command data for(int j = 0; j < 4 && j < remaining; ++j) { u8 command = commands[i + j]; switch(command) { case FIFO_TEX_COORD: displayList.push_back(commandData[dataCounter++]); break; case FIFO_NORMAL: displayList.push_back(commandData[dataCounter++]); break; case FIFO_VERTEX16: displayList.push_back(commandData[dataCounter++]); displayList.push_back(commandData[dataCounter++]); break; case FIFO_BEGIN: displayList.push_back(commandData[dataCounter++]); break; default: CRASH("Invalid command specified in display list"); break; } } } ASSERT(displayList[0] == displayList.size() - 1, "Display list size does not packed command count + data size"); ASSERT(displayList[2] == GL_TRIANGLES, "Something went wrong (1)"); ASSERT(dataCounter == (int)commandData.size(), "Something went wrong (2)"); }
#include "Graphics.h" #define TEXTURE_PACK_T16(u, v) ((((u) << 4) & 0xFFFF) | ((v) << 20)) void glVertex2v16(int x, int y) { GFX_VERTEX16 = ((x & 0xffff) | (y<<16)); } u32 temlate_quadList[] = { 16, FIFO_COMMAND_PACK(FIFO_BEGIN, FIFO_TEX_COORD, FIFO_VERTEX16, FIFO_TEX_COORD), GL_QUAD, 0, 0, 0, 0, FIFO_COMMAND_PACK(FIFO_VERTEX_XY, FIFO_TEX_COORD, FIFO_VERTEX_XY, FIFO_TEX_COORD), 0, 0, 0, 0, FIFO_COMMAND_PACK(FIFO_VERTEX_XY, FIFO_NOP, FIFO_NOP, FIFO_NOP), 0, 0,0,0, }; void initGl2D(void) { videoSetMode(MODE_0_3D); vramSetBankA(VRAM_A_TEXTURE); vramSetBankE(VRAM_E_TEX_PALETTE);