// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane. void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { Application* application = Application::getInstance(); QGLWidget* glWidget = application->getGLWidget(); MyAvatar* myAvatar = application->getAvatar(); const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); // Get vertical FoV of the displayed overlay texture const float halfVerticalAngle = _oculusAngle / 2.0f; const float overlayAspectRatio = glWidget->width() / (float)glWidget->height(); const float halfOverlayHeight = _distance * tan(halfVerticalAngle); const float overlayHeight = halfOverlayHeight * 2.0f; // The more vertices, the better the curve const int numHorizontalVertices = 20; const int numVerticalVertices = 20; // U texture coordinate width at each quad const float quadTexWidth = 1.0f / (numHorizontalVertices - 1); const float quadTexHeight = 1.0f / (numVerticalVertices - 1); // Get horizontal angle and angle increment from vertical angle and aspect ratio const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio; const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1); const float halfHorizontalAngle = horizontalAngle / 2; const float verticalAngleIncrement = _oculusAngle / (numVerticalVertices - 1); glActiveTexture(GL_TEXTURE0); glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // Transform to world space glm::quat rotation = whichCamera.getRotation(); glm::vec3 axis2 = glm::axis(rotation); glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z); glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z); // Translate to the front of the camera glm::vec3 pos = whichCamera.getPosition(); glm::quat rot = myAvatar->getOrientation(); glm::vec3 axis = glm::axis(rot); glTranslatef(pos.x, pos.y, pos.z); glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z); glColor3f(1.0f, 1.0f, 1.0f); glDepthMask(GL_TRUE); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.01f); float leftX, rightX, leftZ, rightZ, topZ, bottomZ; //Draw the magnifiers for (int i = 0; i < _numMagnifiers; i++) { renderMagnifier(_mouseX[i], _mouseY[i]); } glDepthMask(GL_FALSE); glDisable(GL_ALPHA_TEST); //TODO: Remove immediate mode in favor of VBO if (_uiType == HEMISPHERE) { renderTexturedHemisphere(); } else{ glBegin(GL_QUADS); // Place the vertices in a semicircle curve around the camera for (int i = 0; i < numHorizontalVertices - 1; i++) { for (int j = 0; j < numVerticalVertices - 1; j++) { // Calculate the X and Z coordinates from the angles and radius from camera leftX = sin(angleIncrement * i - halfHorizontalAngle) * _distance; rightX = sin(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; leftZ = -cos(angleIncrement * i - halfHorizontalAngle) * _distance; rightZ = -cos(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; if (_uiType == 2) { topZ = -cos((verticalAngleIncrement * (j + 1) - halfVerticalAngle) * overlayAspectRatio) * _distance; bottomZ = -cos((verticalAngleIncrement * j - halfVerticalAngle) * overlayAspectRatio) * _distance; } else { topZ = -99999; bottomZ = -99999; } glTexCoord2f(quadTexWidth * i, (j + 1) * quadTexHeight); glVertex3f(leftX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, leftZ)); glTexCoord2f(quadTexWidth * (i + 1), (j + 1) * quadTexHeight); glVertex3f(rightX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, rightZ)); glTexCoord2f(quadTexWidth * (i + 1), j * quadTexHeight); glVertex3f(rightX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, rightZ)); glTexCoord2f(quadTexWidth * i, j * quadTexHeight); glVertex3f(leftX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, leftZ)); } } glEnd(); } glPopMatrix(); glDepthMask(GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glEnable(GL_LIGHTING); }
void rglSetCombiner(rglRenderChunk_t & chunk, int format) { static char _1ma[64]; static char t1[64]; static char t1a[64]; static char t2[64]; static char t2a[64]; static char prim_lod_frac[64]; static const char *saRGB[] = { "c", t1, t2, "p/*PRIM*/", "gl_Color", "e", "1.0/*NOISE*/", "1.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0" }; static const char *mRGB[] = { "c", t1, t2, "p/*PRIM*/", "gl_Color/*SHADE*/","e", "0.0/*SCALE*/", "c.a/*COMBINED_A*/", "t1.a/*TEXEL0_A*/", "t2.a/*TEXEL1_A*/", "p.a/*PRIM_A*/", "gl_Color.a/*SHADEA*/", "e.a/*ENV_ALPHA*/", "0.5/*LOD_FRACTION*/","0.5/*PRIM_LOD_FRAC*/","k5/*K5*/", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "0.0" }; static const char *aRGB[] = { "c", t1, t2, "p/*PRIM*/", "gl_Color/*SHADE*/","e/*ENV*/", "1.0", "0.0", }; static const char *saA[] = { "c.a", t1a, t2a, "p.a/*PRIM*/", "gl_Color.a", "e.a", "1.0", "0.0", }; static const char *sbA[] = { "c.a", t1a, t2a, "p.a/*PRIM*/", "gl_Color.a", "e.a", "1.0", "0.0", }; static const char *mA[] = { "0.5/*LOD_FRACTION*/", t1a, t2a, "p.a/*PRIM*/", "gl_Color.a/*SHADE*/", "e.a", prim_lod_frac, "0.0", }; static const char *aA[] = { "c.a", t1a, t2a, "p.a/*PRIM*/", "gl_Color.a/*SHADE*/", "e.a", "1.0", "0.0", }; const static char * bRGB[] = { "c/*PREV*/", "f", "b", "fog/*FOG*/" }; const static char * bA[2][4] = { {"c.a/*PREVA*/", "fog.a/*FOGA*/", "gl_Color.a/*SHADEA*/", "0.0/*ZERO*/"}, {_1ma/*"(1.0-c.a/ *PREVA)"*/, "0.0/*f.a*//*FRAGA*/", "1.0", "0.0"}}; // need clamping on 1-alpha ? rdpState_t & state = chunk.rdpState; static rglCombiner_t * c; uint32_t cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes); int i; //, fmt, size; char * p; const char * alphaTest; const char * alphaTest2; const char * write; static char src[4*4096]; float env[4]; env[0] = RDP_GETC32_R(state.envColor)/255.0f; env[1] = RDP_GETC32_G(state.envColor)/255.0f; env[2] = RDP_GETC32_B(state.envColor)/255.0f; env[3] = RDP_GETC32_A(state.envColor)/255.0f; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env); env[0] = RDP_GETC32_R(state.blendColor)/255.0f; env[1] = RDP_GETC32_G(state.blendColor)/255.0f; env[2] = RDP_GETC32_B(state.blendColor)/255.0f; env[3] = RDP_GETC32_A(state.blendColor)/255.0f; glLightfv(GL_LIGHT0, GL_AMBIENT, env); env[0] = RDP_GETC32_R(state.fogColor)/255.0f; env[1] = RDP_GETC32_G(state.fogColor)/255.0f; env[2] = RDP_GETC32_B(state.fogColor)/255.0f; env[3] = RDP_GETC32_A(state.fogColor)/255.0f; glLightfv(GL_LIGHT0, GL_DIFFUSE, env); glActiveTextureARB(GL_TEXTURE1_ARB); env[0] = state.k5/255.0f; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env); if (cycle == RDP_CYCLE_TYPE_FILL) { if (0/*fb_size == 3*/) { // FIXME env[0] = RDP_GETC32_R(state.fillColor)/255.0f; env[1] = RDP_GETC32_G(state.fillColor)/255.0f; env[2] = RDP_GETC32_B(state.fillColor)/255.0f; env[3] = RDP_GETC32_A(state.fillColor)/255.0f; } else { env[0] = RDP_GETC16_R(state.fillColor)/31.0f; env[1] = RDP_GETC16_G(state.fillColor)/31.0f; env[2] = RDP_GETC16_B(state.fillColor)/31.0f; env[3] = RDP_GETC16_A(state.fillColor); } } else { env[0] = RDP_GETC32_R(state.primColor)/255.0f; env[1] = RDP_GETC32_G(state.primColor)/255.0f; env[2] = RDP_GETC32_B(state.primColor)/255.0f; env[3] = RDP_GETC32_A(state.primColor)/255.0f; } glLightfv(GL_LIGHT0, GL_SPECULAR, env); glActiveTextureARB(GL_TEXTURE0_ARB); rglAssert(glGetError() == GL_NO_ERROR); // if (c && rglNbCombiners && // RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle && // (RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 || // (!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t)) && // !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t))))) { // return; // } for (i=0; i<rglNbCombiners; i++) { c = rglCombiners + i; if (c->format == format && RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle && (RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 || (!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t)) && !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t)) ))) { #ifdef RDP_DEBUG chunk.shader = c->shader; #endif rglUseShader(c->shader); goto ok; } } if (rglNbCombiners == RGL_MAX_COMBINERS) rglClearCombiners(); c = rglCombiners + rglNbCombiners++; c->otherModes = state.otherModes; c->combineModes = state.combineModes; c->format = format; #ifndef RGL_EXACT_BLEND c->srcBlend = GL_ONE; c->dstBlend = GL_ZERO; #endif switch (format & RGL_COMB_FMT) { case RGL_COMB_FMT_RGBA: write = "gl_FragColor = c;"; break; case RGL_COMB_FMT_I: write = "gl_FragColor = vec4(c[0]);"; break; case RGL_COMB_FMT_DEPTH: write = "gl_FragDepth = c[0];"; break; } if (cycle == RDP_CYCLE_TYPE_FILL) { sprintf( src, "void main() \n" "{ \n" //" c = gl_TextureEnvColor[1];\n" " vec4 c = gl_LightSource[0].specular;\n" " %s\n" "} \n", write); c->shader = rglCreateShader( "void main() \n" "{ \n" " gl_Position = ftransform(); \n" " gl_FrontColor = gl_Color; \n" " gl_BackColor = gl_Color; \n" " gl_TexCoord[0] = gl_MultiTexCoord0; \n" "} \n" , src ); #ifdef RDP_DEBUG chunk.shader = c->shader; #endif rglUseShader(c->shader); goto ok; } alphaTest = ""; alphaTest2 = ""; if (//cycle < 2 && // CHECK THIS RDP_GETOM_CVG_TIMES_ALPHA(chunk.rdpState.otherModes) //&& rglT1Usage(chunk.rdpState) ) { if (RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes)) alphaTest = "if (c.a < 0.5) discard; \n"; else alphaTest = "if (t1.a < 0.5) discard; \n"; alphaTest2 = "if (c.a < 0.5) discard; \n"; } else if (RDP_GETOM_ALPHA_COMPARE_EN(chunk.rdpState.otherModes) && !RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes)) { if (RDP_GETC32_A(chunk.rdpState.blendColor) > 0) { alphaTest = "if (c.a < b.a) discard; \n"; alphaTest2 = " vec4 b = gl_LightSource[0].ambient; \n" " if (c.a < b.a) discard; \n"; //alphaTest2 = "if (c.a < 0.5) discard; \n"; } else { alphaTest = "if (c.a == 0.0) discard; \n"; alphaTest2 = "if (c.a == 0.0) discard; \n"; } } if (cycle == RDP_CYCLE_TYPE_COPY) { sprintf( src, "uniform sampler2D texture0; \n" " \n" "void main() \n" "{ \n" " vec4 c = texture2D(texture0, vec2(gl_TexCoord[0])); \n" " %s" " %s\n" "} \n", alphaTest2, write ); c->shader = rglCreateShader( "void main() \n" "{ \n" " gl_Position = ftransform(); \n" " gl_FrontColor = gl_Color; \n" " gl_BackColor = gl_Color; \n" " gl_TexCoord[0] = gl_MultiTexCoord0; \n" "} \n" , src ); #ifdef RDP_DEBUG chunk.shader = c->shader; #endif rglUseShader(c->shader); goto ok; } p = src; p += sprintf(p, "uniform sampler2D texture0; \n" "uniform sampler2D texture2; \n" #ifdef RGL_EXACT_BLEND "uniform sampler2D texture1; \n" #endif " \n" "void main() \n" "{ \n" "vec4 c = vec4(0,0,0,0);\n" "vec4 e = gl_TextureEnvColor[0];\n" "float k5 = gl_TextureEnvColor[1][0];\n" "vec4 p = gl_LightSource[0].specular;\n" #ifdef RGL_EXACT_BLEND "vec4 f = texture2D(texture1, vec2(gl_FragCoord.x/(2048.0*gl_TexCoord[1].x), gl_FragCoord.y/(2048.0*gl_TexCoord[1].y))); \n" #endif "vec4 fog = gl_LightSource[0].diffuse; \n" "vec4 b = gl_LightSource[0].ambient; \n"); switch (format & RGL_COMB_IN0) { case 0: p += sprintf(p, "vec4 t1 = texture2D(texture0, vec2(gl_TexCoord[0]));\n"); break; case RGL_COMB_IN0_DEPTH: p += sprintf(p, "vec4 t1 = vec4(texture2D(texture0, vec2(gl_TexCoord[0]))[0]);\n"); break; } switch (format & RGL_COMB_IN1) { case 0: p += sprintf(p, "vec4 t2 = texture2D(texture2, vec2(gl_TexCoord[2]));\n"); break; case RGL_COMB_IN1_DEPTH: p += sprintf(p, "vec4 t2 = vec4(texture2D(texture2, vec2(gl_TexCoord[2]))[0]);\n"); break; } const char * comb, * comb2; comb2 = 0; // switch (RDP_GETOM_CVG_DEST(state.otherModes)) // { // case 3: // comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n"; // break; // case 2: // comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n"; // //comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a*((%s - %s) * %s + %s));\n"; // break; // case 0: // //comb2 = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a);\n"; // case 1: // comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n"; // break; // } comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n"; strcpy(prim_lod_frac, "0.5/*PRIM_LOD_FRAC*/"); strcpy(t1, "t1"); strcpy(t1a, "t1.a"); if (format & RGL_COMB_TILE7) { strcpy(t2, "t1"); strcpy(t2a, "t1.a"); } else { strcpy(t2, "t2"); strcpy(t2a, "t2.a"); } p += sprintf(p, comb , saRGB[RDP_GETCM_SUB_A_RGB0(state.combineModes)], saRGB[RDP_GETCM_SUB_B_RGB0(state.combineModes)], mRGB[RDP_GETCM_MUL_RGB0(state.combineModes)], aRGB[RDP_GETCM_ADD_RGB0(state.combineModes)], saA[RDP_GETCM_SUB_A_A0(state.combineModes)], sbA[RDP_GETCM_SUB_B_A0(state.combineModes)], mA[RDP_GETCM_MUL_A0(state.combineModes)], aA[RDP_GETCM_ADD_A0(state.combineModes)] ); if (cycle == RDP_CYCLE_TYPE_2) { if (!(format & RGL_COMB_TILE7)) { strcpy(t1, "t2"); strcpy(t1a, "t2.a"); strcpy(t2, "t1"); strcpy(t2a, "t1.a"); } //strcpy(prim_lod_frac, "0.0/*PRIM_LOD_FRAC*/"); // if (!RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes)) // p += // sprintf(p, " c.a = t1.a; \n"); p += sprintf(p, comb2? comb2 : comb , saRGB[RDP_GETCM_SUB_A_RGB1(state.combineModes)], saRGB[RDP_GETCM_SUB_B_RGB1(state.combineModes)], mRGB[RDP_GETCM_MUL_RGB1(state.combineModes)], aRGB[RDP_GETCM_ADD_RGB1(state.combineModes)], saA[RDP_GETCM_SUB_A_A1(state.combineModes)], sbA[RDP_GETCM_SUB_B_A1(state.combineModes)], mA[RDP_GETCM_MUL_A1(state.combineModes)], aA[RDP_GETCM_ADD_A1(state.combineModes)] ); } // if (!RDP_GETOM_CVG_TIMES_ALPHA(state.otherModes)) // p += sprintf(p, "c.a = t1.a; \n"); p += sprintf(p, "%s", alphaTest); const char * blender; blender = "c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), 1.0); \n"; #ifdef RGL_EXACT_BLEND const char * noblender = "c.a = 1.0;\n"; #endif int m1b, m1a, m2b, m2a; //LOG("New combiner / blender :\n%s", rglCombiner2String(state)); if (cycle == RDP_CYCLE_TYPE_2) { if (RDP_GETOM_FORCE_BLEND(state.otherModes)) { #ifndef RGL_EXACT_BLEND if (RDP_GETOM_BLEND_M1A_0(state.otherModes) != 1 && RDP_GETOM_BLEND_M2A_0(state.otherModes) != 1) { #endif sprintf(_1ma, "(1.0 - %s)", bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)]); p += sprintf( p, "c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), c.a); \n" ,bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)], bRGB[RDP_GETOM_BLEND_M1A_0(state.otherModes)], bA[1][RDP_GETOM_BLEND_M2B_0(state.otherModes)], bRGB[RDP_GETOM_BLEND_M2A_0(state.otherModes)] ); #ifndef RGL_EXACT_BLEND } else { LOG("Blender error : fragment in cycle 1\n%s", rglCombiner2String(state)); } #endif m1b = RDP_GETOM_BLEND_M1B_1(state.otherModes); m1a = RDP_GETOM_BLEND_M1A_1(state.otherModes); m2b = RDP_GETOM_BLEND_M2B_1(state.otherModes); m2a = RDP_GETOM_BLEND_M2A_1(state.otherModes); } else { m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes); m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes); m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes); m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes); } } else { m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes); m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes); m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes); m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes); } if (RDP_GETOM_FORCE_BLEND(state.otherModes) || cycle == RDP_CYCLE_TYPE_2) { #ifndef RGL_EXACT_BLEND if (m1a == 1 || m2a == 1) { if (/*(m1a != 1 || m1b == 3) &&*/ (m2a == 1 || m2b == 3)) { int src = GL_ZERO, dst = GL_ONE; const char * alpha = "c.a"; switch (m1b) { case 0: // c.a src = GL_SRC_ALPHA; break; case 1: // fog.a src = GL_SRC_ALPHA; alpha = "fog.a"; // LOGERROR("Unsupported src alpha : FOG\n"); // LOGERROR(rglCombiner2String(state)); break; case 2: // shade.a src = GL_SRC_ALPHA; alpha = "gl_Color.a"; // LOGERROR("Unsupported src alpha : SHADE\n"); // LOGERROR(rglCombiner2String(state)); break; case 3: // 0 src = GL_ZERO; break; } switch (m1a) { case 0: // c if (m1b != 0 /* c.a */) p += sprintf( p, "c.a = %s; \n", alpha); break; case 1: // f LOGERROR("Unsupported src color : FRAG\n"); LOGERROR("%s", rglCombiner2String(state)); break; case 2: // b p += sprintf( p, "c = vec4(vec3(b), %s); \n", alpha); break; case 3: // fog p += sprintf( p, "c = vec4(vec3(fog), %s); \n", alpha); break; } switch (m2b) { case 0: switch (m1b) { case 3: dst = GL_ONE; break; default: dst = GL_ONE_MINUS_SRC_ALPHA; break; } break; case 1: dst = GL_DST_ALPHA; break; case 2: dst = GL_ONE; break; case 3: dst = GL_ZERO; break; } c->srcBlend = src; c->dstBlend = dst; } else { LOGERROR("Unsuported blender :\n"); LOGERROR("%s", rglCombiner2String(state)); } } else #endif { sprintf(_1ma, "(1.0 - %s)", bA[0][m1b]); p += sprintf(p, blender, bA[0][m1b], bRGB[m1a], bA[1][m2b], bRGB[m2a]); } } else { #ifdef RGL_EXACT_BLEND p += sprintf(p, noblender ); #endif } p += sprintf( p, "%s \n" "} \n" ,write ); rglAssert(p < src+sizeof(src)); c->shader = rglCreateShader( "void main() \n" "{ \n" " gl_Position = ftransform(); \n" " gl_FrontColor = gl_Color; \n" " gl_BackColor = gl_FrontColor; \n" " gl_TexCoord[0] = gl_MultiTexCoord0; \n" #ifdef RGL_EXACT_BLEND " gl_TexCoord[1] = gl_MultiTexCoord1; \n" #endif " gl_TexCoord[2] = gl_MultiTexCoord2; \n" "} \n" , src); #ifdef RDP_DEBUG chunk.shader = c->shader; #endif rglUseShader(c->shader); rglAssert(glGetError() == GL_NO_ERROR); int location; location = glGetUniformLocationARB(c->shader->prog, "texture0"); glUniform1iARB(location, 0); #ifdef RGL_EXACT_BLEND location = glGetUniformLocationARB(c->shader->prog, "texture1"); glUniform1iARB(location, 1); #endif location = glGetUniformLocationARB(c->shader->prog, "texture2"); glUniform1iARB(location, 2); rglAssert(glGetError() == GL_NO_ERROR); ok:; #ifndef RGL_EXACT_BLEND if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_DEPTH || (c->srcBlend == GL_ONE && c->dstBlend == GL_ZERO)) glDisable(GL_BLEND); else { glEnable(GL_BLEND); if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_RGBA) glBlendFuncSeparate(c->srcBlend, c->dstBlend, GL_ZERO, GL_ONE); else glBlendFunc(c->srcBlend, c->dstBlend); } #endif }
static void _cairo_gl_set_operator (cairo_gl_context_t *ctx, cairo_operator_t op, cairo_bool_t component_alpha) { struct { GLenum src; GLenum dst; } blend_factors[] = { { GL_ZERO, GL_ZERO }, /* Clear */ { GL_ONE, GL_ZERO }, /* Source */ { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */ { GL_DST_ALPHA, GL_ZERO }, /* In */ { GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */ { GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */ { GL_ZERO, GL_ONE }, /* Dest */ { GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */ { GL_ZERO, GL_SRC_ALPHA }, /* DestIn */ { GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */ { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */ { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */ { GL_ONE, GL_ONE }, /* Add */ }; GLenum src_factor, dst_factor; assert (op < ARRAY_LENGTH (blend_factors)); /* different dst and component_alpha changes cause flushes elsewhere */ if (ctx->current_operator != op) _cairo_gl_composite_flush (ctx); ctx->current_operator = op; src_factor = blend_factors[op].src; dst_factor = blend_factors[op].dst; /* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA * due to texture filtering of GL_CLAMP_TO_BORDER. So fix those * bits in that case. */ if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) { if (src_factor == GL_ONE_MINUS_DST_ALPHA) src_factor = GL_ZERO; if (src_factor == GL_DST_ALPHA) src_factor = GL_ONE; } if (component_alpha) { if (dst_factor == GL_ONE_MINUS_SRC_ALPHA) dst_factor = GL_ONE_MINUS_SRC_COLOR; if (dst_factor == GL_SRC_ALPHA) dst_factor = GL_SRC_COLOR; } if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) { glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor); } else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) { glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE); } else { glBlendFunc (src_factor, dst_factor); } }
int Init(int windowWidth, int windowHeight) { // TODO: Init graphics engine GLenum err = 0; err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } //glClearColor(100.0f / 255.0f, 149.0f / 255.0f, 237.0f / 255.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //glClearDepth(1.0f); // assign callback functions glDebugMessageCallbackARB(glErrorCallback, NULL); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } glEnable(GL_DEPTH_TEST); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } glDepthFunc(GL_LESS); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } glEnable(GL_CULL_FACE); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); glCullFace(GL_BACK); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } glFrontFace(GL_CCW); err = glGetError(); if( err ) { LOG_ERROR << "Got GL error:" << err << std::endl; err = 0; } //Initialize RenderCore Renderer().Initialize(windowWidth, windowHeight); return GFX_SUCCESS; }
void GLGSRender::ExecCMD() { if(!LoadProgram()) { ConLog.Error("LoadProgram failed."); Emu.Pause(); return; } if(!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) { ConLog.Warning("New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); last_width = RSXThread::m_width; last_height = RSXThread::m_height; last_depth_format = m_surface_depth_format; m_fbo.Create(); checkForGlError("m_fbo.Create"); m_fbo.Bind(); m_rbo.Create(4 + 1); checkForGlError("m_rbo.Create"); for(int i=0; i<4; ++i) { m_rbo.Bind(i); m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); } m_rbo.Bind(4); switch(m_surface_depth_format) { case 1: m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); break; case 2: m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); break; default: ConLog.Error("Bad depth format! (%d)", m_surface_depth_format); assert(0); break; } for(int i=0; i<4; ++i) { m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); checkForGlError(wxString::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); } m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); if(m_surface_depth_format == 2) { m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); } } if(!m_set_surface_clip_horizontal) { m_surface_clip_x = 0; m_surface_clip_w = RSXThread::m_width; } if(!m_set_surface_clip_vertical) { m_surface_clip_y = 0; m_surface_clip_h = RSXThread::m_height; } m_fbo.Bind(); if(Ini.GSDumpDepthBuffer.GetValue()) WriteDepthBuffer(); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch(m_surface_colour_target) { case 0x0: break; case 0x1: glDrawBuffer(draw_buffers[0]); break; case 0x2: glDrawBuffer(draw_buffers[1]); break; case 0x13: glDrawBuffers(2, draw_buffers); break; case 0x17: glDrawBuffers(3, draw_buffers); break; case 0x1f: glDrawBuffers(4, draw_buffers); break; default: ConLog.Error("Bad surface colour target: %d", m_surface_colour_target); break; } if(m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); checkForGlError("glColorMask"); } if(m_set_viewport_horizontal && m_set_viewport_vertical) { glViewport(m_viewport_x, RSXThread::m_height-m_viewport_y-m_viewport_h, m_viewport_w, m_viewport_h); checkForGlError("glViewport"); } if(m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(m_scissor_x, RSXThread::m_height-m_scissor_y-m_scissor_h, m_scissor_w, m_scissor_h); checkForGlError("glScissor"); } if(m_clear_surface_mask) { GLbitfield f = 0; if (m_clear_surface_mask & 0x1) { glClearDepth(m_clear_surface_z / (float)0xffffff); f |= GL_DEPTH_BUFFER_BIT; } if (m_clear_surface_mask & 0x2) { glClearStencil(m_clear_surface_s); f |= GL_STENCIL_BUFFER_BIT; } if (m_clear_surface_mask & 0xF0) { glClearColor( m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); f |= GL_COLOR_BUFFER_BIT; } glClear(f); } if(m_set_front_polygon_mode) { glPolygonMode(GL_FRONT, m_front_polygon_mode); checkForGlError("glPolygonMode"); } Enable(m_depth_test_enable, GL_DEPTH_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); Enable(m_set_blend, GL_BLEND); Enable(m_set_logic_op, GL_LOGIC_OP); Enable(m_set_cull_face_enable, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); //Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); //Requires OpenGL 3.1+ if(m_set_clip_plane) { Enable(m_clip_plane_0, GL_CLIP_PLANE0); Enable(m_clip_plane_1, GL_CLIP_PLANE1); Enable(m_clip_plane_2, GL_CLIP_PLANE2); Enable(m_clip_plane_3, GL_CLIP_PLANE3); Enable(m_clip_plane_4, GL_CLIP_PLANE4); Enable(m_clip_plane_5, GL_CLIP_PLANE5); checkForGlError("m_set_clip_plane"); } checkForGlError("glEnable"); if(m_set_two_sided_stencil_test_enable) { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOpSeparate"); } if(m_set_stencil_mask) { glStencilMaskSeparate(GL_FRONT, m_stencil_mask); checkForGlError("glStencilMaskSeparate"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFuncSeparate"); } if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) { glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); checkForGlError("glStencilOpSeparate(GL_BACK)"); } if(m_set_back_stencil_mask) { glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); checkForGlError("glStencilMaskSeparate(GL_BACK)"); } if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) { glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); checkForGlError("glStencilFuncSeparate(GL_BACK)"); } } else { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOp"); } if(m_set_stencil_mask) { glStencilMask(m_stencil_mask); checkForGlError("glStencilMask"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFunc"); } } if(m_set_shade_mode) { glShadeModel(m_shade_mode); checkForGlError("glShadeModel"); } if(m_set_depth_mask) { glDepthMask(m_depth_mask); checkForGlError("glDepthMask"); } if(m_set_depth_func) { glDepthFunc(m_depth_func); //ConLog.Warning("glDepthFunc(0x%x)", m_depth_func); checkForGlError("glDepthFunc"); } if(m_set_depth_bounds) { //ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); glDepthBounds(m_depth_bounds_min, m_depth_bounds_max); checkForGlError("glDepthBounds"); } if(m_set_clip) { //ConLog.Warning("glDepthRangef(%f, %f)", m_clip_min, m_clip_max); glDepthRangef(m_clip_min, m_clip_max); checkForGlError("glDepthRangef"); } if(m_set_line_width) { glLineWidth(m_line_width / 255.f); checkForGlError("glLineWidth"); } if(m_set_blend_equation) { glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); checkForGlError("glBlendEquationSeparate"); } if(m_set_blend_sfactor && m_set_blend_dfactor) { glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); checkForGlError("glBlendFuncSeparate"); } if(m_set_blend_color) { glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); checkForGlError("glBlendColor"); } if(m_set_cull_face) { glCullFace(m_cull_face); checkForGlError("glCullFace"); } if(m_set_alpha_func && m_set_alpha_ref) { glAlphaFunc(m_alpha_func, m_alpha_ref); checkForGlError("glAlphaFunc"); } if(m_set_fog_mode) { glFogi(GL_FOG_MODE, m_fog_mode); checkForGlError("glFogi(GL_FOG_MODE)"); } if(m_set_fog_params) { glFogf(GL_FOG_START, m_fog_param0); checkForGlError("glFogf(GL_FOG_START)"); glFogf(GL_FOG_END, m_fog_param1); checkForGlError("glFogf(GL_FOG_END)"); } if(m_set_restart_index) { ConLog.Warning("m_set_restart_index requires glPrimitiveRestartIndex()"); //glPrimitiveRestartIndex(m_restart_index); //Requires OpenGL 3.1+ //checkForGlError("glPrimitiveRestartIndex"); } if(m_indexed_array.m_count && m_draw_array_count) { ConLog.Warning("m_indexed_array.m_count && draw_array_count"); } for(u32 i=0; i<m_textures_count; ++i) { if(!m_textures[i].IsEnabled()) continue; glActiveTexture(GL_TEXTURE0 + i); checkForGlError("glActiveTexture"); m_gl_textures[i].Create(); m_gl_textures[i].Bind(); checkForGlError(wxString::Format("m_gl_textures[%d].Bind", i)); m_program.SetTex(i); m_gl_textures[i].Init(m_textures[i]); checkForGlError(wxString::Format("m_gl_textures[%d].Init", i)); } m_vao.Bind(); if(m_indexed_array.m_count) { LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); } EnableVertexData(m_indexed_array.m_count ? true : false); InitVertexData(); InitFragmentData(); if(m_indexed_array.m_count) { switch(m_indexed_array.m_type) { case 0: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); checkForGlError("glDrawElements #4"); break; case 1: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); checkForGlError("glDrawElements #2"); break; default: ConLog.Error("Bad indexed array type (%d)", m_indexed_array.m_type); break; } DisableVertexData(); m_indexed_array.Reset(); } if(m_draw_array_count) { //ConLog.Warning("glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count); glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count); checkForGlError("glDrawArrays"); DisableVertexData(); } if(Ini.GSDumpColorBuffers.GetValue()) WriteBuffers(); }
void OpenGL3StateChangeWrapper::blendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { bool callIsRedundant = d_blendFuncSeperateParams.equal(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); if(!callIsRedundant) glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); }
void TransFuncOverlay::process() { #ifndef VRN_MODULE_FONTRENDERING LWARNING("Empty output, enable module 'fontrendering'."); return; #endif tgtAssert(outport_.isReady(), "Outport not ready"); tgtAssert(imageInport_.isReady(), "Inport not ready"); tgtAssert(program_ && copyShader_, "Shader missing"); if(dynamic_cast<TransFunc1DKeys*>(transferFunc_.get()) == 0){ LWARNING("No transfer function of class TransFuncIntensity is given!!!"); return; } TransFunc1DKeys* tfi = dynamic_cast<TransFunc1DKeys*>(transferFunc_.get()); //render overlay privatePort_.activateTarget(); glPushAttrib(GL_ALL_ATTRIB_BITS); glClearColor(fontColor_.get().r,fontColor_.get().g,fontColor_.get().b,0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //render the transfer function texture const tgt::Texture* tfTex = 0; if(renderPreIntegrationTable_.get()) tfTex = tfi->getPreIntegrationTable(1.0f / (41.0f * 2.0f))->getTexture(); else tfTex = tfi->getTexture(); tgtAssert(tfTex, "No transfer function texture"); tfTex->bind(); glColor4f(1.f,1.f,1.f,1.f); glDisable(GL_DEPTH_TEST); glBegin(GL_QUADS); glVertex2f(-0.8f,-0.9f); glVertex2f(-0.5f,-0.9f); glVertex2f(-0.5f,0.7f); glVertex2f(-0.8f,0.7f); glEnd(); glColor4f(0.8f,0.8f,0.8f,1.f); glBegin(GL_QUADS); glVertex2f(-0.8f,-0.9f); glVertex2f(-0.65f,-0.9f); glVertex2f(-0.65f,-0.58f); glVertex2f(-0.8f,-0.58f); glVertex2f(-0.65f,-0.58f); glVertex2f(-0.5f,-0.58f); glVertex2f(-0.5f,-0.26f); glVertex2f(-0.65f,-0.26f); glVertex2f(-0.8f,-0.26f); glVertex2f(-0.65f,-0.26f); glVertex2f(-0.65f,0.06f); glVertex2f(-0.8f,0.06f); glVertex2f(-0.65f,0.06f); glVertex2f(-0.5f,0.06f); glVertex2f(-0.5f,0.38f); glVertex2f(-0.65f,0.38f); glVertex2f(-0.8f,0.38f); glVertex2f(-0.65f,0.38f); glVertex2f(-0.65f,0.7f); glVertex2f(-0.8f,0.7f); glEnd(); glColor4f(1.f,1.f,1.f,1.f); if(renderPreIntegrationTable_.get()) glEnable(GL_TEXTURE_2D); else glEnable(GL_TEXTURE_1D); glEnable(GL_BLEND); glBlendColor(0.0f,0.0f,0.0f,overlayOpacity_.get()); glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ZERO,GL_CONSTANT_ALPHA); glBegin(GL_QUADS); if(renderPreIntegrationTable_.get()) { glTexCoord2f(0.f, 0.f); glVertex2f(-0.8f,-0.9f); glTexCoord2f(1.f, 0.f); glVertex2f(-0.5f,-0.9f); glTexCoord2f(1.f, 1.f); glVertex2f(-0.5f,0.7f); glTexCoord2f(0.f, 1.f); glVertex2f(-0.8f,0.7f); } else { glTexCoord1f(0.f); glVertex2f(-0.8f,-0.9f); glTexCoord1f(0.f); glVertex2f(-0.5f,-0.9f); glTexCoord1f(1.f); glVertex2f(-0.5f,0.7f); glTexCoord1f(1.f); glVertex2f(-0.8f,0.7f); } glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_1D); glEnable(GL_DEPTH_TEST); //render fonts glPushMatrix(); glTranslatef(-1.f,-1.f,0.f); float scaleFactorX = 2.0f / (float)privatePort_.getSize().x; float scaleFactorY = 2.0f / (float)privatePort_.getSize().y; glScalef(scaleFactorX, scaleFactorY, 1.f); glColor4f(fontColor_.get().r,fontColor_.get().g,fontColor_.get().b,fontColor_.get().a*overlayOpacity_.get()); fontProp_.get()->setSize(privatePort_.getSize().y/12); fontProp_.get()->setVerticalTextAlignment(tgt::Font::Middle); fontProp_.get()->setFontType(tgt::Font::BitmapFont); fontProp_.get()->setLineWidth(privatePort_.getSize().x*0.35f); fontProp_.get()->setTextAlignment(tgt::Font::Center); fontProp_.get()->render(tgt::vec3(0,privatePort_.getSize().y*0.925f,0), tfUnit_.get()); fontProp_.get()->setLineWidth((float)privatePort_.getSize().x); fontProp_.get()->setTextAlignment(tgt::Font::Left); std::stringstream strstr; strstr << tfi->getDomain(0).x * scalingProp_.get(); fontProp_.get()->render(tgt::vec3(privatePort_.getSize().x*0.3f,privatePort_.getSize().y*0.05f,0), strstr.str()); strstr.clear(); strstr.str(""); strstr << (tfi->getDomain(0).x+((tfi->getDomain(0).y-tfi->getDomain(0).x)/2)) * scalingProp_.get(); fontProp_.get()->render(tgt::vec3(privatePort_.getSize().x*0.3f,privatePort_.getSize().y*0.45f,0), strstr.str()); strstr.clear(); strstr.str(""); strstr << tfi->getDomain(0).y * scalingProp_.get(); fontProp_.get()->render(tgt::vec3(privatePort_.getSize().x*0.3f,privatePort_.getSize().y*0.85f,0), strstr.str()); glPopMatrix(); glPopAttrib(); // render border around overlay if (renderBorder_.get()) { glPushAttrib(GL_ALL_ATTRIB_BITS); glColor4f(borderColor_.get().r,borderColor_.get().g,borderColor_.get().b,borderColor_.get().a*overlayOpacity_.get()); glLineWidth(borderWidth_.get()); glDepthFunc(GL_ALWAYS); glBegin(GL_LINE_STRIP); glVertex2f(-0.8f,-0.9f); glVertex2f(-0.5f,-0.9f); glVertex2f(-0.5f,0.7f); glVertex2f(-0.8f,0.7f); glVertex2f(-0.8f,-0.9f); glEnd(); glPopAttrib(); } LGL_ERROR; privatePort_.deactivateTarget(); //same code as in ImageOverlay // | // v outport_.activateTarget(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // bind input image to tex unit TextureUnit imageUnit, imageUnitDepth; imageInport_.bindTextures(imageUnit.getEnum(), imageUnitDepth.getEnum()); // 1. copy input image to outport copyShader_->activate(); setGlobalShaderParameters(copyShader_); imageInport_.setTextureParameters(copyShader_, "texParams_"); copyShader_->setUniform("colorTex_", imageUnit.getUnitNumber()); copyShader_->setUniform("depthTex_", imageUnitDepth.getUnitNumber()); renderQuad(); copyShader_->deactivate(); LGL_ERROR; // 2. render overlay over copied input image (using compositor shader) // check, if overlay dims are greater zero bool dimensionsValid = ( (usePixelCoordinates_.getValue() && tgt::hand(tgt::greaterThan(overlayDimensions_.get(), tgt::ivec2(0)))) || (!usePixelCoordinates_.getValue() && tgt::hand(tgt::greaterThan(overlayDimensionsRelative_.get(), tgt::vec2(0.f)))) ); if (renderOverlay_.get() && /*overlayInport_.isReady() &&*/ dimensionsValid) { // bind overlay to tex unit TextureUnit overlayUnit; tgt::Texture* overlayTex = privatePort_.getColorTexture();//overlayInport_.getColorTexture(); tgtAssert(overlayTex, "No overlay texture"); overlayUnit.activate(); overlayTex->bind(); program_->activate(); setGlobalShaderParameters(program_); // image texture parameters imageInport_.setTextureParameters(program_, "textureParameters0_"); program_->setUniform("colorTex0_", imageUnit.getUnitNumber()); program_->setUniform("depthTex0_", imageUnitDepth.getUnitNumber()); program_->setUniform("colorTex1_", overlayUnit.getUnitNumber()); //program_->setUniform("weightingFactor_", 1.f-overlayOpacity_.get()); // determine overlay dimensions and bottom-left in float pixel coords tgt::vec2 outportDim = tgt::vec2(outport_.getSize()); tgt::vec2 overlayDim, overlayBL; if (usePixelCoordinates_.getValue()) { overlayDim = tgt::vec2(overlayDimensions_.get()); overlayBL = tgt::vec2(overlayBottomLeft_.get()); } else { overlayDim = overlayDimensionsRelative_.get() * outportDim; overlayBL = overlayBottomLeftRelative_.get() * outportDim; } // overlay texture matrix mapping from normalized frag coords (outport) to overlay tex coords tgt::mat4 overlayTexCoordMatrix = tgt::mat4::identity; overlayTexCoordMatrix *= tgt::mat4::createScale(tgt::vec3(outportDim / overlayDim, 0.f)); overlayTexCoordMatrix *= tgt::mat4::createTranslation(-tgt::vec3(overlayBL / outportDim, 1.f)); // overlay texture parameters bool oldIgnoreError = program_->getIgnoreUniformLocationError(); program_->setIgnoreUniformLocationError(true); program_->setUniform("textureParameters1_.dimensions_", overlayDim); program_->setUniform("textureParameters1_.dimensionsRCP_", tgt::vec2(1.f) / overlayDim); program_->setUniform("textureParameters1_.matrix_", overlayTexCoordMatrix); program_->setIgnoreUniformLocationError(oldIgnoreError); LGL_ERROR; // render overlay at specified position and size tgt::vec2 bl = 2.f*overlayBL / outportDim - 1.f; tgt::vec2 dim = 2.f*overlayDim / outportDim; glDepthFunc(GL_ALWAYS); glBegin(GL_QUADS); glVertex2f(bl.x, bl.y); glVertex2f(bl.x + dim.x, bl.y); glVertex2f(bl.x + dim.x, bl.y + dim.y); glVertex2f(bl.x, bl.y + dim.y); glEnd(); glDepthFunc(GL_LESS); program_->deactivate(); LGL_ERROR; } outport_.deactivateTarget(); TextureUnit::setZeroUnit(); LGL_ERROR; }
void window::render() { if (graphics::is_debug_supported()) { glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, get_title().c_str()); } auto&& old_window = SDL_GL_GetCurrentWindow(); auto&& old_context = SDL_GL_GetCurrentContext(); // Need to flush here before the context change for macOS OpenGL to // finish rendering the framebuffers (on Intel at least)! glFlush(); SDL_GL_MakeCurrent(handle.get(), get_graphics_context().handle.get()); // Draw each viewport. Layer them on top of each other and use blending // for transparency. Disable depth mask so that transparent views don't // block each other from rendering. // The viewport contains colour already multiplied with the alpha // channel, so instead of doing that again with GL_SRC_ALPHA, it is // drawn with GL_ONE. The destination colour is attenuated normally with // GL_ONE_MINUS_SRC_ALPHA. GLboolean old_blend, old_depth_mask; GLint old_source_rgb, old_source_alpha, old_destination_rgb, old_destination_alpha; glGetBooleanv(GL_BLEND, &old_blend); glGetBooleanv(GL_DEPTH_WRITEMASK, &old_depth_mask); glGetIntegerv(GL_BLEND_SRC_RGB, &old_source_rgb); glGetIntegerv(GL_BLEND_SRC_ALPHA, &old_source_alpha); glGetIntegerv(GL_BLEND_DST_RGB, &old_destination_rgb); glGetIntegerv(GL_BLEND_DST_ALPHA, &old_destination_alpha); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, get_backbuffer_width(), get_backbuffer_height()); glClearColor(get_background_color().get_r(), get_background_color().get_g(), get_background_color().get_b(), get_background_color().get_a()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (auto&& iterator = graphics::viewport::viewports.rbegin(); iterator != graphics::viewport::viewports.rend(); iterator++) { auto&& viewport = **iterator; if (viewport.get_window() != this) { continue; } viewport.draw(); } glBlendFuncSeparate(old_source_rgb, old_destination_rgb, old_source_alpha, old_destination_alpha); if (not old_blend) { glDisable(GL_BLEND); } if (old_depth_mask) { glDepthMask(GL_TRUE); } SDL_GL_SwapWindow(handle.get()); SDL_GL_MakeCurrent(old_window, old_context); if (graphics::is_debug_supported()) { glPopDebugGroup(); } }
void MapRenderer::draw(GameWorld* world, const MapInfo& mi) { renderer->pushDebugGroup("Map"); renderer->useProgram(rectProg); // World out the number of units per tile glm::vec2 worldSize(GAME_MAP_SIZE); const int mapBlockLine = 8; glm::vec2 tileSize = worldSize / (float)mapBlockLine; // Determine the scale to show the right number of world units on the screen float worldScale = mi.screenSize / mi.worldSize; auto proj = renderer->get2DProjection(); glm::mat4 view, model; renderer->setUniform(rectProg, "proj", proj); renderer->setUniform(rectProg, "model", glm::mat4()); renderer->setUniform(rectProg, "colour", glm::vec4(0.f, 0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(mi.screenPosition, 0.f)); if (mi.clipToSize) { glBindVertexArray( circle.getVAOName() ); glBindTexture(GL_TEXTURE_2D, 0); glm::mat4 circleView = glm::scale(view, glm::vec3(mi.screenSize)); renderer->setUniform(rectProg, "view", circleView); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); glColorMask(0x00, 0x00, 0x00, 0x00); glDrawArrays(GL_TRIANGLE_FAN, 0, 182); glColorMask(0xFF, 0xFF, 0xFF, 0xFF); glStencilFunc(GL_EQUAL, 1, 0xFF); } view = glm::scale(view, glm::vec3(worldScale)); view = glm::rotate(view, mi.rotation, glm::vec3(0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(glm::vec2(-1.f, 1.f) * mi.worldCenter, 0.f)); renderer->setUniform(rectProg, "view", view); glBindVertexArray( rect.getVAOName() ); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); // radar00 = -x, +y // incrementing in X, then Y int initX = -(mapBlockLine/2); int initY = -(mapBlockLine/2); for( int m = 0; m < MAP_BLOCK_SIZE; ++m ) { std::string num = (m < 10 ? "0" : ""); std::string name = "radar" + num + std::to_string(m); auto texture = world->data->textures[{name,""}]; glBindTexture(GL_TEXTURE_2D, texture->getName()); int mX = initX + (m % mapBlockLine); int mY = initY + (m / mapBlockLine); auto tc = glm::vec2(mX, mY) * tileSize + glm::vec2(tileSize/2.f); glm::mat4 tilemodel = model; tilemodel = glm::translate( tilemodel, glm::vec3( tc, 0.f ) ); tilemodel = glm::scale( tilemodel, glm::vec3( tileSize, 1.f ) ); renderer->setUniform(rectProg, "model", tilemodel); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } // From here on out we will work in screenspace renderer->setUniform(rectProg, "view", glm::mat4()); if (mi.clipToSize) { glDisable(GL_STENCIL_TEST); // We only need the outer ring if we're clipping. glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO); TextureData::Handle radarDisc = data->findTexture("radardisc"); glm::mat4 model; model = glm::translate(model, glm::vec3(mi.screenPosition, 0.0f)); model = glm::scale(model, glm::vec3(mi.screenSize*1.07)); renderer->setUniform(rectProg, "model", model); glBindTexture(GL_TEXTURE_2D, radarDisc->getName()); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); } for(auto& blip : world->state->radarBlips) { glm::vec2 blippos( blip.second.coord ); if( blip.second.target > 0 ) { GameObject* object = world->getBlipTarget(blip.second); if( object ) { blippos = glm::vec2( object->getPosition() ); } } drawBlip(blippos, view, mi, blip.second.texture); } // Draw the player blip auto player = world->pedestrianPool.find(world->state->playerObject); if( player ) { glm::vec2 plyblip(player->getPosition()); float hdg = glm::roll(player->getRotation()); drawBlip(plyblip, view, mi, "radar_centre", mi.rotation - hdg); } drawBlip(mi.worldCenter + glm::vec2(0.f, mi.worldSize), view, mi, "radar_north", 0.f, 24.f); glBindVertexArray( 0 ); glBindTexture(GL_TEXTURE_2D, 0); glUseProgram(0); /// @TODO migrate to using the renderer renderer->invalidate(); renderer->popDebugGroup(); }
void OpenGLState::Apply() const { // Culling if (cull.enabled != cur_state.cull.enabled) { if (cull.enabled) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } } if (cull.mode != cur_state.cull.mode) { glCullFace(cull.mode); } if (cull.front_face != cur_state.cull.front_face) { glFrontFace(cull.front_face); } // Depth test if (depth.test_enabled != cur_state.depth.test_enabled) { if (depth.test_enabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } if (depth.test_func != cur_state.depth.test_func) { glDepthFunc(depth.test_func); } // Depth mask if (depth.write_mask != cur_state.depth.write_mask) { glDepthMask(depth.write_mask); } // Color mask if (color_mask.red_enabled != cur_state.color_mask.red_enabled || color_mask.green_enabled != cur_state.color_mask.green_enabled || color_mask.blue_enabled != cur_state.color_mask.blue_enabled || color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); } // Stencil test if (stencil.test_enabled != cur_state.stencil.test_enabled) { if (stencil.test_enabled) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } } if (stencil.test_func != cur_state.stencil.test_func || stencil.test_ref != cur_state.stencil.test_ref || stencil.test_mask != cur_state.stencil.test_mask) { glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); } if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail || stencil.action_depth_pass != cur_state.stencil.action_depth_pass || stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); } // Stencil mask if (stencil.write_mask != cur_state.stencil.write_mask) { glStencilMask(stencil.write_mask); } // Blending if (blend.enabled != cur_state.blend.enabled) { if (blend.enabled) { glEnable(GL_BLEND); glDisable(GL_COLOR_LOGIC_OP); } else { glDisable(GL_BLEND); glEnable(GL_COLOR_LOGIC_OP); } } if (blend.color.red != cur_state.blend.color.red || blend.color.green != cur_state.blend.color.green || blend.color.blue != cur_state.blend.color.blue || blend.color.alpha != cur_state.blend.color.alpha) { glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); } if (blend.src_rgb_func != cur_state.blend.src_rgb_func || blend.dst_rgb_func != cur_state.blend.dst_rgb_func || blend.src_a_func != cur_state.blend.src_a_func || blend.dst_a_func != cur_state.blend.dst_a_func) { glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); } if (blend.rgb_equation != cur_state.blend.rgb_equation || blend.a_equation != cur_state.blend.a_equation) { glBlendEquationSeparate(blend.rgb_equation, blend.a_equation); } if (logic_op != cur_state.logic_op) { glLogicOp(logic_op); } // Textures for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { glActiveTexture(TextureUnits::PicaTexture(i).Enum()); glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); } if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { glBindSampler(i, texture_units[i].sampler); } } if (texture_cube_unit.texture_cube != cur_state.texture_cube_unit.texture_cube) { glActiveTexture(TextureUnits::TextureCube.Enum()); glBindTexture(GL_TEXTURE_CUBE_MAP, texture_cube_unit.texture_cube); } if (texture_cube_unit.sampler != cur_state.texture_cube_unit.sampler) { glBindSampler(TextureUnits::TextureCube.id, texture_cube_unit.sampler); } // Texture buffer LUTs if (texture_buffer_lut_rg.texture_buffer != cur_state.texture_buffer_lut_rg.texture_buffer) { glActiveTexture(TextureUnits::TextureBufferLUT_RG.Enum()); glBindTexture(GL_TEXTURE_BUFFER, texture_buffer_lut_rg.texture_buffer); } // Texture buffer LUTs if (texture_buffer_lut_rgba.texture_buffer != cur_state.texture_buffer_lut_rgba.texture_buffer) { glActiveTexture(TextureUnits::TextureBufferLUT_RGBA.Enum()); glBindTexture(GL_TEXTURE_BUFFER, texture_buffer_lut_rgba.texture_buffer); } // Shadow Images if (image_shadow_buffer != cur_state.image_shadow_buffer) { glBindImageTexture(ImageUnits::ShadowBuffer, image_shadow_buffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); } if (image_shadow_texture_px != cur_state.image_shadow_texture_px) { glBindImageTexture(ImageUnits::ShadowTexturePX, image_shadow_texture_px, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } if (image_shadow_texture_nx != cur_state.image_shadow_texture_nx) { glBindImageTexture(ImageUnits::ShadowTextureNX, image_shadow_texture_nx, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } if (image_shadow_texture_py != cur_state.image_shadow_texture_py) { glBindImageTexture(ImageUnits::ShadowTexturePY, image_shadow_texture_py, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } if (image_shadow_texture_ny != cur_state.image_shadow_texture_ny) { glBindImageTexture(ImageUnits::ShadowTextureNY, image_shadow_texture_ny, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } if (image_shadow_texture_pz != cur_state.image_shadow_texture_pz) { glBindImageTexture(ImageUnits::ShadowTexturePZ, image_shadow_texture_pz, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } if (image_shadow_texture_nz != cur_state.image_shadow_texture_nz) { glBindImageTexture(ImageUnits::ShadowTextureNZ, image_shadow_texture_nz, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); } // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); } if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer); } // Vertex array if (draw.vertex_array != cur_state.draw.vertex_array) { glBindVertexArray(draw.vertex_array); } // Vertex buffer if (draw.vertex_buffer != cur_state.draw.vertex_buffer) { glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); } // Uniform buffer if (draw.uniform_buffer != cur_state.draw.uniform_buffer) { glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer); } // Shader program if (draw.shader_program != cur_state.draw.shader_program) { glUseProgram(draw.shader_program); } // Program pipeline if (draw.program_pipeline != cur_state.draw.program_pipeline) { glBindProgramPipeline(draw.program_pipeline); } // Scissor test if (scissor.enabled != cur_state.scissor.enabled) { if (scissor.enabled) { glEnable(GL_SCISSOR_TEST); } else { glDisable(GL_SCISSOR_TEST); } } if (scissor.x != cur_state.scissor.x || scissor.y != cur_state.scissor.y || scissor.width != cur_state.scissor.width || scissor.height != cur_state.scissor.height) { glScissor(scissor.x, scissor.y, scissor.width, scissor.height); } if (viewport.x != cur_state.viewport.x || viewport.y != cur_state.viewport.y || viewport.width != cur_state.viewport.width || viewport.height != cur_state.viewport.height) { glViewport(viewport.x, viewport.y, viewport.width, viewport.height); } // Clip distance for (size_t i = 0; i < clip_distance.size(); ++i) { if (clip_distance[i] != cur_state.clip_distance[i]) { if (clip_distance[i]) { glEnable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i)); } else { glDisable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i)); } } } cur_state = *this; }
uintptr_t processFn(struct fnargs* args, char* parg) { uintptr_t ret = 0; switch (args->fn) { case glfnUNDEFINED: abort(); // bad glfn break; case glfnActiveTexture: glActiveTexture((GLenum)args->a0); break; case glfnAttachShader: glAttachShader((GLint)args->a0, (GLint)args->a1); break; case glfnBindAttribLocation: glBindAttribLocation((GLint)args->a0, (GLint)args->a1, (GLchar*)args->a2); break; case glfnBindBuffer: glBindBuffer((GLenum)args->a0, (GLuint)args->a1); break; case glfnBindFramebuffer: glBindFramebuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindRenderbuffer: glBindRenderbuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindTexture: glBindTexture((GLenum)args->a0, (GLint)args->a1); break; case glfnBlendColor: glBlendColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnBlendEquation: glBlendEquation((GLenum)args->a0); break; case glfnBlendEquationSeparate: glBlendEquationSeparate((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFunc: glBlendFunc((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFuncSeparate: glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnBufferData: glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2); break; case glfnBufferSubData: glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)parg); break; case glfnCheckFramebufferStatus: ret = glCheckFramebufferStatus((GLenum)args->a0); break; case glfnClear: glClear((GLenum)args->a0); break; case glfnClearColor: glClearColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnClearDepthf: glClearDepthf(*(GLfloat*)&args->a0); break; case glfnClearStencil: glClearStencil((GLint)args->a0); break; case glfnColorMask: glColorMask((GLboolean)args->a0, (GLboolean)args->a1, (GLboolean)args->a2, (GLboolean)args->a3); break; case glfnCompileShader: glCompileShader((GLint)args->a0); break; case glfnCompressedTexImage2D: glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)parg); break; case glfnCompressedTexSubImage2D: glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)parg); break; case glfnCopyTexImage2D: glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCopyTexSubImage2D: glCopyTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCreateProgram: ret = glCreateProgram(); break; case glfnCreateShader: ret = glCreateShader((GLenum)args->a0); break; case glfnCullFace: glCullFace((GLenum)args->a0); break; case glfnDeleteBuffer: glDeleteBuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteFramebuffer: glDeleteFramebuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteProgram: glDeleteProgram((GLint)args->a0); break; case glfnDeleteRenderbuffer: glDeleteRenderbuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteShader: glDeleteShader((GLint)args->a0); break; case glfnDeleteTexture: glDeleteTextures(1, (const GLuint*)(&args->a0)); break; case glfnDepthFunc: glDepthFunc((GLenum)args->a0); break; case glfnDepthMask: glDepthMask((GLboolean)args->a0); break; case glfnDepthRangef: glDepthRangef(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnDetachShader: glDetachShader((GLint)args->a0, (GLint)args->a1); break; case glfnDisable: glDisable((GLenum)args->a0); break; case glfnDisableVertexAttribArray: glDisableVertexAttribArray((GLint)args->a0); break; case glfnDrawArrays: glDrawArrays((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnDrawElements: glDrawElements((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (void*)args->a3); break; case glfnEnable: glEnable((GLenum)args->a0); break; case glfnEnableVertexAttribArray: glEnableVertexAttribArray((GLint)args->a0); break; case glfnFinish: glFinish(); break; case glfnFlush: glFlush(); break; case glfnFramebufferRenderbuffer: glFramebufferRenderbuffer((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3); break; case glfnFramebufferTexture2D: glFramebufferTexture2D((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnFrontFace: glFrontFace((GLenum)args->a0); break; case glfnGenBuffer: glGenBuffers(1, (GLuint*)&ret); break; case glfnGenFramebuffer: glGenFramebuffers(1, (GLuint*)&ret); break; case glfnGenRenderbuffer: glGenRenderbuffers(1, (GLuint*)&ret); break; case glfnGenTexture: glGenTextures(1, (GLuint*)&ret); break; case glfnGenerateMipmap: glGenerateMipmap((GLenum)args->a0); break; case glfnGetActiveAttrib: glGetActiveAttrib( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)&ret, (GLenum*)args->a3, (GLchar*)parg); break; case glfnGetActiveUniform: glGetActiveUniform( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)&ret, (GLenum*)args->a3, (GLchar*)parg); break; case glfnGetAttachedShaders: glGetAttachedShaders((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)&ret, (GLuint*)parg); break; case glfnGetAttribLocation: ret = glGetAttribLocation((GLint)args->a0, (GLchar*)args->a1); break; case glfnGetBooleanv: glGetBooleanv((GLenum)args->a0, (GLboolean*)parg); break; case glfnGetBufferParameteri: glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetFloatv: glGetFloatv((GLenum)args->a0, (GLfloat*)parg); break; case glfnGetIntegerv: glGetIntegerv((GLenum)args->a0, (GLint*)parg); break; case glfnGetError: ret = glGetError(); break; case glfnGetFramebufferAttachmentParameteriv: glGetFramebufferAttachmentParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint*)&ret); break; case glfnGetProgramiv: glGetProgramiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetProgramInfoLog: glGetProgramInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetRenderbufferParameteriv: glGetRenderbufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderiv: glGetShaderiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderInfoLog: glGetShaderInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetShaderPrecisionFormat: glGetShaderPrecisionFormat((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg, &((GLint*)parg)[2]); break; case glfnGetShaderSource: glGetShaderSource((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetString: ret = (uintptr_t)glGetString((GLenum)args->a0); break; case glfnGetTexParameterfv: glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnGetTexParameteriv: glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnGetUniformfv: glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)parg); break; case glfnGetUniformiv: glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)parg); break; case glfnGetUniformLocation: ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1); break; case glfnGetVertexAttribfv: glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnGetVertexAttribiv: glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnHint: glHint((GLenum)args->a0, (GLenum)args->a1); break; case glfnIsBuffer: ret = glIsBuffer((GLint)args->a0); break; case glfnIsEnabled: ret = glIsEnabled((GLenum)args->a0); break; case glfnIsFramebuffer: ret = glIsFramebuffer((GLint)args->a0); break; case glfnIsProgram: ret = glIsProgram((GLint)args->a0); break; case glfnIsRenderbuffer: ret = glIsRenderbuffer((GLint)args->a0); break; case glfnIsShader: ret = glIsShader((GLint)args->a0); break; case glfnIsTexture: ret = glIsTexture((GLint)args->a0); break; case glfnLineWidth: glLineWidth(*(GLfloat*)&args->a0); break; case glfnLinkProgram: glLinkProgram((GLint)args->a0); break; case glfnPixelStorei: glPixelStorei((GLenum)args->a0, (GLint)args->a1); break; case glfnPolygonOffset: glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnReadPixels: glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)parg); break; case glfnReleaseShaderCompiler: glReleaseShaderCompiler(); break; case glfnRenderbufferStorage: glRenderbufferStorage((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnSampleCoverage: glSampleCoverage(*(GLfloat*)&args->a0, (GLboolean)args->a1); break; case glfnScissor: glScissor((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnShaderSource: #if defined(os_ios) || defined(os_osx) glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar *const *)args->a2, NULL); #else glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar **)args->a2, NULL); #endif break; case glfnStencilFunc: glStencilFunc((GLenum)args->a0, (GLint)args->a1, (GLuint)args->a2); break; case glfnStencilFuncSeparate: glStencilFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLuint)args->a3); break; case glfnStencilMask: glStencilMask((GLuint)args->a0); break; case glfnStencilMaskSeparate: glStencilMaskSeparate((GLenum)args->a0, (GLuint)args->a1); break; case glfnStencilOp: glStencilOp((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2); break; case glfnStencilOpSeparate: glStencilOpSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnTexImage2D: glTexImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLsizei)args->a3, (GLsizei)args->a4, 0, // border (GLenum)args->a5, (GLenum)args->a6, (const GLvoid*)parg); break; case glfnTexSubImage2D: glTexSubImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLsizei)args->a4, (GLsizei)args->a5, (GLenum)args->a6, (GLenum)args->a7, (const GLvoid*)parg); break; case glfnTexParameterf: glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2); break; case glfnTexParameterfv: glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnTexParameteri: glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2); break; case glfnTexParameteriv: glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnUniform1f: glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnUniform1fv: glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform1i: glUniform1i((GLint)args->a0, (GLint)args->a1); break; case glfnUniform1iv: glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform2f: glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnUniform2fv: glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform2i: glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnUniform2iv: glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform3f: glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnUniform3fv: glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform3i: glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnUniform3iv: glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform4f: glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnUniform4fv: glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform4i: glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnUniform4iv: glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniformMatrix2fv: glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUniformMatrix3fv: glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUniformMatrix4fv: glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUseProgram: glUseProgram((GLint)args->a0); break; case glfnValidateProgram: glValidateProgram((GLint)args->a0); break; case glfnVertexAttrib1f: glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnVertexAttrib1fv: glVertexAttrib1fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib2f: glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnVertexAttrib2fv: glVertexAttrib2fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib3f: glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnVertexAttrib3fv: glVertexAttrib3fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib4f: glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnVertexAttrib4fv: glVertexAttrib4fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttribPointer: glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5); break; case glfnViewport: glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; } return ret; }
void GLGSRender::begin() { rsx::thread::begin(); if (!load_program()) { //no program - no drawing return; } init_buffers(); u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; bool color_mask_b = !!(color_mask & 0xff); bool color_mask_g = !!((color_mask >> 8) & 0xff); bool color_mask_r = !!((color_mask >> 16) & 0xff); bool color_mask_a = !!((color_mask >> 24) & 0xff); __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) { __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); } if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))) { __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); } __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); __glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); if (__glcheck enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST)) { //TODO: NV4097_SET_ALPHA_REF must be converted to f32 //glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF])); } if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) { u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; u16 sfactor_rgb = sfactor; u16 sfactor_a = sfactor >> 16; u16 dfactor_rgb = dfactor; u16 dfactor_a = dfactor >> 16; __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); if (m_surface.color_format == Surface_color_format::w16z16y16x16) //TODO: check another color formats { u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; u16 blend_color_r = blend_color; u16 blend_color_g = blend_color >> 16; u16 blend_color_b = blend_color2; u16 blend_color_a = blend_color2 >> 16; __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL14_nglBlendFuncSeparate(JNIEnv *env, jclass clazz, jint sfactorRGB, jint dfactorRGB, jint sfactorAlpha, jint dfactorAlpha, jlong function_pointer) { glBlendFuncSeparatePROC glBlendFuncSeparate = (glBlendFuncSeparatePROC)((intptr_t)function_pointer); glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); }
void Channel::frameAssemble( const eq::uint128_t&, const eq::Frames& frames ) { _startAssemble(); eq::PixelViewport coveredPVP; eq::ImageOps dbImages; eq::Zoom zoom( eq::Zoom::NONE ); // Make sure all frames are ready and gather some information on them for( eq::Frame* frame : frames ) { { eq::ChannelStatistics stat( eq::Statistic::CHANNEL_FRAME_WAIT_READY, this ); frame->waitReady( ); } for( eq::Image* image : frame->getImages( )) { eq::ImageOp op( frame, image ); op.offset = frame->getOffset(); const eq::Range& range = image->getContext().range; if( range == eq::Range::ALL ) // 2D frame, assemble directly eq::Compositor::assembleImage( op, this ); else { dbImages.emplace_back( op ); zoom = frame->getZoom(); coveredPVP.merge( image->getPixelViewport() + frame->getOffset()); } } } if( dbImages.empty( )) { resetAssemblyState(); return; } // calculate correct image sequence const bool dbCompose = _image.getContext().range != eq::Range::ALL; coveredPVP.intersect( getPixelViewport( )); if( dbCompose && coveredPVP.hasArea( )) { eq::ImageOp op; op.image = &_image; op.buffers = eq::Frame::BUFFER_COLOR; op.zoom = zoom; op.offset = eq::Vector2i( coveredPVP.x, coveredPVP.y ); dbImages.emplace_back( op ); } _orderImages( dbImages ); // check if current image is in proper position, read back if not if( dbCompose ) { if( _bgColor == eq::Vector3f() && dbImages.front().image == &_image) dbImages.erase( dbImages.begin( )); else if( coveredPVP.hasArea()) { eq::util::ObjectManager& glObjects = getObjectManager(); eq::PixelViewport pvp = getRegion(); pvp.intersect( coveredPVP ); // Update range eq::Range range( 1.f, 0.f ); for( const eq::ImageOp& op : dbImages ) { const eq::Range& r = op.image->getContext().range; range.start = std::min( range.start, r.start ); range.end = std::max( range.end, r.end ); } eq::RenderContext context = _image.getContext(); context.range = range; if( _image.startReadback( eq::Frame::BUFFER_COLOR, pvp, context, zoom, glObjects )) { _image.finishReadback( glewGetContext( )); } clearViewport( coveredPVP ); } } glEnable( GL_BLEND ); LBASSERT( GLEW_EXT_blend_func_separate ); glBlendFuncSeparate( GL_ONE, GL_SRC_ALPHA, GL_ZERO, GL_SRC_ALPHA ); eq::Compositor::blendImages( dbImages, this, 0 ); resetAssemblyState(); }
void OpenGLState::Apply() { // Culling if (cull.enabled != cur_state.cull.enabled) { if (cull.enabled) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } } if (cull.mode != cur_state.cull.mode) { glCullFace(cull.mode); } if (cull.front_face != cur_state.cull.front_face) { glFrontFace(cull.front_face); } // Depth test if (depth.test_enabled != cur_state.depth.test_enabled) { if (depth.test_enabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } if (depth.test_func != cur_state.depth.test_func) { glDepthFunc(depth.test_func); } // Depth mask if (depth.write_mask != cur_state.depth.write_mask) { glDepthMask(depth.write_mask); } // Color mask if (color_mask.red_enabled != cur_state.color_mask.red_enabled || color_mask.green_enabled != cur_state.color_mask.green_enabled || color_mask.blue_enabled != cur_state.color_mask.blue_enabled || color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); } // Stencil test if (stencil.test_enabled != cur_state.stencil.test_enabled) { if (stencil.test_enabled) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } } if (stencil.test_func != cur_state.stencil.test_func || stencil.test_ref != cur_state.stencil.test_ref || stencil.test_mask != cur_state.stencil.test_mask) { glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); } if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail || stencil.action_depth_pass != cur_state.stencil.action_depth_pass || stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); } // Stencil mask if (stencil.write_mask != cur_state.stencil.write_mask) { glStencilMask(stencil.write_mask); } // Blending if (blend.enabled != cur_state.blend.enabled) { if (blend.enabled) { glEnable(GL_BLEND); cur_state.logic_op = GL_COPY; glLogicOp(cur_state.logic_op); glDisable(GL_COLOR_LOGIC_OP); } else { glDisable(GL_BLEND); glEnable(GL_COLOR_LOGIC_OP); } } if (blend.color.red != cur_state.blend.color.red || blend.color.green != cur_state.blend.color.green || blend.color.blue != cur_state.blend.color.blue || blend.color.alpha != cur_state.blend.color.alpha) { glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); } if (blend.src_rgb_func != cur_state.blend.src_rgb_func || blend.dst_rgb_func != cur_state.blend.dst_rgb_func || blend.src_a_func != cur_state.blend.src_a_func || blend.dst_a_func != cur_state.blend.dst_a_func) { glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); } if (logic_op != cur_state.logic_op) { glLogicOp(logic_op); } // Textures for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); } if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { glBindSampler(i, texture_units[i].sampler); } } // Framebuffer if (draw.framebuffer != cur_state.draw.framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer); } // Vertex array if (draw.vertex_array != cur_state.draw.vertex_array) { glBindVertexArray(draw.vertex_array); } // Vertex buffer if (draw.vertex_buffer != cur_state.draw.vertex_buffer) { glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); } // Uniform buffer if (draw.uniform_buffer != cur_state.draw.uniform_buffer) { glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer); } // Shader program if (draw.shader_program != cur_state.draw.shader_program) { glUseProgram(draw.shader_program); } cur_state = *this; }
GLboolean UtilResetState(void) { // Do we need to delete textures, shaders, and programs? #if 0 GLint i, val; int windowWidth = atoi(flagWidthValue.cstring); int windowHeight = atoi(flagHeightValue.cstring); glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &val ); for( i = 0; i < val; ++i ) { glDisableVertexAttribArray( i ); glVertexAttribPointer( i , 4, GL_FLOAT, GL_FALSE, 0, NULL ); } glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glViewport( 0, 0, windowWidth, windowHeight ); glDepthRangef( 0, 1 ); glLineWidth( 1.f ); glDisable( GL_CULL_FACE ); glCullFace( GL_BACK ); glFrontFace( GL_CCW ); glPolygonOffset( 0, 0 ); glDisable( GL_SAMPLE_ALPHA_TO_COVERAGE ); glDisable( GL_SAMPLE_COVERAGE ); glSampleCoverage( 1, GL_FALSE ); glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, &val ); for ( i = 0; i < val; ++i ) { glActiveTexture( GL_TEXTURE0+i ); glBindTexture( GL_TEXTURE_2D, 0 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //glBindTexture( GL_TEXTURE_3D, 0 ); // Need to check to see if extension is supported //glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); //glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); //glTexParameteri( GL_TEXTURE_3D, GL_WRAP_S, GL_REPEAT ); //glTexParameteri( GL_TEXTURE_3D, GL_WRAP_T, GL_REPEAT ); glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT ); } glActiveTexture( GL_TEXTURE0 ); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glDepthMask( GL_TRUE ); glStencilMaskSeparate( GL_FRONT_AND_BACK, 0xffffffff ); glClearColor( 0, 0, 0, 0 ); glClearDepthf( 1 ); glClearStencil( 0 ); glDisable( GL_SCISSOR_TEST ); glScissor( 0, 0, windowWidth, windowHeight ); glDisable( GL_STENCIL_TEST ); glStencilFuncSeparate( GL_FRONT_AND_BACK, GL_ALWAYS, 0, 0xffffffff ); glStencilOpSeparate( GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP ); glDisable( GL_DEPTH_TEST ); glDepthFunc( GL_LESS ); glDisable( GL_BLEND ); glBlendFuncSeparate( GL_ONE, GL_ZERO, GL_ONE, GL_ZERO ); glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD ); glBlendColor( 0, 0, 0, 0 ); glEnable( GL_DITHER ); glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); glPixelStorei( GL_PACK_ALIGNMENT, 4 ); glUseProgram(0); glGetError(); #endif return GL_TRUE; }
static void icon_draw_size( float x, float y, int icon_id, float aspect, float alpha, const float rgb[3], enum eIconSizes size, int draw_size, const bool UNUSED(nocreate), const bool is_preview) { bTheme *btheme = UI_GetTheme(); Icon *icon = NULL; DrawInfo *di = NULL; IconImage *iimg; const float fdraw_size = (float)draw_size; int w, h; icon = BKE_icon_get(icon_id); alpha *= btheme->tui.icon_alpha; if (icon == NULL) { if (G.debug & G_DEBUG) printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id); return; } di = (DrawInfo *)icon->drawinfo; if (!di) { di = icon_create_drawinfo(); icon->drawinfo = di; icon->drawinfo_free = UI_icons_free_drawinfo; } /* scale width and height according to aspect */ w = (int)(fdraw_size / aspect + 0.5f); h = (int)(fdraw_size / aspect + 0.5f); if (di->type == ICON_TYPE_VECTOR) { /* vector icons use the uiBlock transformation, they are not drawn * with untransformed coordinates like the other icons */ di->data.vector.func((int)x, (int)y, w, h, 1.0f); } else if (di->type == ICON_TYPE_TEXTURE) { /* texture image use premul alpha for correct scaling */ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y, di->data.texture.w, di->data.texture.h, alpha, rgb); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else if (di->type == ICON_TYPE_BUFFER) { /* it is a builtin icon */ iimg = di->data.buffer.image; #ifndef WITH_HEADLESS icon_verify_datatoc(iimg); #endif if (!iimg->rect) return; /* something has gone wrong! */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, is_preview); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else if (di->type == ICON_TYPE_PREVIEW) { PreviewImage *pi = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj; if (pi) { /* no create icon on this level in code */ if (!pi->rect[size]) return; /* something has gone wrong! */ /* preview images use premul alpha ... */ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, is_preview); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } }
//============================== // OvrGazeCursorLocal::Render void OvrGazeCursorLocal::Render( int const eye, Matrix4f const & mvp ) const { GL_CheckErrors( "OvrGazeCursorLocal::Render - pre" ); //LOG( "OvrGazeCursorLocal::Render" ); if ( HiddenFrames >= 0 ) { return; } if ( !HasUser && !TimerActive() ) { return; } if ( Hidden && !TimerActive() ) { return; } if ( CursorScale <= 0.0f ) { LOG( "OvrGazeCursorLocal::Render - scale 0" ); return; } // It is important that glBlendFuncSeparate be used so that destination alpha // correctly holds the opacity over the overlay plane. If normal blending is // used, the cursor ghosts will "punch holes" in things through to the overlay plane. glEnable( GL_BLEND ); glBlendFuncSeparate( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); // If the cursor is not active, allow it to depth sort... if it is active we know it should // be on top, so don't bother depth testing. However, this assumes that the cursor is placed // correctly. If it isn't, then it could still appear stereoscopically behind the object it's // on top of, which would be bad. The reason for not using depth testing when active is to // solve any z-fighting issues, particularly with SwipeView, where the panel distance isn't // entirely accurate right now. It can also be solved by pushing the cursor in a little bit // from the panel, but in stereo vision it looks like it's floating further above the panel // than it does with other systems like the VRMenu. glDepthMask( GL_FALSE ); // don't write to depth, or ghost trails wouldn't work // We always want depth test enabled so we can see if any GUI panels have // been placed too close and obscured the cursor. glEnable( GL_DEPTH_TEST ); glUseProgram( CursorProgram.program ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, CursorTextureHandle[Info.State] ); // draw from oldest and faintest to newest for ( int i = TRAIL_GHOSTS-1 ; i >= 0 ; i-- ) { const int index = ( CurrentTransform - i ) % TRAIL_GHOSTS; if ( index <= 0 ) { continue; } Vector4f cursorColor( 1.0f, 1.0f, 1.0f, 0.5 * ( 1.0 - (float)i / TRAIL_GHOSTS ) ); glUniform4fv( CursorProgram.uColor, 1, &cursorColor.x ); Matrix4f cursorMVP = mvp * CursorTransform[index]; glUniformMatrix4fv( CursorProgram.uMvp, 1, GL_FALSE, cursorMVP.Transposed().M[0] ); CursorGeometry.Draw(); } // Reverse depth test and draw the scattered ghosts where they are occluded glDepthFunc( GL_GREATER ); for ( int i = TRAIL_GHOSTS-1 ; i >= 0 ; i-- ) { const int index = ( CurrentTransform - i ) % TRAIL_GHOSTS; if ( index <= 0 ) { continue; } Vector4f cursorColor( 1.0f, 0.0f, 0.0f, 0.15 * ( 1.0 - (float)i / TRAIL_GHOSTS ) ); glUniform4fv( CursorProgram.uColor, 1, &cursorColor.x ); Matrix4f cursorMVP = mvp * CursorScatterTransform[index]; glUniformMatrix4fv( CursorProgram.uMvp, 1, GL_FALSE, cursorMVP.Transposed().M[0] ); CursorGeometry.Draw(); } glDepthFunc( GL_LEQUAL ); // draw the timer if it's enabled if ( TimerEndTime > 0.0 && ovr_GetTimeInSeconds() >= TimerShowTime ) { glUseProgram( TimerProgram.program ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, TimerTextureHandle ); glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, ColorTableHandle ); // do not do any filtering on the "palette" texture glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); Matrix4f timerMVP = mvp * TimerTransform; glUniformMatrix4fv( TimerProgram.uMvp, 1, GL_FALSE, timerMVP.Transposed().M[0] ); Vector4f cursorColor( 0.0f, 0.643f, 1.0f, 1.0f ); glUniform4fv( TimerProgram.uColor, 1, &cursorColor.x ); glUniform2fv( TimerProgram.uColorTableOffset, 1, &ColorTableOffset.x ); CursorGeometry.Draw(); } glDepthMask( GL_TRUE ); glDisable( GL_BLEND ); GL_CheckErrors( "OvrGazeCursorLocal::Render - post" ); }
void OpenGLBlendState::apply() { if (changed_desc) { changed_desc = false; BlendEquation equation_color, equation_alpha; BlendFunc src, dest, src_alpha, dest_alpha; desc.get_blend_equation(equation_color, equation_alpha); desc.get_blend_function(src, dest, src_alpha, dest_alpha); desc.is_blending_enabled() ? glEnable(GL_BLEND) : glDisable(GL_BLEND); if (glColorMask) { bool red, green, blue, alpha; desc.get_color_write(red, green, blue, alpha); glColorMask(red, green, blue, alpha); } if (equation_color == equation_alpha) { if (glBlendEquation) glBlendEquation(OpenGL::to_enum(equation_color)); } else { if (glBlendEquationSeparate) { glBlendEquationSeparate(OpenGL::to_enum(equation_color), OpenGL::to_enum(equation_alpha)); } else { if (glBlendEquation) glBlendEquation(OpenGL::to_enum(equation_color)); } } if (src == src_alpha && dest == dest_alpha) { if (glBlendFunc) glBlendFunc(OpenGL::to_enum(src), OpenGL::to_enum(dest)); } else { if (glBlendFuncSeparate) { glBlendFuncSeparate(OpenGL::to_enum(src), OpenGL::to_enum(dest), OpenGL::to_enum(src_alpha), OpenGL::to_enum(dest_alpha)); } else { if (glBlendFunc) glBlendFunc(OpenGL::to_enum(src), OpenGL::to_enum(dest)); } } desc.is_logic_op_enabled() ? glEnable(GL_COLOR_LOGIC_OP) : glDisable(GL_COLOR_LOGIC_OP); if (glLogicOp) glLogicOp(OpenGL::to_enum(desc.get_logic_op())); } if (changed_blend_color) { changed_blend_color = false; if (glBlendColor) glBlendColor(blend_color.r, blend_color.g, blend_color.b, blend_color.a); } }
void OGLRenderState::apply(const RenderState& _stateCaptured) noexcept { const auto& blendState = this->getBlendState(); const auto& rasterState = this->getRasterState(); const auto& depthState = this->getDepthState(); const auto& stencilState = this->getStencilState(); auto& _blendState = _stateCaptured.getBlendState(); auto& _rasterState = _stateCaptured.getRasterState(); auto& _depthState = _stateCaptured.getDepthState(); auto& _stencilState = _stateCaptured.getStencilState(); if (blendState.blendEnable) { if (!_blendState.blendEnable) { #if _USE_RENDER_COMMAND BlendEnableCommand command; command.header = GL_BLEND_ENABLE_COMMAND; _renderCommands.write(&command, sizeof(command)); #else glEnable(GL_BLEND); #endif } if (blendState.blendSeparateEnable) { if (_blendState.blendSrc != blendState.blendSrc || _blendState.blendDest != blendState.blendDest || _blendState.blendAlphaSrc != blendState.blendAlphaSrc || _blendState.blendAlphaDest != blendState.blendAlphaDest) { GLenum sfactorRGB = OGLTypes::asBlendFactor(blendState.blendSrc); GLenum dfactorRGB = OGLTypes::asBlendFactor(blendState.blendDest); GLenum sfactorAlpha = OGLTypes::asBlendFactor(blendState.blendAlphaSrc); GLenum dfactorAlpha = OGLTypes::asBlendFactor(blendState.blendAlphaDest); glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); } if (_blendState.blendOp != blendState.blendOp || _blendState.blendAlphaOp != blendState.blendAlphaOp) { GLenum modeRGB = OGLTypes::asBlendOperation(blendState.blendOp); GLenum modeAlpha = OGLTypes::asBlendOperation(blendState.blendAlphaOp); glBlendEquationSeparate(modeRGB, modeAlpha); } } else { if (_blendState.blendSrc != blendState.blendSrc || _blendState.blendDest != blendState.blendDest) { GLenum sfactorRGB = OGLTypes::asBlendFactor(blendState.blendSrc); GLenum dfactorRGB = OGLTypes::asBlendFactor(blendState.blendDest); glBlendFunc(sfactorRGB, dfactorRGB); } if (_blendState.blendOp != blendState.blendOp) { GLenum modeRGB = OGLTypes::asBlendOperation(blendState.blendOp); glBlendEquation(modeRGB); } } } else { if (_blendState.blendEnable) { glDisable(GL_BLEND); } } if (_rasterState.cullMode != rasterState.cullMode) { if (rasterState.cullMode != GPU_CULL_NONE) { GLenum mode = OGLTypes::asCullMode(rasterState.cullMode); glEnable(GL_CULL_FACE); glCullFace(mode); } else { glDisable(GL_CULL_FACE); } } #if !defined(EGLAPI) if (_rasterState.fillMode != rasterState.fillMode) { GLenum mode = OGLTypes::asFillMode(rasterState.fillMode); glPolygonMode(GL_FRONT_AND_BACK, mode); } #endif if (_rasterState.scissorTestEnable != rasterState.scissorTestEnable) { if (rasterState.scissorTestEnable) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); } if (_rasterState.srgbEnable != rasterState.srgbEnable) { if (rasterState.srgbEnable) glEnable(GL_FRAMEBUFFER_SRGB); else glDisable(GL_FRAMEBUFFER_SRGB); } if (depthState.depthEnable) { if (!_depthState.depthEnable) { glEnable(GL_DEPTH_TEST); } if (_depthState.depthFunc != depthState.depthFunc) { GLenum func = OGLTypes::asCompareFunction(depthState.depthFunc); glDepthFunc(func); } } else { if (_depthState.depthEnable) { glDisable(GL_DEPTH_TEST); } } if (_depthState.depthWriteMask != depthState.depthWriteMask) { GLboolean enable = depthState.depthWriteMask ? GL_TRUE : GL_FALSE; glDepthMask(enable); } if (depthState.depthBiasEnable) { if (!_depthState.depthBiasEnable) { glEnable(GL_POLYGON_OFFSET_FILL); } if (_depthState.depthBias != depthState.depthBias || _depthState.depthSlopScaleBias != depthState.depthSlopScaleBias) { glPolygonOffset(depthState.depthSlopScaleBias, depthState.depthBias); } } else { if (_depthState.depthBiasEnable) { glDisable(GL_POLYGON_OFFSET_FILL); } } if (stencilState.stencilEnable) { if (!_stencilState.stencilEnable) { glEnable(GL_STENCIL_TEST); } if (stencilState.stencilTwoEnable) { if (_stencilState.stencilFunc != stencilState.stencilFunc || _stencilState.stencilRef != stencilState.stencilRef || _stencilState.stencilReadMask != stencilState.stencilReadMask) { GLenum frontfunc = OGLTypes::asCompareFunction(stencilState.stencilFunc); glStencilFuncSeparate(GL_FRONT, frontfunc, stencilState.stencilRef, stencilState.stencilReadMask); GLenum backfunc = OGLTypes::asCompareFunction(stencilState.stencilTwoFunc); glStencilFuncSeparate(GL_BACK, backfunc, stencilState.stencilRef, stencilState.stencilTwoReadMask); } if (_stencilState.stencilFail != _stencilState.stencilFail || _stencilState.stencilZFail != _stencilState.stencilZFail || _stencilState.stencilPass != _stencilState.stencilPass) { GLenum frontfail = OGLTypes::asStencilOperation(_stencilState.stencilFail); GLenum frontzfail = OGLTypes::asStencilOperation(_stencilState.stencilZFail); GLenum frontpass = OGLTypes::asStencilOperation(_stencilState.stencilPass); glStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontpass); GLenum backfail = OGLTypes::asStencilOperation(_stencilState.stencilTwoFail); GLenum backzfail = OGLTypes::asStencilOperation(_stencilState.stencilTwoZFail); GLenum backpass = OGLTypes::asStencilOperation(_stencilState.stencilTwoPass); glStencilOpSeparate(GL_BACK, backfail, backzfail, backpass); } if (_stencilState.stencilWriteMask != stencilState.stencilWriteMask || _stencilState.stencilTwoWriteMask != stencilState.stencilTwoWriteMask) { glStencilMaskSeparate(GL_FRONT, stencilState.stencilWriteMask); glStencilMaskSeparate(GL_BACK, stencilState.stencilTwoWriteMask); } } else { if (_stencilState.stencilFunc != stencilState.stencilFunc || _stencilState.stencilRef != stencilState.stencilRef || _stencilState.stencilReadMask != stencilState.stencilReadMask) { GLenum func = OGLTypes::asCompareFunction(stencilState.stencilFunc); glStencilFunc(func, stencilState.stencilRef, stencilState.stencilReadMask); } if (_stencilState.stencilFail != stencilState.stencilFail || _stencilState.stencilZFail != stencilState.stencilZFail || _stencilState.stencilPass != stencilState.stencilPass) { GLenum fail = OGLTypes::asStencilOperation(stencilState.stencilFail); GLenum zfail = OGLTypes::asStencilOperation(stencilState.stencilZFail); GLenum pass = OGLTypes::asStencilOperation(stencilState.stencilPass); glStencilOp(fail, zfail, pass); } if (_stencilState.stencilWriteMask != stencilState.stencilWriteMask) { glStencilMask(stencilState.stencilWriteMask); } } } else { if (_stencilState.stencilEnable) { glDisable(GL_STENCIL_TEST); } } }
void Device_OpenGL::SetBlendState(const BlendState &blendState) { currentBlendState = blendState; glBlendEquationSeparate(blendState.colorBlendEquation, blendState.alphaBlendEquation); glBlendFuncSeparate(blendState.colorSrcBlendFactor, blendState.colorDestBlendFactor, blendState.alphaSrcBlendFactor, blendState.alphaDestBlendFactor); }
bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp) { int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR const_color; const int blend_modes[10] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_DST_COLOR, #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR #else GL_ONE, GL_ONE #endif }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; (void)ogl_disp; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); const_color = al_get_blend_color(); /* glBlendFuncSeparate was only included with OpenGL 1.4 */ #if !defined ALLEGRO_CFG_OPENGLES if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { #else /* FIXME: At this time (09/2014) there are a lot of Android phones that * don't support glBlendFuncSeparate even though they claim OpenGL ES 2.0 * support. Rather than not work on 20-25% of phones, we just don't support * separate blending on Android for now. */ #ifdef ALLEGRO_ANDROID if (false) { #else if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { #endif #endif glEnable(GL_BLEND); #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) #ifndef ALLEGRO_ANDROID_HACK_X86_64 glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a); #endif #endif glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else { glBlendEquation(blend_equations[op]); } } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) #ifndef ALLEGRO_ANDROID_HACK_X86_64 glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a); #endif #endif glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); } else { ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n", op, src_color, dst_color, op_alpha, src_alpha, dst_alpha); return false; } } return true; } /* These functions make drawing calls use shaders or the fixed pipeline * based on what the user has set up. FIXME: OpenGL only right now. */ static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { /* Only use this shader stuff with GLES2+ or equivalent */ if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.pos_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); } #endif } else { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(n, t, stride, v); } } static void vert_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.pos_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); } #endif } else { glDisableClientState(GL_VERTEX_ARRAY); } } static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.color_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc); } #endif } else { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(n, t, stride, v); } } static void color_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.color_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc); } #endif } else { glDisableClientState(GL_COLOR_ARRAY); } } static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.texcoord_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); } #endif } else { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(n, t, stride, v); } } static void tex_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.texcoord_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); } #endif } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } /* There's a very nasty bug in Android 2.1 that makes glClear cause * screen flicker (appears to me it's swapping buffers.) Work around * by drawing two triangles instead on that OS. */ static void ogl_clear_android_2_1_workaround(ALLEGRO_DISPLAY *d, float r, float g, float b, float a) { GLfloat v[8] = { 0, d->h, 0, 0, d->w, d->h, d->w, 0 }; GLfloat c[16] = { r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a }; ALLEGRO_TRANSFORM bak1, bak2, t; al_copy_transform(&bak1, al_get_current_projection_transform()); al_copy_transform(&bak2, al_get_current_transform()); al_identity_transform(&t); al_orthographic_transform(&t, 0, 0, -1, d->w, d->h, 1); al_use_projection_transform(&t); al_identity_transform(&t); al_use_transform(&t); _al_opengl_set_blender(d); vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), v); color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), c); if (!(d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); vert_ptr_off(d); color_ptr_off(d); al_use_projection_transform(&bak1); al_use_transform(&bak2); } static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY *ogl_disp = (void *)d; ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; float r, g, b, a; if (target->parent) target = target->parent; ogl_target = target->extra; if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != target) || target->locked) { _al_clear_bitmap_by_locking(target, color); return; } al_unmap_rgba_f(*color, &r, &g, &b, &a); if (ogl_target->is_backbuffer && IS_ANDROID_AND(_al_android_is_os_2_1())) { ogl_clear_android_2_1_workaround(d, r, g, b, a); return; } glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT); }
int render::exec() { cur_width = req_width; cur_height = req_height; glfwMakeContextCurrent(window); if (glewInit() != GLEW_OK) ERRRET(1, "FATAL: GLEW could not be initialized!\n"); if (!GLEW_VERSION_4_5) ERRRET(1, "FATAL: This program requires an OpenGL 4.5 compatible render device.\n"); if (!render::shader::init()) ERRRET(1, "FATAL: Shaders failed to load.\n"); if (!render::texture::init()) ERRRET(1, "FATAL: Textures failed to load.\n"); if (!render::mesh::init()) ERRRET(1, "FATAL: Meshes failed to load.\n"); if (!render::framebuffer::init(cur_width, cur_height)) ERRRET(1, "FATAL: Framebuffers failed to initialize.\n"); glClearColor(0.0f, 0.75f, 1.0f, 1.0f); glfwSwapInterval(1); while (!glfwWindowShouldClose(window)) { //Adjust Viewport and Framebuffers if necessary if (cur_width != req_width || cur_height != req_height) { cur_width = req_width; cur_height = req_height; glViewport(0, 0, cur_width, cur_height); render::framebuffer::update_framebuffer_sizes(cur_width, cur_height); } //Bind the color+glow framebuffer render::framebuffer::cc->bind(); render::framebuffer::clear(); //Draw the board render::shader::board->use(); render::texture::bind_board(); render::shader::board->uniform_transform(glm::vec3{0, 0, 0}, glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{1.0f, 1.0f, 1.0f}); render::mesh::draw_board(); //Draw the pieces glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); render::texture::bind_piece_pawn(); render::shader::piece->use(); game::set_board_lock(true); for (shogi::piece_placement const & piece : game::get_pieces()) { if (piece.piece->align == shogi::alignment::HOME) { render::shader::piece->uniform_color(glm::vec3{1.0f, 0.0f, 0.5f}); } else { render::shader::piece->uniform_color(glm::vec3{0.0f, 1.0f, 0.5f}); } render::shader::piece->uniform_transform(glm::vec3{piece.coords.x / 4.5f - (1.0f - (1.0f / 9)), piece.coords.y / 4.5f - (1.0f - (1.0f / 9)), 0}, glm::vec3{0.0f, 0.0f, piece.piece->align == shogi::alignment::HOME ? 0.0f : glm::radians(180.0f)}, glm::vec3{0.111111f, 0.111111f, 1.0f}); render::mesh::draw_piece(); } game::set_board_lock(false); glDisable(GL_BLEND); //Bind main framebuffer and begin first pass - diffuse render::framebuffer::use_mainfb(); render::shader::postproc_0->use(); render::framebuffer::cc->bind_as_textures(); render::mesh::draw_fullquad(); //Second pass - glow glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE, GL_ZERO); render::shader::postproc_glow->use(); render::mesh::draw_fullquad(); glDisable(GL_BLEND); glfwSwapBuffers(window); } }
void AmbientOcclusionEffect::render() { glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); // render with the occlusion shader to the secondary/tertiary buffer QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); freeFBO->bind(); float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; Application::getInstance()->computeOffAxisFrustum( left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_X_INDEX = 0; const int VIEWPORT_WIDTH_INDEX = 2; QSize widgetSize = Application::getInstance()->getGLWidget()->size(); float sMin = viewport[VIEWPORT_X_INDEX] / (float)widgetSize.width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)widgetSize.width(); _occlusionProgram->bind(); _occlusionProgram->setUniformValue(_nearLocation, nearVal); _occlusionProgram->setUniformValue(_farLocation, farVal); _occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom); _occlusionProgram->setUniformValue(_rightTopLocation, right, top); _occlusionProgram->setUniformValue(_noiseScaleLocation, viewport[VIEWPORT_WIDTH_INDEX] / (float)ROTATION_WIDTH, widgetSize.height() / (float)ROTATION_HEIGHT); _occlusionProgram->setUniformValue(_texCoordOffsetLocation, sMin, 0.0f); _occlusionProgram->setUniformValue(_texCoordScaleLocation, sWidth, 1.0f); renderFullscreenQuad(); _occlusionProgram->release(); freeFBO->release(); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); // now render secondary to primary with 4x4 blur Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind(); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); _blurProgram->bind(); _blurProgram->setUniformValue(_blurScaleLocation, 1.0f / widgetSize.width(), 1.0f / widgetSize.height()); renderFullscreenQuad(sMin, sMin + sWidth); _blurProgram->release(); glBindTexture(GL_TEXTURE_2D, 0); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); }
/* Called by GLUT whenever the window needs to be redrawn. This * function should not be called directly by the programmer. Instead, * we can call glutPostRedisplay() to request that GLUT call display() * at some point. */ void display() { /* If we are using DGR, send or receive data to keep multiple * processes/computers synchronized. */ dgr_update(); /* Render the scene once for each viewport. Frequently one * viewport will fill the entire screen. However, this loop will * run twice for HMDs (once for the left eye and once for the * right. */ viewmat_begin_frame(); for(int viewportID=0; viewportID<viewmat_num_viewports(); viewportID++) { viewmat_begin_eye(viewportID); /* Where is the viewport that we are drawing onto and what is its size? */ int viewport[4]; // x,y of lower left corner, width, height viewmat_get_viewport(viewport, viewportID); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); /* Clear the current viewport. Without glScissor(), glClear() * clears the entire screen. We could call glClear() before * this viewport loop---but on order for all variations of * this code to work (Oculus support, etc), we can only draw * after viewmat_begin_eye(). */ glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); glEnable(GL_SCISSOR_TEST); glClearColor(.2,.2,.2,0); // set clear color to grey glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // turn on depth testing kuhl_errorcheck(); /* Turn on blending (note, if you are using transparent textures, the transparency may not look correct unless you draw further items before closer items. This program always draws the geometry in the same order.). */ glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); /* Get the view or camera matrix; update the frustum values if needed. */ float viewMat[16], perspective[16]; viewmat_get(viewMat, perspective, viewportID); /* Calculate an angle to rotate the * object. glutGet(GLUT_ELAPSED_TIME) is the number of * milliseconds since glutInit() was called. */ int count = glutGet(GLUT_ELAPSED_TIME) % 10000; // get a counter that repeats every 10 seconds float angle = count / 10000.0 * 360; // rotate 360 degrees every 10 seconds /* Make sure all computers/processes use the same angle */ dgr_setget("angle", &angle, sizeof(GLfloat)); /* Create a 4x4 rotation matrix based on the angle we computed. */ float rotateMat[16]; mat4f_rotateAxis_new(rotateMat, angle, 0,1,0); /* Create a scale matrix. */ float scaleMatrix[16]; mat4f_scale_new(scaleMatrix, 3, 3, 3); // Modelview = (viewMatrix * scaleMatrix) * rotationMatrix float modelview[16]; mat4f_mult_mat4f_new(modelview, viewMat, scaleMatrix); mat4f_mult_mat4f_new(modelview, modelview, rotateMat); kuhl_errorcheck(); glUseProgram(program); kuhl_errorcheck(); /* Send the perspective projection matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("Projection"), 1, // number of 4x4 float matrices 0, // transpose perspective); // value /* Send the modelview matrix to the vertex program. */ glUniformMatrix4fv(kuhl_get_uniform("ModelView"), 1, // number of 4x4 float matrices 0, // transpose modelview); // value kuhl_errorcheck(); /* Draw the geometry using the matrices that we sent to the * vertex programs immediately above */ kuhl_geometry_draw(&triangle); } // finish viewport loop viewmat_end_frame(); /* Check for errors. If there are errors, consider adding more * calls to kuhl_errorcheck() in your code. */ kuhl_errorcheck(); /* Ask GLUT to call display() again. We shouldn't call display() * ourselves recursively because it will not leave time for GLUT * to call other callback functions for when a key is pressed, the * window is resized, etc. */ glutPostRedisplay(); }
void apply(CoreRenderingStatus & target, const CoreRenderingStatus & actual, bool forced) { // Blending if(forced || target.blendingParametersChanged(actual)) { const BlendingParameters & targetParams = target.getBlendingParameters(); const BlendingParameters & actualParams = actual.getBlendingParameters(); if(forced || targetParams.isEnabled() != actualParams.isEnabled()) { if(actualParams.isEnabled()) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } } if(forced || targetParams.getBlendFuncSrcRGB() != actualParams.getBlendFuncSrcRGB() || targetParams.getBlendFuncDstRGB() != actualParams.getBlendFuncDstRGB() || targetParams.getBlendFuncSrcAlpha() != actualParams.getBlendFuncSrcAlpha() || targetParams.getBlendFuncDstAlpha() != actualParams.getBlendFuncDstAlpha()) { glBlendFuncSeparate(BlendingParameters::functionToGL(actualParams.getBlendFuncSrcRGB()), BlendingParameters::functionToGL(actualParams.getBlendFuncDstRGB()), BlendingParameters::functionToGL(actualParams.getBlendFuncSrcAlpha()), BlendingParameters::functionToGL(actualParams.getBlendFuncDstAlpha())); } if(forced || targetParams.getBlendColor() != actualParams.getBlendColor()) { glBlendColor(actualParams.getBlendColor().getR(), actualParams.getBlendColor().getG(), actualParams.getBlendColor().getB(), actualParams.getBlendColor().getA()); } if(forced || targetParams.getBlendEquationRGB() != actualParams.getBlendEquationRGB() || targetParams.getBlendEquationAlpha() != actualParams.getBlendEquationAlpha()) { glBlendEquationSeparate(BlendingParameters::equationToGL(actualParams.getBlendEquationRGB()), BlendingParameters::equationToGL(actualParams.getBlendEquationAlpha())); } target.updateBlendingParameters(actual); } // ColorBuffer if(forced || target.colorBufferParametersChanged(actual)) { glColorMask( actual.getColorBufferParameters().isRedWritingEnabled() ? GL_TRUE : GL_FALSE, actual.getColorBufferParameters().isGreenWritingEnabled() ? GL_TRUE : GL_FALSE, actual.getColorBufferParameters().isBlueWritingEnabled() ? GL_TRUE : GL_FALSE, actual.getColorBufferParameters().isAlphaWritingEnabled() ? GL_TRUE : GL_FALSE ); target.setColorBufferParameters(actual.getColorBufferParameters()); } GET_GL_ERROR(); // CullFace if(forced || target.cullFaceParametersChanged(actual)) { if(actual.getCullFaceParameters().isEnabled()) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } switch(actual.getCullFaceParameters().getMode()) { case CullFaceParameters::CULL_BACK: glCullFace(GL_BACK); break; case CullFaceParameters::CULL_FRONT: glCullFace(GL_FRONT); break; case CullFaceParameters::CULL_FRONT_AND_BACK: glCullFace(GL_FRONT_AND_BACK); break; default: throw std::invalid_argument("Invalid CullFaceParameters::cullFaceMode_t enumerator"); } target.setCullFaceParameters(actual.getCullFaceParameters()); } // DepthBuffer if(forced || target.depthBufferParametersChanged(actual)) { if(actual.getDepthBufferParameters().isTestEnabled()) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } if(actual.getDepthBufferParameters().isWritingEnabled()) { glDepthMask(GL_TRUE); } else { glDepthMask(GL_FALSE); } glDepthFunc(Comparison::functionToGL(actual.getDepthBufferParameters().getFunction())); target.setDepthBufferParameters(actual.getDepthBufferParameters()); } GET_GL_ERROR(); // Line if(forced || target.lineParametersChanged(actual)) { auto width = actual.getLineParameters().getWidth(); glLineWidth(RenderingContext::getCompabilityMode() ? width : std::min(width, 1.0f)); target.setLineParameters(actual.getLineParameters()); } // stencil if (forced || target.stencilParametersChanged(actual)) { const StencilParameters & targetParams = target.getStencilParameters(); const StencilParameters & actualParams = actual.getStencilParameters(); if(forced || targetParams.isEnabled() != actualParams.isEnabled()) { if(actualParams.isEnabled()) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } } if(forced || targetParams.differentFunctionParameters(actualParams)) { glStencilFunc(Comparison::functionToGL(actualParams.getFunction()), actualParams.getReferenceValue(), actualParams.getBitMask().to_ulong()); } if(forced || targetParams.differentActionParameters(actualParams)) { glStencilOp(convertStencilAction(actualParams.getFailAction()), convertStencilAction(actualParams.getDepthTestFailAction()), convertStencilAction(actualParams.getDepthTestPassAction())); } target.updateStencilParameters(actual); } GET_GL_ERROR(); #ifdef LIB_GL if(RenderingContext::getCompabilityMode()) { // AlphaTest if(forced || target.alphaTestParametersChanged(actual)) { if(actual.getAlphaTestParameters().isEnabled()) { glDisable(GL_ALPHA_TEST); } else { glEnable(GL_ALPHA_TEST); } glAlphaFunc(Comparison::functionToGL(actual.getAlphaTestParameters().getMode()), actual.getAlphaTestParameters().getReferenceValue()); target.setAlphaTestParameters(actual.getAlphaTestParameters()); } GET_GL_ERROR(); } #endif /* LIB_GL */ // Lighting if(forced || target.lightingParametersChanged(actual)) { #ifdef LIB_GL if(RenderingContext::getCompabilityMode()) { if(actual.getLightingParameters().isEnabled()) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); } } #endif /* LIB_GL */ target.setLightingParameters(actual.getLightingParameters()); } GET_GL_ERROR(); #ifdef LIB_GL // polygonMode if(forced || target.polygonModeParametersChanged(actual) ) { glPolygonMode(GL_FRONT_AND_BACK, PolygonModeParameters::modeToGL(actual.getPolygonModeParameters().getMode())); target.setPolygonModeParameters(actual.getPolygonModeParameters()); } GET_GL_ERROR(); #endif /* LIB_GL */ // PolygonOffset if(forced || target.polygonOffsetParametersChanged(actual)) { if(actual.getPolygonOffsetParameters().isEnabled()) { glEnable(GL_POLYGON_OFFSET_FILL); #ifdef LIB_GL glEnable(GL_POLYGON_OFFSET_LINE); glEnable(GL_POLYGON_OFFSET_POINT); #endif /* LIB_GL */ glPolygonOffset(actual.getPolygonOffsetParameters().getFactor(), actual.getPolygonOffsetParameters().getUnits()); } else { glDisable(GL_POLYGON_OFFSET_FILL); #ifdef LIB_GL glDisable(GL_POLYGON_OFFSET_LINE); glDisable(GL_POLYGON_OFFSET_POINT); #endif /* LIB_GL */ } target.setPolygonOffsetParameters(actual.getPolygonOffsetParameters()); } GET_GL_ERROR(); // PrimitiveRestart #ifdef LIB_GL if(forced || target.primitiveRestartParametersChanged(actual)) { if(actual.getPrimitiveRestartParameters().isEnabled()) { glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(actual.getPrimitiveRestartParameters().getIndex()); } else { glDisable(GL_PRIMITIVE_RESTART); } target.setPrimitiveRestartParameters(actual.getPrimitiveRestartParameters()); } GET_GL_ERROR(); #endif /* LIB_GL */ // Textures if(forced || target.texturesChanged(actual)) { for(uint_fast8_t unit = 0; unit < MAX_TEXTURES; ++unit) { const auto & texture = actual.getTexture(unit); const auto & oldTexture = target.getTexture(unit); if(forced || texture != oldTexture) { glActiveTexture(GL_TEXTURE0 + static_cast<GLenum>(unit)); if( texture ) { glBindTexture(texture->getGLTextureType(), texture->getGLId()); #if defined(LIB_GL) BufferObject* buffer = texture->getBufferObject(); if(buffer) glTexBuffer( GL_TEXTURE_BUFFER, texture->getFormat().pixelFormat.glInternalFormat, buffer->getGLId() ); #endif } else if( oldTexture ) { glBindTexture(oldTexture->getGLTextureType(), 0); } else { glBindTexture(GL_TEXTURE_2D, 0); } } } target.updateTextures(actual); } GET_GL_ERROR(); }
void displayCallback() { akj::ResetCubeDrawCount(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); if(gUseFBO) { if(gWidth != gPostFXFrameBuffer->mWidth || gHeight != gPostFXFrameBuffer->mHeight) { gPostFXFrameBuffer->InitBuffers(gWidth, gHeight, GL_SRGB8_ALPHA8); //rebind to the normal back buffer glBindFramebuffer(GL_FRAMEBUFFER, 0); } glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFuncSeparate (GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); RenderBackground(); glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); //flame effects need to know about the time gCompositingShader->BindUniformToFloat("my_time", gTime); glPolygonMode(GL_FRONT, GL_FILL); gCompositingShader->Use(); // clear the color buffer // set up camera: we want a quad matched up to the viewport glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); //drawcube gives a -0.5 - 0.5 range, so mult by 2 glScalef(2.0, 2.0, 1.0); glTranslatef( 0.0, 0.0, -0.8); akj::glDrawRect2D(); akj::glCheckAllErrors(__FILE__,__LINE__); glClear( GL_DEPTH_BUFFER_BIT ); } else { RenderBackground(); } glClear( GL_DEPTH_BUFFER_BIT ); glDisable(GL_BLEND); SetupCamera(); RenderRabbit(); if(gUseFBO) { if(gClearFBO) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); gClearFBO = false; } glActiveTexture(GL_TEXTURE0 + gPostFXFrameBuffer->GetBoundTextureUnit()); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, gWidth, gHeight); } glutSwapBuffers(); if (gDump) { // save images to file dumpPPM(); } //printf("number of cubes this frame = %d\n", akj::GetCubeDrawCount()); }
void dejongAttractor::update() { if (!isSetup) { ofLog(OF_LOG_WARNING, "dja: update called but not yet setup"); return; } // float cval = 0.04;//1.0/255.0; float cval = 1.0; ofDisableAlphaBlending(); attractorFbo.begin(); ofClear(0); attractorShader.begin(); attractorShader.setUniform4f("color", cval, cval, cval, 0); attractorShader.setUniform1f("a", this->a); attractorShader.setUniform1f("b", this->b); attractorShader.setUniform1f("c", this->c); attractorShader.setUniform1f("d", this->d); attractorShader.setUniform1f("zoom", this->zoom); attractorShader.setUniform1i("nverts", this->shaderverts); ofEnableAlphaBlending(); glBlendEquation(GL_FUNC_ADD); // pre color blending // glBlendFunc(GL_ONE, GL_ONE); glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE); vertvbo.draw(GL_POINTS, 0, this->nverts); attractorShader.end(); attractorFbo.end(); glDisable(GL_BLEND); drawFbo.begin(); ofClear(0); drawShader.begin(); drawShader.setUniformTexture("texmap", attractorFbo.getTextureReference(), 0); drawShader.setUniform1f("logmaxd", logmaxd); drawShader.setUniform1f("mindens", mindens); float w = attractorFbo.getWidth(); float h = attractorFbo.getHeight(); glBegin(GL_QUADS); glTexCoord2d(1, 1); glVertex2d(1, 1); glTexCoord2d(w, 1); glVertex2d(w, 1); glTexCoord2d(w, h); glVertex2d(w, h); glTexCoord2d(1, h); glVertex2d(1, h); glEnd(); drawShader.end(); drawFbo.end(); if (useBlur) { glEnable(GL_POINT_SMOOTH); blurFbo.begin(); ofClear(0); blurShader.begin(); blurShader.setUniformTexture("texmap", drawFbo.getTextureReference(), 0); glBegin(GL_QUADS); glTexCoord2d(1, 1); glVertex2d(1, 1); glTexCoord2d(w, 1); glVertex2d(w, 1); glTexCoord2d(w, h); glVertex2d(w, h); glTexCoord2d(1, h); glVertex2d(1, h); glEnd(); blurShader.end(); blurFbo.end(); glDisable(GL_POINT_SMOOTH); } dirty = false; }
void enableAlphaBlending() { glEnable(GL_BLEND); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); }
void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha) { makeContextCurrent(); glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); }