TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture( unsigned int scaled_tex_w, unsigned int scaled_tex_h) { TCacheEntry *const entry = new TCacheEntry; glActiveTexture(GL_TEXTURE0+9); glBindTexture(GL_TEXTURE_2D, entry->texture); GL_REPORT_ERRORD(); const GLenum gl_format = GL_RGBA, gl_iformat = GL_RGBA, gl_type = GL_UNSIGNED_BYTE; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, scaled_tex_w, scaled_tex_h, 0, gl_format, gl_type, nullptr); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(1, &entry->framebuffer); FramebufferManager::SetFramebuffer(entry->framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, entry->texture, 0); GL_REPORT_FBO_ERROR(); SetStage(); GL_REPORT_ERRORD(); return entry; }
void RasterFont::printString(const char *s, double x, double y, double z) { int length = (int)strlen(s); if (!length) return; if (length >= TEMP_BUFFER_SIZE) length = TEMP_BUFFER_SIZE - 1; // Sanitize string to avoid GL errors. char *s2 = temp_buffer; memcpy(s2, s, length); s2[length] = 0; for (int i = 0; i < length; i++) { if (s2[i] < 32 || s2[i] > 126) s2[i] = '!'; } // go to the right spot glRasterPos3d(x, y, z); GL_REPORT_ERRORD(); glPushAttrib (GL_LIST_BIT); glListBase(fontOffset); glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2); GL_REPORT_ERRORD(); glPopAttrib(); GL_REPORT_ERRORD(); }
static void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type) { // uniform parameters GLint p; pf->prog.link = (void*)pf; // Setting autolink pf->prog.isFragment = true; // Setting autolink pf->ShaderType = ShaderTypes[pf->Shader]; pf->ParametersStart = NumActiveUniforms; ZZshProgram prog = madeProgram(pf->Shader, 0, ""); glUseProgram(prog); GL_REPORT_ERRORD(); SET_UNIFORMPARAM(sOneColor, "g_fOneColor"); SET_UNIFORMPARAM(sBitBltZ, "g_fBitBltZ"); SET_UNIFORMPARAM(sInvTexDims, "g_fInvTexDims"); SET_UNIFORMPARAM(fTexAlpha2, AddContextToName("fTexAlpha2", context)); SET_UNIFORMPARAM(fTexOffset, AddContextToName("g_fTexOffset", context)); SET_UNIFORMPARAM(fTexDims, AddContextToName("g_fTexDims", context)); SET_UNIFORMPARAM(fTexBlock, AddContextToName("g_fTexBlock", context)); SET_UNIFORMPARAM(fClampExts, AddContextToName("g_fClampExts", context)); // FIXME: There is a bug, that lead FFX-1 to incorrect CLAMP if this uniform have context. SET_UNIFORMPARAM(fTexWrapMode, AddContextToName("TexWrapMode", context)); SET_UNIFORMPARAM(fRealTexDims, AddContextToName("g_fRealTexDims", context)); SET_UNIFORMPARAM(fTestBlack, AddContextToName("g_fTestBlack", context)); SET_UNIFORMPARAM(fPageOffset, AddContextToName("g_fPageOffset", context)); SET_UNIFORMPARAM(fTexAlpha, AddContextToName("fTexAlpha", context)); GL_REPORT_ERRORD(); // textures INIT_SAMPLERPARAM(ptexBlocks, "g_sBlocks"); if (type == 3) {INIT_SAMPLERPARAM(ptexConv16to32, "g_sConv16to32");} else if (type == 4) {INIT_SAMPLERPARAM(ptexConv32to16, "g_sConv32to16");} else {INIT_SAMPLERPARAM(ptexBilinearBlocks, "g_sBilinearBlocks");} GL_REPORT_ERRORD(); SET_UNIFORMPARAM(sMemory, AddContextToName("g_sMemory", context)); SET_UNIFORMPARAM(sFinal, "g_sSrcFinal"); SET_UNIFORMPARAM(sBitwiseANDX, "g_sBitwiseANDX"); SET_UNIFORMPARAM(sBitwiseANDY, "g_sBitwiseANDY"); SET_UNIFORMPARAM(sCLUT, "g_sCLUT"); SET_UNIFORMPARAM(sInterlace, "g_sInterlace"); GL_REPORT_ERRORD(); // set global shader constants INIT_UNIFORMPARAM(float4(0.5f, (conf.settings().exact_color)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f), "g_fExactColor"); INIT_UNIFORMPARAM(float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ), "g_fBilinear"); INIT_UNIFORMPARAM(float4(1.0f/256.0f, 1.0004f, 1, 0.5f), "g_fZBias"); INIT_UNIFORMPARAM(float4(0,1, 0.001f, 0.5f), "g_fc0"); INIT_UNIFORMPARAM(float4(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f), "g_fMult"); pf->ParametersFinish = NumActiveUniforms; if (NumActiveUniforms > MAX_ACTIVE_UNIFORMS) ZZLog::Error_Log("Too many shader variables. You may increase the limit in source %d.", NumActiveUniforms); glUseProgram(0); GL_REPORT_ERRORD(); }
FRAGMENTSHADER* ZZshLoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed) { int texwrap; assert( texfilter < NUM_FILTERS ); //assert( g_nPixelShaderVer == SHADER_30 ); if( clamp.wms == clamp.wmt ) { switch( clamp.wms ) { case 0: texwrap = TEXWRAP_REPEAT; break; case 1: texwrap = TEXWRAP_CLAMP; break; case 2: texwrap = TEXWRAP_CLAMP; break; default: texwrap = TEXWRAP_REGION_REPEAT; break; } } else if( clamp.wms==3||clamp.wmt==3) texwrap = TEXWRAP_REGION_REPEAT; else texwrap = TEXWRAP_REPEAT_CLAMP; int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0); if( pbFailed != NULL ) *pbFailed = false; FRAGMENTSHADER* pf = ppsTexture+index; if (ZZshExistProgram(pf)) { return pf; } pf->Shader = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context); if (ZZshExistProgram(pf)) { SetupFragmentProgramParameters(pf, context, type); GL_REPORT_ERRORD(); if( glGetError() != GL_NO_ERROR ) { ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt); if (pbFailed != NULL ) *pbFailed = true; return pf; } return pf; } ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt); if( pbFailed != NULL ) *pbFailed = true; GL_REPORT_ERRORD(); return NULL; }
// A lot of times, the target is too big and overwrites the texture. // If tbp != 0, use it to bound. void VB::CheckFrame(int tbp) { GL_REPORT_ERRORD(); static int bChanged; if (bNeedZCheck) { ZZLog::Prim_Log("zbuf_%d: zbp=0x%x psm=0x%x, zmsk=%d\n", ictx, zbuf.zbp, zbuf.psm, zbuf.zmsk); //zbuf = *zb; } if (m_Blocks[gsfb.psm].bpp == 0) { ZZLog::Error_Log("CheckFrame invalid bpp %d.", gsfb.psm); return; } bChanged = 0; if (bNeedFrameCheck) { // important to set before calling GetTarg bNeedFrameCheck = 0; bNeedZCheck = 0; if (CheckFrameAddConstraints(tbp) == -1) return; if ((prndr != NULL) && (prndr->psm != gsfb.psm)) { // behavior for dest alpha varies // ResetAlphaVariables(); } bChanged = CheckFrameResolveRender(tbp); CheckFrame16vs32Conversion(); } else if (bNeedZCheck) { bNeedZCheck = 0; if (prndr != NULL && gsfb.fbw > 0) CheckFrameResolveDepth(tbp); } if (prndr != NULL) SetContextTarget(ictx); GL_REPORT_ERRORD(); }
// Flush == draw on screen // This function made VB state consistant before real Flush. void VB::FlushTexData() { GL_REPORT_ERRORD(); //assert(bNeedTexCheck); if (bNeedTexCheck) { bNeedTexCheck = 0; u32 psm = ZZOglGet_psm_TexBitsFix(uNextTex0Data[0]); // don't update unless necessary if (ZZOglAllExceptClutIsSame(uCurTex0Data, uNextTex0Data)) { // Don't need to do anything if there is no clutting and VB tex data was not changed if (!PSMT_ISCLUT(psm)) return; // have to write the CLUT again if only CLD was changed if (ZZOglClutMinusCLDunchanged(uCurTex0Data, uNextTex0Data)) { FlushTexUnchangedClutDontUpdate(); return; } // Cld bit is 0 means that clut buffer stay unchanged if (ZZOglGet_cld_TexBits(uNextTex0Data[1]) == 0) { FlushTexClutDontUpdate(); return; } } // Made the full update Flush(ictx); bVarsTexSync = false; bTexConstsSync = false; uCurTex0Data[0] = uNextTex0Data[0]; uCurTex0Data[1] = uNextTex0Data[1]; FlushTexSetNewVars(psm); if (PSMT_ISCLUT(psm)) CluttingForFlushedTex(&tex0, uNextTex0Data[1], ictx) ; GL_REPORT_ERRORD(); } }
void Clear() { u8 r = (bpmem.clearcolorAR & 0x00ff); u8 g = (bpmem.clearcolorGB & 0xff00) >> 8; u8 b = (bpmem.clearcolorGB & 0x00ff); u8 a = (bpmem.clearcolorAR & 0xff00) >> 8; GLfloat left = (GLfloat)bpmem.copyTexSrcXY.x / efbHalfWidth - 1.0f; GLfloat top = 1.0f - (GLfloat)bpmem.copyTexSrcXY.y / efbHalfHeight; GLfloat right = (GLfloat)(left + bpmem.copyTexSrcWH.x + 1) / efbHalfWidth - 1.0f; GLfloat bottom = 1.0f - (GLfloat)(top + bpmem.copyTexSrcWH.y + 1) / efbHalfHeight; GLfloat depth = (GLfloat)bpmem.clearZValue / (GLfloat)0x00ffffff; static const GLfloat verts[4][3] = { { left, top, depth }, { right, top, depth }, { right, bottom, depth }, { left, bottom, depth } }; { glUseProgram(clearProg); glVertexAttribPointer(clear_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); glUniform4f(clear_ucol, r, g, b, a); glEnableVertexAttribArray(col_apos); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(col_apos); } GL_REPORT_ERRORD(); }
// This is called after Initialize() from the Core // Run from the graphics thread void VideoBackend::Video_Prepare() { GLInterface->MakeCurrent(); g_renderer = new Renderer; s_efbAccessRequested = false; s_FifoShuttingDown = false; s_swapRequested = false; CommandProcessor::Init(); PixelEngine::Init(); g_texture_cache = new TextureCache; BPInit(); g_vertex_manager = new VertexManager; Fifo_Init(); // must be done before OpcodeDecoder_Init() OpcodeDecoder_Init(); VertexShaderCache::Init(); VertexShaderManager::Init(); PixelShaderCache::Init(); PixelShaderManager::Init(); PostProcessing::Init(); GL_REPORT_ERRORD(); VertexLoaderManager::Init(); TextureConverter::Init(); DLCache::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); }
static ZZshShader LoadShaderFromType(const char* srcdir, const char* srcfile, int type, int texfilter, int texwrap, int fog, int writedepth, int testaem, int exactcolor, int ps, int context) { assert( texwrap < NUM_TEXWRAPS); assert( type < NUM_TYPES ); //ZZLog::Error_Log("\n"); ZZshProgram prog; char* name = new char[MAX_SHADER_NAME_SIZE]; sprintf(name, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]); ZZLog::Debug_Log("Starting shader for %s", name); const char* AddWrap = g_pPsTexWrap[texwrap]; const char* AddDepth = writedepth?"#define WRITE_DEPTH 1\n":""; const char* AddAEM = testaem?"#define TEST_AEM 1\n":""; const char* AddExcolor = exactcolor?"#define EXACT_COLOR 1\n":""; const char* AddAccurate = (ps & SHADER_ACCURATE)?"#define ACCURATE_DECOMPRESSION 1\n":""; char DefineString[DEFINE_STRING_SIZE] = ""; char temp[200]; GlslHeaderString(temp, name, AddWrap); sprintf(DefineString, "%s#define FRAGMENT_SHADER 1\n%s%s%s%s\n#define CTX %d\n", temp, AddDepth, AddAEM, AddExcolor, AddAccurate, context * NOCONTEXT); ZZshShader shader; if (!CompileShader(shader, DefineString, name, GL_FRAGMENT_SHADER)) return UseEmptyShader(name, GL_FRAGMENT_SHADER); ZZLog::Debug_Log("Used shader for type:%d filter:%d wrap:%d for:%d depth:%d aem:%d color:%d decompression:%d ctx:%d... Ok \n", type, texfilter, texwrap, fog, writedepth, testaem, exactcolor, ps, context); GL_REPORT_ERRORD(); return shader; }
void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc, const MathUtil::Rectangle<float> &drawrc, int width, int height) const { // Texture map xfbSource->texture onto the main buffer glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glBegin(GL_QUADS); glTexCoord2f(sourcerc.left, sourcerc.bottom); glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); glVertex2f(drawrc.left, drawrc.bottom); glTexCoord2f(sourcerc.left, sourcerc.top); glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); glVertex2f(drawrc.left, drawrc.top); glTexCoord2f(sourcerc.right, sourcerc.top); glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); glVertex2f(drawrc.right, drawrc.top); glTexCoord2f(sourcerc.right, sourcerc.bottom); glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); glVertex2f(drawrc.right, drawrc.bottom); glEnd(); GL_REPORT_ERRORD(); }
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int level) { if (pcfmt != PC_TEX_FMT_DXT1) { glActiveTexture(GL_TEXTURE0+9); glBindTexture(GL_TEXTURE_2D, texture); if (expanded_width != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width); glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, temp); if (expanded_width != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { PanicAlert("PC_TEX_FMT_DXT1 support disabled"); //glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, //width, height, 0, expanded_width * expanded_height/2, temp); } TextureCache::SetStage(); GL_REPORT_ERRORD(); }
// Should be scale free. void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture) { u8* srcAddr = Memory::GetPointer(xfbAddr); if (!srcAddr) { WARN_LOG(VIDEO, "Tried to decode from invalid memory address"); return; } g_renderer->ResetAPIState(); // reset any game specific settings // switch to texture converter frame buffer // attach destTexture as color destination FramebufferManager::SetFramebuffer(s_texConvFrameBuffer[1]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destTexture, 0); GL_REPORT_FBO_ERROR(); // activate source texture // set srcAddr as data for source texture glActiveTexture(GL_TEXTURE0+9); glBindTexture(GL_TEXTURE_2D, s_srcTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, srcWidth / 2, srcHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr); glViewport(0, 0, srcWidth, srcHeight); s_yuyvToRgbProgram.Bind(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); FramebufferManager::SetFramebuffer(0); g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); }
void SetupVertexProgramParameters(VERTEXSHADER* pf, int context) { GLint p; pf->prog.link = (void*)pf; // Setting autolink pf->prog.isFragment = false; // Setting autolink pf->ShaderType = ShaderTypes[pf->Shader]; pf->ParametersStart = NumActiveUniforms; ZZshProgram prog = madeProgram(pf->Shader, 0, ""); glUseProgram(prog); GL_REPORT_ERRORD(); // Set Z-test, log or no log; if (conf.settings().no_logz) { g_vdepth = float4( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f)); vlogz = float4( 1.0f, 0.0f, 0.0f, 0.0f); } else { g_vdepth = float4( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f); vlogz = float4( 0.0f, 1.0f, 0.0f, 0.0f); } INIT_UNIFORMPARAM(g_vdepth, "g_fZ"); if (p > -1) { INIT_UNIFORMPARAM(vlogz, "g_fZMin"); if (p == -1) ZZLog::Error_Log ("Shader file version is outdated! Only log-Z is possible."); } GL_REPORT_ERRORD(); float4 vnorm = float4(g_filog32, 0, 0,0); INIT_UNIFORMPARAM(vnorm, "g_fZNorm"); INIT_UNIFORMPARAM(float4(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ), "g_fBilinear"); INIT_UNIFORMPARAM(float4(1.0f/256.0f, 1.0004f, 1, 0.5f), "g_fZBias") ; INIT_UNIFORMPARAM(float4(0,1, 0.001f, 0.5f), "g_fc0"); SET_UNIFORMPARAM(sBitBltPos, "g_fBitBltPos"); SET_UNIFORMPARAM(sBitBltTex, "g_fBitBltTex"); SET_UNIFORMPARAM(fBitBltTrans, "g_fBitBltTrans"); pf->ParametersFinish = NumActiveUniforms; if (NumActiveUniforms > MAX_ACTIVE_UNIFORMS) ZZLog::Error_Log("Too many shader variables. You may increase the limit in the source."); glUseProgram(0); GL_REPORT_ERRORD(); }
static void PutParametersInProgam(int start, int finish) { for (int i = start; i < finish; i++) { ZZshParamInfo param = UniformsIndex[i]; GLint location = glGetUniformLocation(ZZshMainProgram, param.ShName); if (location != -1 && param.type != ZZ_UNDEFINED) { UNIFORM_ERROR_LOG("\tTry uniform %d %d %d %s...\t\t", i, location, param.type, param.ShName); if (!param.Settled && !param.Constant) { UNIFORM_ERROR_LOG("\tUnsettled, non-constant uniform, could be bug: %d %s", param.type, param.ShName); continue; } if (param.type == ZZ_FLOAT4) { glUniform4fv(location, 1, param.fvalue); } else { // assert(param.texid != 0); // ZZLog::Error_Log("Set texture (%s) : %d with sampler %d\n", param.ShName, param.texid, param.sampler); // assert(param.sampler >= 0); glActiveTexture(GL_TEXTURE0 + param.sampler); if (param.type == ZZ_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, param.texid); else if (param.type == ZZ_TEXTURE_3D) glBindTexture(GL_TEXTURE_3D, param.texid); else glBindTexture(GL_TEXTURE_RECTANGLE, param.texid); GL_REPORT_ERRORD(); } if (glGetError() == GL_NO_ERROR) UNIFORM_ERROR_LOG("Ok. Param name %s, location %d, type %d", param.ShName, location, param.type); else ZZLog::Error_Log("error in PutParametersInProgam param name %s, location %d, type %d", param.ShName, location, param.type); if (!param.Constant) // Unset used parameters UniformsIndex[i].Settled == false; } else if (start != 0 && location == -1 && param.Settled) // No global variable ZZLog::Error_Log("Warning! Unused, but set uniform %d, %s", location, param.ShName); } GL_REPORT_ERRORD(); }
void SWRenderer::DrawTexture(u8 *texture, int width, int height) { // FIXME: This should add black bars when the game has set the VI to render less than the full xfb. // Save screenshot if (s_bScreenshot) { std::lock_guard<std::mutex> lk(s_criticalScreenshot); TextureToPng(texture, width*4, s_sScreenshotName, width, height, false); // Reset settings s_sScreenshotName.clear(); s_bScreenshot = false; } GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth(); GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight(); // Update GLViewPort glViewport(0, 0, glWidth, glHeight); glScissor(0, 0, glWidth, glHeight); glBindTexture(GL_TEXTURE_2D, s_RenderTarget); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glUseProgram(program); static const GLfloat verts[4][2] = { { -1, -1}, // Left top { -1, 1}, // left bottom { 1, 1}, // right bottom { 1, -1} // right top }; static const GLfloat texverts[4][2] = { {0, 1}, {0, 0}, {1, 0}, {1, 1} }; glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts); glEnableVertexAttribArray(attr_pos); glEnableVertexAttribArray(attr_tex); glUniform1i(uni_tex, 0); glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(attr_pos); glDisableVertexAttribArray(attr_tex); glBindTexture(GL_TEXTURE_2D, 0); GL_REPORT_ERRORD(); }
void XFBSource::Draw(const MathUtil::Rectangle<int> &sourcerc, const MathUtil::Rectangle<float> &drawrc) const { // Texture map xfbSource->texture onto the main buffer glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glBlitFramebuffer(sourcerc.left, sourcerc.bottom, sourcerc.right, sourcerc.top, (int)drawrc.left, (int)drawrc.bottom, (int)drawrc.right, (int)drawrc.top, GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_REPORT_ERRORD(); }
void VertexManager::DestroyDeviceObjects() { GL_REPORT_ERRORD(); glBindBuffer(GL_ARRAY_BUFFER, 0 ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 ); GL_REPORT_ERROR(); delete s_vertexBuffer; delete s_indexBuffer; GL_REPORT_ERROR(); }
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) { g_renderer->ResetAPIState(); s_rgbToYuyvProgram.Bind(); EncodeToRamUsingShader(srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); TextureCache::DisableStage(0); g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); }
void SWRenderer::Prepare() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment glGenTextures(1, &s_RenderTarget); CreateShaders(); // TODO: Enable for GLES once RasterFont supports GLES #ifndef USE_GLES s_pfont = new RasterFont(); glEnable(GL_TEXTURE_2D); #endif GL_REPORT_ERRORD(); }
void DrawColorVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) { float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f; float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight); float z0 = v0->screenPosition.z / (float)0x00ffffff; float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f; float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight); float z1 = v1->screenPosition.z / (float)0x00ffffff; float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f; float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight); float z2 = v2->screenPosition.z / (float)0x00ffffff; float r0 = v0->color[0][OutputVertexData::RED_C] / 255.0f; float g0 = v0->color[0][OutputVertexData::GRN_C] / 255.0f; float b0 = v0->color[0][OutputVertexData::BLU_C] / 255.0f; float r1 = v1->color[0][OutputVertexData::RED_C] / 255.0f; float g1 = v1->color[0][OutputVertexData::GRN_C] / 255.0f; float b1 = v1->color[0][OutputVertexData::BLU_C] / 255.0f; float r2 = v2->color[0][OutputVertexData::RED_C] / 255.0f; float g2 = v2->color[0][OutputVertexData::GRN_C] / 255.0f; float b2 = v2->color[0][OutputVertexData::BLU_C] / 255.0f; static const GLfloat verts[3][3] = { { x0, y0, z0 }, { x1, y1, z1 }, { x2, y2, z2 } }; static const GLfloat col[3][4] = { { r0, g0, b0, 1.0f }, { r1, g1, b1, 1.0f }, { r2, g2, b2, 1.0f } }; { glUseProgram(colProg); glEnableVertexAttribArray(col_apos); glEnableVertexAttribArray(col_atex); glVertexAttribPointer(col_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(col_atex, 4, GL_FLOAT, GL_FALSE, 0, col); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(col_atex); glDisableVertexAttribArray(col_apos); } GL_REPORT_ERRORD(); }
static void CreateNewProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) { ZZLog::Error_Log("\n---> New shader program %d, %s(%d) \t+\t%s(%d).", ZZshMainProgram, ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader); if (vs->Shader != 0) glAttachShader(ZZshMainProgram, vs->Shader); if (ps->Shader != 0) glAttachShader(ZZshMainProgram, ps->Shader); glLinkProgram(ZZshMainProgram); if (!GetLinkLog(ZZshMainProgram)) { ZZLog::Error_Log("Main program linkage error, don't use any shader for this stage."); return; } GL_REPORT_ERRORD(); }
void DrawTextureVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) { float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f; float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight); float z0 = v0->screenPosition.z; float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f; float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight); float z1 = v1->screenPosition.z; float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f; float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight); float z2 = v2->screenPosition.z; float s0 = v0->texCoords[0].x / width; float t0 = v0->texCoords[0].y / height; float s1 = v1->texCoords[0].x / width; float t1 = v1->texCoords[0].y / height; float s2 = v2->texCoords[0].x / width; float t2 = v2->texCoords[0].y / height; static const GLfloat verts[3][3] = { { x0, y0, z0 }, { x1, y1, z1 }, { x2, y2, z2 } }; static const GLfloat tex[3][2] = { { s0, t0 }, { s1, t1 }, { s2, t2 } }; { glUseProgram(texProg); glEnableVertexAttribArray(tex_apos); glEnableVertexAttribArray(tex_atex); glVertexAttribPointer(tex_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(tex_atex, 2, GL_FLOAT, GL_FALSE, 0, tex); glUniform1i(tex_utex, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(tex_atex); glDisableVertexAttribArray(tex_apos); } GL_REPORT_ERRORD(); }
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) { g_renderer->ResetAPIState(); s_rgbToYuyvProgram.Bind(); glUniform4f(s_rgbToYuyvUniform_loc, sourceRc.left, sourceRc.top, sourceRc.right, sourceRc.bottom); // We enable linear filtering, because the gamecube does filtering in the vertical direction when // yscale is enabled. // Otherwise we get jaggies when a game uses yscaling (most PAL games) EncodeToRamUsingShader(srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, dstWidth*dstHeight*2, true); FramebufferManager::SetFramebuffer(0); TextureCache::DisableStage(0); g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); }
void SWRenderer::SwapBuffer() { // Do our OSD callbacks OSD::DoCallbacks(OSD::OSD_ONFRAME); DrawDebugText(); glFlush(); GLInterface->Swap(); swstats.ResetFrame(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_REPORT_ERRORD(); }
void PutSInProgam(int start, int finish) { for (int i = start; i < finish; i++) { ZZshParamInfo param = UniformsIndex[i]; GLint location = glGetUniformLocation(ZZshMainProgram, param.ShName); if (location != -1 && param.type != ZZ_UNDEFINED) { if (param.type != ZZ_FLOAT4) { UNIFORM_ERROR_LOG("\tTry sampler %d %d %d %s %d...\t\t", i, location, param.type, param.ShName, param.sampler); if (glGetError() == GL_NO_ERROR) UNIFORM_ERROR_LOG("Ok"); else UNIFORM_ERROR_LOG("error!"); glUniform1i(location, param.sampler); } } } GL_REPORT_ERRORD(); }
bool CRenderTarget::Create(const frameInfo& frame) { FUNCLOG Resolve(); Destroy(); created = 123; lastused = timeGetTime(); fbp = frame.fbp; fbw = frame.fbw; fbh = frame.fbh; psm = (u8)frame.psm; fbm = frame.fbm; vposxy.x = 2.0f * (1.0f / 8.0f) / (float)fbw; vposxy.y = 2.0f * (1.0f / 8.0f) / (float)fbh; vposxy.z = -1.0f - 0.5f / (float)fbw; vposxy.w = -1.0f + 0.5f / (float)fbh; status = 0; if (fbw > 0 && fbh > 0) { GetRectMemAddressZero(start, end, psm, fbw, fbh, fbp, fbw); psys = _aligned_malloc(Tex_Memory_Size(fbw, fbh), 16); GL_REPORT_ERRORD(); if (!InitialiseDefaultTexture(&ptex, RW(fbw), RH(fbh))) { Destroy(); return false; } status = TS_NeedUpdate; } else { start = end = 0; } return true; }
void SWRenderer::DrawTexture(u8 *texture, int width, int height) { GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth(); GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight(); // Update GLViewPort glViewport(0, 0, glWidth, glHeight); glScissor(0, 0, glWidth, glHeight); glBindTexture(GL_TEXTURE_2D, s_RenderTarget); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glUseProgram(program); static const GLfloat verts[4][2] = { { -1, -1}, // Left top { -1, 1}, // left bottom { 1, 1}, // right bottom { 1, -1} // right top }; static const GLfloat texverts[4][2] = { {0, 1}, {0, 0}, {1, 0}, {1, 1} }; glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts); glEnableVertexAttribArray(attr_pos); glEnableVertexAttribArray(attr_tex); glUniform1i(uni_tex, 0); glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(attr_pos); glDisableVertexAttribArray(attr_tex); glBindTexture(GL_TEXTURE_2D, 0); GL_REPORT_ERRORD(); }
void SWRenderer::Prepare() { s_xfbColorTexture[0] = new u8[640*568*4]; s_xfbColorTexture[1] = new u8[640*568*4]; s_currentColorTexture = 0; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment glGenTextures(1, &s_RenderTarget); CreateShaders(); // TODO: Enable for GLES once RasterFont supports GLES if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) { s_pfont = new RasterFont(); glEnable(GL_TEXTURE_2D); } GL_REPORT_ERRORD(); }
void ZZshSetupShader() { VERTEXSHADER* vs = (VERTEXSHADER*)g_vsprog.link; FRAGMENTSHADER* ps = (FRAGMENTSHADER*)g_psprog.link; if (vs == NULL || ps == NULL) return; // From the glValidateProgram docs: "The implementation may use this as an opportunity to perform any internal // shader modifications that may be required to ensure correct operation of the installed // shaders given the current GL state" // It might be a good idea to validate the pipeline also in release mode??? #if defined(DEVBUILD) || defined(_DEBUG) glValidateProgramPipeline(s_pipeline); GLint isValid; glGetProgramPipelineiv(s_pipeline, GL_VALIDATE_STATUS, &isValid); if (!isValid) ZZLog::Error_Log("Something weird happened on pipeline validation."); #endif PutParametersInProgram(vs, ps); GL_REPORT_ERRORD(); }
static void PutParametersAndRun(VERTEXSHADER* vs, FRAGMENTSHADER* ps) { UNIFORM_ERROR_LOG("Run program %s(%d) \t+\t%s(%d)", ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader); glUseProgram(ZZshMainProgram); if (glGetError() != GL_NO_ERROR) { ZZLog::Error_Log("Something weird happened on Linking stage."); glUseProgram(0); return; } PutSInProgam(vs->ParametersStart, vs->ParametersFinish); PutSInProgam(ps->ParametersStart, ps->ParametersFinish); PutParametersInProgam(0, NumGlobalUniforms); PutParametersInProgam(vs->ParametersStart, vs->ParametersFinish); PutParametersInProgam(ps->ParametersStart, ps->ParametersFinish); ValidateProgram(ZZshMainProgram); GL_REPORT_ERRORD(); }