Fix a bug introduced by r6240.
[dolphin.git] / Source / Plugins / Plugin_VideoOGL / Src / VertexManager.cpp
blob40938f41787a87f98fb1b758bd0fe627efcba498
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include "Globals.h"
20 #include <fstream>
21 #include <vector>
23 #include "Fifo.h"
25 #include "VideoConfig.h"
26 #include "Statistics.h"
27 #include "MemoryUtil.h"
28 #include "Profiler.h"
29 #include "Render.h"
30 #include "ImageWrite.h"
31 #include "BPMemory.h"
32 #include "TextureCache.h"
33 #include "PixelShaderCache.h"
34 #include "PixelShaderManager.h"
35 #include "VertexShaderCache.h"
36 #include "VertexShaderManager.h"
37 #include "VertexShaderGen.h"
38 #include "VertexLoader.h"
39 #include "VertexManager.h"
40 #include "IndexGenerator.h"
41 #include "OpcodeDecoding.h"
42 #include "FileUtil.h"
44 #include "main.h"
46 // internal state for loading vertices
47 extern NativeVertexFormat *g_nativeVertexFmt;
49 namespace OGL
52 //static GLint max_Index_size = 0;
54 //static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
55 //static int s_nCurVBOIndex = 0; // current free buffer
57 VertexManager::VertexManager()
59 // TODO: doesn't seem to be used anywhere
61 //glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size);
63 //if (max_Index_size > MAXIBUFFERSIZE)
64 // max_Index_size = MAXIBUFFERSIZE;
66 //GL_REPORT_ERRORD();
68 glEnableClientState(GL_VERTEX_ARRAY);
69 GL_REPORT_ERRORD();
72 void VertexManager::Draw()
74 if (IndexGenerator::GetNumTriangles() > 0)
76 glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
77 INCSTAT(stats.thisFrame.numIndexedDrawCalls);
79 if (IndexGenerator::GetNumLines() > 0)
81 glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
82 INCSTAT(stats.thisFrame.numIndexedDrawCalls);
84 if (IndexGenerator::GetNumPoints() > 0)
86 glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
87 INCSTAT(stats.thisFrame.numIndexedDrawCalls);
91 void VertexManager::vFlush()
93 if (LocalVBuffer == s_pCurBufferPointer) return;
94 if (Flushed) return;
95 Flushed=true;
96 VideoFifo_CheckEFBAccess();
97 #if defined(_DEBUG) || defined(DEBUGFAST)
98 PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGens,
99 xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op,
100 bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.zmode.updateenable);
102 for (int i = 0; i < xfregs.nNumChans; ++i)
104 LitChannel* ch = &xfregs.colChans[i].color;
105 PRIM_LOG("colchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc);
106 ch = &xfregs.colChans[i].alpha;
107 PRIM_LOG("alpchan%d: matsrc=%d, light=0x%x, ambsrc=%d, diffunc=%d, attfunc=%d", i, ch->matsource, ch->GetFullLightMask(), ch->ambsource, ch->diffusefunc, ch->attnfunc);
110 for (int i = 0; i < xfregs.numTexGens; ++i)
112 TexMtxInfo tinfo = xfregs.texcoords[i].texmtxinfo;
113 if (tinfo.texgentype != XF_TEXGEN_EMBOSS_MAP) tinfo.hex &= 0x7ff;
114 if (tinfo.texgentype != XF_TEXGEN_REGULAR) tinfo.projection = 0;
116 PRIM_LOG("txgen%d: proj=%d, input=%d, gentype=%d, srcrow=%d, embsrc=%d, emblght=%d, postmtx=%d, postnorm=%d",
117 i, tinfo.projection, tinfo.inputform, tinfo.texgentype, tinfo.sourcerow, tinfo.embosssourceshift, tinfo.embosslightshift,
118 xfregs.texcoords[i].postmtxinfo.index, xfregs.texcoords[i].postmtxinfo.normalize);
121 PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages,
122 bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff);
123 #endif
125 DVSTARTPROFILE();
127 (void)GL_REPORT_ERROR();
129 //glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]);
130 //glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW);
131 GL_REPORT_ERRORD();
133 // setup the pointers
134 if (g_nativeVertexFmt)
135 g_nativeVertexFmt->SetupVertexPointers();
136 GL_REPORT_ERRORD();
138 // set the textures
139 DVSTARTSUBPROFILE("VertexManager::Flush:textures");
141 u32 usedtextures = 0;
142 for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
143 if (bpmem.tevorders[i / 2].getEnable(i & 1))
144 usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
146 if (bpmem.genMode.numindstages > 0)
147 for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
148 if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
149 usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
151 for (int i = 0; i < 8; i++)
153 if (usedtextures & (1 << i))
155 glActiveTexture(GL_TEXTURE0 + i);
156 FourTexUnits &tex = bpmem.tex[i >> 2];
157 TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
158 (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
159 tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
160 tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
161 tex.texTlut[i&3].tlut_format);
163 if (tentry)
165 // 0s are probably for no manual wrapping needed.
166 PixelShaderManager::SetTexDims(i, tentry->Realw, tentry->Realh, 0, 0);
168 if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
170 // save the textures
171 char strfile[255];
172 sprintf(strfile, "%stex%.3d_%d.tga", File::GetUserPath(D_DUMPFRAMES_IDX), g_Config.iSaveTargetId, i);
173 SaveTexture(strfile, GL_TEXTURE_2D, tentry->texture, tentry->w, tentry->h);
176 else
177 ERROR_LOG(VIDEO, "error loading texture");
181 // set global constants
182 VertexShaderManager::SetConstants();
183 PixelShaderManager::SetConstants();
185 // finally bind
186 FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
187 VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
188 if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
189 if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
191 Draw();
193 // run through vertex groups again to set alpha
194 if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
196 ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
197 if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
199 // only update alpha
200 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
202 glDisable(GL_BLEND);
204 Draw();
205 // restore color mask
206 Renderer::SetColorMask();
208 if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
209 glEnable(GL_BLEND);
211 //s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
212 s_pCurBufferPointer = LocalVBuffer;
213 IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
215 #if defined(_DEBUG) || defined(DEBUGFAST)
216 if (g_ActiveConfig.iLog & CONF_SAVESHADERS)
218 // save the shaders
219 char strfile[255];
220 sprintf(strfile, "%sps%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX), g_ActiveConfig.iSaveTargetId);
221 std::ofstream fps(strfile);
222 fps << ps->strprog.c_str();
223 sprintf(strfile, "%svs%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX), g_ActiveConfig.iSaveTargetId);
224 std::ofstream fvs(strfile);
225 fvs << vs->strprog.c_str();
228 if (g_ActiveConfig.iLog & CONF_SAVETARGETS)
230 char str[128];
231 sprintf(str, "%starg%.3d.tga", File::GetUserPath(D_DUMPFRAMES_IDX), g_ActiveConfig.iSaveTargetId);
232 TargetRectangle tr;
233 tr.left = 0;
234 tr.right = Renderer::GetTargetWidth();
235 tr.top = 0;
236 tr.bottom = Renderer::GetTargetHeight();
237 Renderer::SaveRenderTarget(str, tr);
239 #endif
240 g_Config.iSaveTargetId++;
242 GL_REPORT_ERRORD();
245 } // namespace