Esempio n. 1
0
 void bind(GLenum face)
 {
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get_handle());
     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, face, cubeMapHandle, 0);
     glDrawBuffer(GL_COLOR_ATTACHMENT0);
     gl_check_error(__FILE__, __LINE__);
 }
Esempio n. 2
0
    void on_draw() override
    {
        glfwMakeContextCurrent(window);
        
        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.1f, 0.1f, 0.5f, 1.0f);

        const auto proj = camera.get_projection_matrix((float) width / (float) height);
        const float4x4 view = camera.get_view_matrix();
        const float4x4 viewProj = mul(proj, view);
        
        skydome.render(viewProj, camera.get_eye_point(), camera.farClip);

        grid.render(proj, view);

        gl_check_error(__FILE__, __LINE__);
        
        glfwSwapBuffers(window);
        
        frameCount++;
    }
Esempio n. 3
0
// Bind texture, preserve previous texture state
bool GnashTexture::bind()
{
    TextureState * const ts = &_texture_state;
    ts->old_texture = 0;
    ts->was_bound   = 0;
    ts->was_enabled = glIsEnabled(GL_TEXTURE_2D);

    if (!ts->was_enabled)
        glEnable(GL_TEXTURE_2D);
    else if (gl_get_param(GL_TEXTURE_BINDING_2D, &ts->old_texture))
        ts->was_bound = _texture == ts->old_texture;
    else
        return false;

    if (!ts->was_bound) {
        gl_purge_errors();
        glBindTexture(GL_TEXTURE_2D, _texture);
        if (gl_check_error())
            return false;
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    return true;
}
Esempio n. 4
0
/**
the main engine loop.

the loop invokes fps counting, SDL event handling,
view translation, and calling the main draw_method.
*/
void loop() {
	running = true;
	SDL_Event e;

	while (running) {
		fpscounter->frame();

		while (SDL_PollEvent(&e)) {
			//call the input callback methods
			for(auto cb: callbacks::on_input) {
				if (!cb(&e)) {
					break;
				};
			}
		}

		//call engine tick callback methods
		for(auto cb: callbacks::on_engine_tick) {
			cb();
		}

		//clear the framebuffer to black
		//in the future, we might disable it for lazy drawing
		glClearColor(0.0, 0.0, 0.0, 0.0);
		glClear(GL_COLOR_BUFFER_BIT);

		glPushMatrix(); {
			//set the framebuffer up for camgame rendering
			glTranslatef(camgame_window.x, camgame_window.y, 0);

			//invoke all game drawing callback methods
			for(auto cb: callbacks::on_drawgame) {
				if (!cb()) {
					break;
				};
			}
		}
		glPopMatrix();

		glPushMatrix(); {
			//the hud coordinate system is automatically established

			//invoke all hud drawing callback methods
			for(auto cb: callbacks::on_drawhud) {
				if (!cb()) {
					break;
				};
			}
		}
		glPopMatrix();

		gl_check_error();

		//the rendering is done
		//swap the drawing buffers to actually show the frame
		SDL_GL_SwapWindow(window);
	}
}
Esempio n. 5
0
// Release texture, restore previous texture state
void GnashTexture::release()
{
    TextureState * const ts = &_texture_state;
    if (!ts->was_bound && ts->old_texture)
        glBindTexture(GL_TEXTURE_2D, ts->old_texture);
    if (!ts->was_enabled)
        glDisable(GL_TEXTURE_2D);
    gl_check_error();
}
Esempio n. 6
0
 ExperimentalApp() : GLFWApp(600, 600, "Nearly Empty App")
 {
     int width, height;
     glfwGetWindowSize(window, &width, &height);
     glViewport(0, 0, width, height);
     grid = RenderableGrid(1, 100, 100);
     gl_check_error(__FILE__, __LINE__);
     camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0});
 }
Esempio n. 7
0
 ExperimentalApp() : GLFWApp(940, 720, "GlCamera Sandbox App")
 {
     int width, height;
     glfwGetWindowSize(window, &width, &height);
     glViewport(0, 0, width, height);
     
     cameraController.set_camera(&camera);
     
     camera.look_at({0, 8, 24}, {0, 0, 0});
     cameraZ = camera.pose.position.z;
     
     simpleShader.reset(new GlShader(read_file_text("assets/shaders/simple_vert.glsl"), read_file_text("assets/shaders/simple_frag.glsl")));
     
     {
         lights.resize(2);
         lights[0].color = float3(249.f / 255.f, 228.f / 255.f, 157.f / 255.f);
         lights[0].pose.position = float3(25, 15, 0);
         lights[1].color = float3(255.f / 255.f, 242.f / 255.f, 254.f / 255.f);
         lights[1].pose.position = float3(-25, 15, 0);
     }
     
     {
         cameraPositions.resize(2);
         cameraPositions[0] = Renderable(make_frustum());
         cameraPositions[0].pose.position = float3(0, 8, +24);
         cameraPositions[0].mesh.set_non_indexed(GL_LINES);
         
         cameraPositions[1] = Renderable(make_frustum());
         cameraPositions[1].pose.position = float3(0, 8, -24);
         cameraPositions[1].mesh.set_non_indexed(GL_LINES);
     }
     
     {
         proceduralModels.resize(4);
         
         proceduralModels[0] = Renderable(make_sphere(1.0));
         proceduralModels[0].pose.position = float3(0, 2, +8);
         
         proceduralModels[1] = Renderable(make_cube());
         proceduralModels[1].pose.position = float3(0, 2, -8);
         
         proceduralModels[2] = Renderable(make_icosahedron());
         proceduralModels[2].pose.position = float3(8, 2, 0);
         
         proceduralModels[3] = Renderable(make_octohedron());
         proceduralModels[3].pose.position = float3(-8, 2, 0);
     }
     
     start = look_at_pose(float3(0, 8, +24), float3(-8, 2, 0));
     end = look_at_pose(float3(0, 8, -24), float3(-8, 2, 0));
     
     grid = RenderableGrid(1, 64, 64);
     
     gl_check_error(__FILE__, __LINE__);
 }
Esempio n. 8
0
/// Release texture, restore previous texture state
static void unbind_texture(TextureState *ts)
{
    if (!ts->was_bound && ts->old_texture) {
        glBindTexture(ts->target, ts->old_texture);
    }
    if (!ts->was_enabled) {
        glDisable(ts->target);
    }

    gl_check_error();
}
Esempio n. 9
0
// glGetIntegerv() wrapper
static bool gl_get_param(GLenum param, unsigned int *pval)
{
    GLint val;

    gl_purge_errors();
    glGetIntegerv(param, &val);
    if (gl_check_error())
        return false;
    if (pval)
        *pval = val;
    return true;
}
Esempio n. 10
0
    void create(float2 resolution)
    {
        depthBuffer.load_data(resolution.x, resolution.y, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
        framebuffer.attach(GL_DEPTH_ATTACHMENT, depthBuffer);
        if (!framebuffer.check_complete()) throw std::runtime_error("incomplete framebuffer");

        glGenTextures(1, &cubeMapHandle);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapHandle);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

        for (int i = 0; i < 6; ++i)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R16F, resolution.x, resolution.y, 0, GL_RED, GL_UNSIGNED_SHORT, nullptr);
        }

        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

        struct CameraInfo
        {
            float3 position;
            float3 target;
            float3 up;
            CameraInfo(float3 p, float3 t, float3 u) : position(p), target(t), up(u) {}
        };

        std::vector<CameraInfo> info = {
            {{0, 0, 0}, { 1,  0,  0}, {0, -1,  0}},
            {{0, 0, 0}, {-1,  0,  0}, {0, -1,  0}},
            {{0, 0, 0}, { 0,  1,  0}, {0,  0,  1}},
            {{0, 0, 0}, { 0, -1,  0}, {0,  0, -1}},
            {{0, 0, 0}, { 0,  0,  1}, {0, -1,  0}},
            {{0, 0, 0}, { 0,  0, -1}, {0, -1,  0}},
        };

        for (int i = 0; i < 6; ++i)
        {
            CubemapCamera cc;
            cc.face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
            cc.faceCamera.look_at(info[i].position, info[i].target, info[i].up);
            faces.push_back(cc);
        }

        gl_check_error(__FILE__, __LINE__);
    }
/**
 * gl_get_texture_param:
 * @target: the target to which the texture is bound
 * @param: the parameter name
 * @pval: return location for the value
 *
 * This function is a wrapper around glGetTexLevelParameteriv() that
 * does extra error checking.
 *
 * Return value: %TRUE on success
 */
gboolean
gl_get_texture_param(GLenum target, GLenum param, guint *pval)
{
    GLint val;

    gl_purge_errors();
    glGetTexLevelParameteriv(target, 0, param, &val);
    if (gl_check_error())
        return FALSE;

    if (pval)
        *pval = val;
    return TRUE;
}
/**
 * gl_get_param:
 * @param: the parameter name
 * @pval: return location for the value
 *
 * This function is a wrapper around glGetIntegerv() that does extra
 * error checking.
 *
 * Return value: %TRUE on success
 */
gboolean
gl_get_param(GLenum param, guint *pval)
{
    GLint val;

    gl_purge_errors();
    glGetIntegerv(param, &val);
    if (gl_check_error())
        return FALSE;

    if (pval)
        *pval = val;
    return TRUE;
}
Esempio n. 13
0
    ExperimentalApp() : GLFWApp(1280, 800, "Glass Material App")
    {
        igm.reset(new gui::ImGuiManager(window));
        gui::make_dark_theme();
        
        //cubeTex = load_cubemap();

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);

         // Debugging views for offscreen surfaces
        uiSurface.bounds = {0, 0, (float) width, (float) height};
        uiSurface.add_child( {{0.0000f, +10},{0, +10},{0.1667f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.1667f, +10},{0, +10},{0.3334f, -10},{0.133f, +10}});
        uiSurface.layout();

        grid = RenderableGrid(1, 100, 100);
        cameraController.set_camera(&camera);
        camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0});

		lights[0] = {{0, 10, -10}, {0, 0, 1}};
		lights[1] = {{0, 10, 10}, {0, 1, 0}};

        Renderable reflectiveSphere = Renderable(make_sphere(2.f));
        reflectiveSphere.pose = Pose(float4(0, 0, 0, 1), float3(0, 2, 0));
        glassModels.push_back(std::move(reflectiveSphere));

        Renderable debugAxis = Renderable(make_axis(), false, GL_LINES);
        debugAxis.pose = Pose(float4(0, 0, 0, 1), float3(0, 1, 0));
        regularModels.push_back(std::move(debugAxis));

        Renderable cubeA = Renderable(make_cube());
        cubeA.pose = Pose(make_rotation_quat_axis_angle({1, 0, 1}, ANVIL_PI / 3), float3(5, 0, 0));
        regularModels.push_back(std::move(cubeA));

        Renderable cubeB = Renderable(make_cube());
		cubeB.pose = Pose(make_rotation_quat_axis_angle({1, 0, 1}, ANVIL_PI / 4), float3(-5, 0, 0));
        regularModels.push_back(std::move(cubeB));

        glassMaterialShader = make_watched_shader(shaderMonitor, "assets/shaders/glass_vert.glsl", "assets/shaders/glass_frag.glsl");
        simpleShader = make_watched_shader(shaderMonitor, "assets/shaders/simple_vert.glsl", "assets/shaders/simple_frag.glsl");

        cubeCamera.reset(new CubemapCamera({1024, 1024}));

        gl_check_error(__FILE__, __LINE__);
    }
Esempio n. 14
0
/// Bind texture, preserve previous texture state
static bool bind_texture(TextureState *ts, GLenum target, GLuint texture)
{
    ts->target      = target;
    ts->old_texture = 0;
    ts->was_bound   = 0;
    ts->was_enabled = glIsEnabled(target);

    GLenum texture_binding;
    switch (target) {
    case GL_TEXTURE_1D:
        texture_binding = GL_TEXTURE_BINDING_1D;
        break;
    case GL_TEXTURE_2D:
        texture_binding = GL_TEXTURE_BINDING_2D;
        break;
    case GL_TEXTURE_3D:
        texture_binding = GL_TEXTURE_BINDING_3D;
        break;
    case GL_TEXTURE_RECTANGLE_ARB:
        texture_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
        break;
    default:
        assert(!target);
        return false;
    }

    if (!ts->was_enabled) {
        glEnable(target);
    } else if (gl_get_param(texture_binding, &ts->old_texture)) {
        ts->was_bound = texture == ts->old_texture;
    } else {
        return false;
    }

    if (!ts->was_bound) {
        gl_purge_errors();
        glBindTexture(target, texture);
        if (gl_check_error()) {
            return false;
        }
    }
    return true;
}
Esempio n. 15
0
static gboolean gl_fbo_test_framebuffer( )
{
    gboolean result = TRUE;
    glGetError(); /* Clear error state just in case */
    render_buffer_t buffer = gl_fbo_create_render_buffer( 640, 480, 0 );
    gl_fbo_set_render_target(buffer);

    GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if( status != GL_FRAMEBUFFER_COMPLETE ) {
        ERROR( "Framebuffer failure: %x", status );
        result = FALSE;
    }
    if( result ) {
        result = gl_check_error( "Setting up framebuffer" );
    }

    gl_fbo_destroy_render_buffer( buffer );
    return result;
}
Esempio n. 16
0
GLuint glsl_compile_link(const char *vprogram, const char *fprogram)
{
        char log[32768];
        GLuint vhandle, fhandle;
        GLuint phandle;

        phandle = glCreateProgram();
        vhandle = glCreateShader(GL_VERTEX_SHADER);
        fhandle = glCreateShader(GL_FRAGMENT_SHADER);

        /* compile */
        /* fragmemt */
        glShaderSource(fhandle, 1, &fprogram, NULL);
        glCompileShader(fhandle);
        /* Print compile log */
        glGetShaderInfoLog(fhandle,32768,NULL,log);
        printf("Compile Log: %s\n", log);
        /* vertex */
        glShaderSource(vhandle, 1, &vprogram, NULL);
        glCompileShader(vhandle);
        /* Print compile log */
        glGetShaderInfoLog(vhandle,32768,NULL,log);
        printf("Compile Log: %s\n", log);

        /* attach and link */
        glAttachShader(phandle, vhandle);
        glAttachShader(phandle, fhandle);
        glLinkProgram(phandle);

        printf("Program compilation/link status: ");
        gl_check_error();

        glGetProgramInfoLog(phandle, 32768, NULL, (GLchar*)log);
        if ( strlen(log) > 0 )
                printf("Link Log: %s\n", log);

        // mark shaders for deletion when program is deleted
        glDeleteShader(vhandle);
        glDeleteShader(fhandle);

        return phandle;
}
Esempio n. 17
0
    void on_draw() override
    {
        glfwMakeContextCurrent(window);

        if (igm) igm->begin_frame();

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        glDepthMask(GL_TRUE);

        float windowAspectRatio = (float) width / (float) height;

        const auto proj = camera.get_projection_matrix(windowAspectRatio);
        const float4x4 view = camera.get_view_matrix();
        const float4x4 viewProj = mul(proj, view);

        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        skydome.render(viewProj, camera.get_eye_point(), camera.farClip);

        float3 target = camera.pose.position;

        ////////////////////////////////////////////
        // Directional Light Shadowmap Pass (sun) //
        ////////////////////////////////////////////
        {
            shadowFramebuffer.bind_to_draw();
            shadowmapShader->bind();

            glClear(GL_DEPTH_BUFFER_BIT);
            glViewport(0, 0, shadowmapResolution, shadowmapResolution);

            shadowmapShader->uniform("u_lightViewProj", sunLight->get_view_proj_matrix(target));

            for (auto & object : sceneObjects)
            {
                if (object->castsShadow)
                {
                    shadowmapShader->uniform("u_modelMatrix", object->get_model());
                    object->draw();
                }
            }

            shadowmapShader->unbind();
            shadowFramebuffer.unbind();
        }


        ///////////////////////////////
        // Spot Light Shadowmap Pass //
        ///////////////////////////////
        {

            for (int i = 0; i < spotLightFramebuffers.size(); ++i)
            {
                spotLightFramebuffers[i]->shadowFramebuffer.bind_to_draw();
                shadowmapShader->bind();

                glClear(GL_DEPTH_BUFFER_BIT);
                glViewport(0, 0, shadowmapResolution, shadowmapResolution);

                shadowmapShader->uniform("u_lightViewProj", spotLights[0]->get_view_proj_matrix()); // only take the first into account for debugging

                for (auto & object : sceneObjects)
                {
                    if (object->castsShadow)
                    {
                        shadowmapShader->uniform("u_modelMatrix", object->get_model());
                        object->draw();
                    }
                }

                shadowmapShader->unbind();
                spotLightFramebuffers[i]->shadowFramebuffer.unbind();
            }

        }

        ////////////////////////////////
        // Point Light Shadowmap Pass //
        ////////////////////////////////
        {
            glViewport(0, 0, shadowmapResolution, shadowmapResolution);

            for (int i = 0; i < 6; ++i)
            {
                pointLightFramebuffer->bind(pointLightFramebuffer->faces[i].face);

                pointLightShader->bind();

                glClear(GL_DEPTH_BUFFER_BIT);

                pointLightFramebuffer->faces[i].faceCamera.set_position(pointLight->position); // set position from light data to camera for shadow fbo
                auto viewProj = mul(pointLightFramebuffer->get_projection(), pointLightFramebuffer->faces[i].faceCamera.get_view_matrix());

                pointLightShader->uniform("u_lightWorldPosition", pointLight->position);
                pointLightShader->uniform("u_lightViewProj", viewProj);

                for (auto & object : sceneObjects)
                {
                    if (object->castsShadow)
                    {
                        pointLightShader->uniform("u_modelMatrix", object->get_model());
                        object->draw();
                    }
                }

                pointLightShader->unbind();
                pointLightFramebuffer->unbind();
            }
        }

        // Blur applied to the directional light shadowmap only (others later)
        {
            shadowBlurFramebuffer.bind_to_draw();
            glDrawBuffer(GL_COLOR_ATTACHMENT0);

            gaussianBlurShader->bind();

            // Configured for a 7x7
            gaussianBlurShader->uniform("blurSize", 1.0f / shadowmapResolution);
            gaussianBlurShader->uniform("sigma", blurSigma);
            gaussianBlurShader->uniform("u_modelViewProj", Identity4x4);

            // Horizontal
            gaussianBlurShader->texture("s_blurTexure", 0, shadowDepthTexture);
            gaussianBlurShader->uniform("numBlurPixelsPerSide", 3.0f);
            gaussianBlurShader->uniform("blurMultiplyVec", float2(1.0f, 0.0f));
            fullscreen_post_quad.draw_elements();

            // Vertical
            gaussianBlurShader->texture("s_blurTexure", 0, shadowBlurTexture);
            gaussianBlurShader->uniform("numBlurPixelsPerSide", 3.0f);
            gaussianBlurShader->uniform("blurMultiplyVec", float2(0.0f, 1.0f));
            fullscreen_post_quad.draw_elements();

            gaussianBlurShader->unbind();

            shadowBlurFramebuffer.unbind();
        }

        {
            glViewport(0, 0, width, height);
            sceneShader->bind();

            sceneShader->uniform("u_viewProj", viewProj);
            sceneShader->uniform("u_eye", camera.get_eye_point());
            sceneShader->uniform("u_directionalLight.color", sunLight->color);
            sceneShader->uniform("u_directionalLight.direction", sunLight->direction);
            sceneShader->uniform("u_dirLightViewProjectionMat", sunLight->get_view_proj_matrix(target));

            int samplerIndex = 0;
            sceneShader->uniform("u_shadowMapBias", 0.01f / shadowmapResolution); // fixme
            sceneShader->uniform("u_shadowMapTexelSize", float2(1.0f / shadowmapResolution));
            sceneShader->texture("s_directionalShadowMap", samplerIndex++, shadowBlurTexture);

            sceneShader->uniform("u_spotLightViewProjectionMat[0]", spotLights[0]->get_view_proj_matrix());

            sceneShader->uniform("u_spotLights[0].color", spotLights[0]->color);
            sceneShader->uniform("u_spotLights[0].direction", spotLights[0]->direction);
            sceneShader->uniform("u_spotLights[0].position", spotLights[0]->position);
            sceneShader->uniform("u_spotLights[0].cutoff", spotLights[0]->get_cutoff());
            sceneShader->uniform("u_spotLights[0].constantAtten", spotLights[0]->attenuation.x);
            sceneShader->uniform("u_spotLights[0].linearAtten", spotLights[0]->attenuation.y);
            sceneShader->uniform("u_spotLights[0].quadraticAtten", spotLights[0]->attenuation.z);

            sceneShader->uniform("u_pointLights[0].color", pointLight->color);
            sceneShader->uniform("u_pointLights[0].position", pointLight->position);
            sceneShader->uniform("u_pointLights[0].constantAtten", pointLight->attenuation.x);
            sceneShader->uniform("u_pointLights[0].linearAtten", pointLight->attenuation.y);
            sceneShader->uniform("u_pointLights[0].quadraticAtten", pointLight->attenuation.z);

            // Update the spotlight 2D sampler
            for (int i = 0; i < spotLightFramebuffers.size(); ++i)
            {
                auto & fbo = spotLightFramebuffers[i];
                std::string uniformLocation = "s_spotLightShadowMap[" + std::to_string(i) + "]";
                sceneShader->texture(uniformLocation.c_str(), samplerIndex + i, fbo->shadowDepthTexture);
            }

            // Update the pointlight cube sampler
            for (int i = 0; i < 6; i++)
                sceneShader->texture("s_pointLightCubemap[0]", 2 + i, pointLightFramebuffer->cubeMapHandle, GL_TEXTURE_CUBE_MAP);

            for (auto & object : sceneObjects)
            {
                sceneShader->uniform("u_modelMatrix", object->get_model());
                sceneShader->uniform("u_modelMatrixIT", inv(transpose(object->get_model())));
                object->draw();
                gl_check_error(__FILE__, __LINE__);
            }

            sceneShader->unbind();
        }

        {
            ImGui::Separator();
            ImGui::SliderFloat("Near Clip", &camera.nearClip, 0.1f, 2.0f);
            ImGui::SliderFloat("Far Clip", &camera.farClip, 2.0f, 75.0f);
            ImGui::DragFloat3("Light Direction", &sunLight->direction[0], 0.1f, -1.0f, 1.0f);
            ImGui::Separator();
            ImGui::SliderFloat("Blur Sigma", &blurSigma, 0.05f, 9.0f);
            ImGui::Separator();
            ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
        }

        viewA->draw(uiSurface.children[0]->bounds, int2(width, height));
        viewB->draw(uiSurface.children[1]->bounds, int2(width, height));
        viewC->draw(uiSurface.children[2]->bounds, int2(width, height));
        viewD->draw(uiSurface.children[3]->bounds, int2(width, height));

        gl_check_error(__FILE__, __LINE__);

        if (igm) igm->end_frame();

        glfwSwapBuffers(window);
    }
Esempio n. 18
0
    void on_draw() override
    {
		glfwMakeContextCurrent(window);
        
		if (igm) igm->begin_frame();

		glEnable(GL_CULL_FACE);
		glEnable(GL_DEPTH_TEST);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		int width, height;
		glfwGetWindowSize(window, &width, &height);
		glViewport(0, 0, width, height);

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(1.0f, 0.1f, 0.0f, 1.0f);

		const auto proj = camera.get_projection_matrix((float) width / (float) height);
		const float4x4 view = camera.get_view_matrix();
		const float4x4 viewProj = mul(proj, view);
        
		if (ImGui::SliderInt("Sun Theta", &sunPos.x, 0, 90)) skydome.set_sun_position(sunPos.x, sunPos.y);
		if (ImGui::SliderInt("Sun Phi", &sunPos.y, 0, 360)) skydome.set_sun_position(sunPos.x, sunPos.y);

        auto draw_cubes = [&](float3 eye, float4x4 vp)
        {
            simpleShader->bind();
            
            simpleShader->uniform("u_eye", eye); 
            simpleShader->uniform("u_viewProj", vp);
            
            simpleShader->uniform("u_emissive", float3(0, 0, 0));
            simpleShader->uniform("u_diffuse", float3(0.33f, 0.33f, 0.33f));
            
            for (int i = 0; i < 2; i++)
            {
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].position", lights[i].position);
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].color", lights[i].color);
            }
            
            for (const auto & model : regularModels)
            {
                simpleShader->uniform("u_modelMatrix", model.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }
            
            simpleShader->unbind();
        };

        // Render/Update cube camera
        cubeCamera->render = [&](float3 eyePosition, float4x4 viewMatrix, float4x4 projMatrix)
        {
            skydome.render(mul(projMatrix, viewMatrix), eyePosition, camera.farClip);
			draw_cubes(eyePosition, mul(projMatrix, viewMatrix));
        };

        cubeCamera->update(camera.get_eye_point()); // render from a camera positioned @ {0, 0, 0}

        glViewport(0, 0, width, height);
        skydome.render(viewProj, camera.get_eye_point(), camera.farClip);
        grid.render(proj, view);

        draw_cubes(camera.get_eye_point(), viewProj);
        
		// Glass material
        {
            glassMaterialShader->bind();
            
            glassMaterialShader->uniform("u_eye", camera.get_eye_point());
            glassMaterialShader->uniform("u_viewProj", viewProj);

			// Can set from either a pre-loaded cubemap, or one capured from the cubeCamera
            glassMaterialShader->texture("u_cubemapTex", 0, cubeCamera->get_cubemap_handle(), GL_TEXTURE_CUBE_MAP); // cubeTex.get_gl_handle()

            for (const auto & model : glassModels)
            {
                glassMaterialShader->uniform("u_modelMatrix", model.get_model());
                glassMaterialShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }

            glassMaterialShader->unbind();
            glDisable(GL_BLEND);
        }

        gl_check_error(__FILE__, __LINE__);
        if (igm) igm->end_frame();
        glfwSwapBuffers(window);
        frameCount++;
    }
Esempio n. 19
0
static void *gl_glsl_init(void *data, const char *path)
{
   unsigned i;
   struct shader_program_info shader_prog_info;
   bool shader_support        = false;
#ifdef GLSL_DEBUG
   char *error_string         = NULL;
#endif
   config_file_t *conf        = NULL;
   const char *stock_vertex   = NULL;
   const char *stock_fragment = NULL;
   glsl_shader_data_t   *glsl = (glsl_shader_data_t*)
      calloc(1, sizeof(glsl_shader_data_t));

   if (!glsl)
      return NULL;

   (void)shader_support;

#ifndef HAVE_OPENGLES
   RARCH_LOG("[GLSL]: Checking GLSL shader support ...\n");
   shader_support = glCreateProgram && glUseProgram && glCreateShader
      && glDeleteShader && glShaderSource && glCompileShader && glAttachShader
      && glDetachShader && glLinkProgram && glGetUniformLocation
      && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
      && glUniformMatrix4fv
      && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
      && glGetProgramInfoLog
      && glDeleteProgram && glGetAttachedShaders
      && glGetAttribLocation && glEnableVertexAttribArray
      && glDisableVertexAttribArray
      && glVertexAttribPointer
      && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      goto error;
   }
#endif

   glsl->shader = (struct video_shader*)calloc(1, sizeof(*glsl->shader));
   if (!glsl->shader)
      goto error;

   if (!string_is_empty(path))
   {
      bool ret             = false;
      const char *path_ext = path_get_extension(path);

      if (string_is_equal_fast(path_ext, "glslp", 5))
      {
         conf = config_file_new(path);
         if (conf)
         {
            ret = video_shader_read_conf_cgp(conf, glsl->shader);
            glsl->shader->modern = true;
         }
      }
      else if (string_is_equal_fast(path_ext, "glsl", 4))
      {
         strlcpy(glsl->shader->pass[0].source.path, path,
               sizeof(glsl->shader->pass[0].source.path));
         glsl->shader->passes = 1;
         glsl->shader->modern = true;
         ret = true;
      }

      if (!ret)
      {
         RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
         goto error;
      }
   }
   else
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      glsl->shader->passes = 1;
      glsl->shader->pass[0].source.string.vertex   =
         strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
      glsl->shader->pass[0].source.string.fragment =
         strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
      glsl->shader->modern = true;
   }

   if (!string_is_empty(path))
      video_shader_resolve_relative(glsl->shader, path);
   video_shader_resolve_parameters(conf, glsl->shader);

   if (conf)
   {
      config_file_free(conf);
      conf = NULL;
   }

   stock_vertex = (glsl->shader->modern) ?
      stock_vertex_modern : stock_vertex_legacy;
   stock_fragment = (glsl->shader->modern) ?
      stock_fragment_modern : stock_fragment_legacy;

   if (glsl_core)
   {
      stock_vertex = stock_vertex_core;
      stock_fragment = stock_fragment_core;
   }

#ifdef HAVE_OPENGLES
   if (!glsl->shader->modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      goto error;
   }
#else
   if (glsl_core && !glsl->shader->modern)
   {
      RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n");
      goto error;
   }
#endif

   /* Find all aliases we use in our GLSLP and add #defines for them so
    * that a shader can choose a fallback if we are not using a preset. */
   *glsl->alias_define = '\0';
   for (i = 0; i < glsl->shader->passes; i++)
   {
      if (*glsl->shader->pass[i].alias)
      {
         char define[128];

         define[0] = '\0';

         snprintf(define, sizeof(define), "#define %s_ALIAS\n",
               glsl->shader->pass[i].alias);
         strlcat(glsl->alias_define, define, sizeof(glsl->alias_define));
      }
   }

   shader_prog_info.vertex   = stock_vertex;
   shader_prog_info.fragment = stock_fragment;
   shader_prog_info.is_file  = false;

   if (!gl_glsl_compile_program(glsl, 0, &glsl->prg[0], &shader_prog_info))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      goto error;
   }

   if (!gl_glsl_compile_programs(glsl, &glsl->prg[1]))
      goto error;

   if (!gl_load_luts(glsl->shader, glsl->lut_textures))
   {
      RARCH_ERR("[GL]: Failed to load LUTs.\n");
      goto error;
   }

   for (i = 0; i <= glsl->shader->passes; i++)
      gl_glsl_find_uniforms(glsl, i, glsl->prg[i].id, &glsl->uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error(&error_string))
   {
      RARCH_ERR("%s\n", error_string);
      free(error_string);
      RARCH_WARN("Detected GL error in GLSL.\n");
   }
#endif

   if (glsl->shader->variables)
   {
      retro_ctx_memory_info_t mem_info;
      struct state_tracker_info info;

      mem_info.id         = RETRO_MEMORY_SYSTEM_RAM;

      core_get_memory(&mem_info);

      info.wram           = (uint8_t*)mem_info.data;
      info.info           = glsl->shader->variable;
      info.info_elem      = glsl->shader->variables;

      info.script         = NULL;
      info.script_class   = NULL;
#ifdef HAVE_PYTHON
      info.script         = glsl->shader->script;
      if (*glsl->shader->script_class)
         info.script_class= glsl->shader->script_class;
#endif
      info.script_is_file = NULL;

      glsl->state_tracker = state_tracker_init(&info);

      if (!glsl->state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }

   glsl->prg[glsl->shader->passes  + 1]     = glsl->prg[0];
   glsl->uniforms[glsl->shader->passes + 1] = glsl->uniforms[0];

   if (glsl->shader->modern)
   {
      shader_prog_info.vertex   =
            glsl_core ?
            stock_vertex_core_blend : stock_vertex_modern_blend;
      shader_prog_info.fragment =
            glsl_core ?
            stock_fragment_core_blend : stock_fragment_modern_blend;
      shader_prog_info.is_file  = false;

      gl_glsl_compile_program(
            glsl,
            VIDEO_SHADER_STOCK_BLEND,
            &glsl->prg[VIDEO_SHADER_STOCK_BLEND],
            &shader_prog_info
            );

      gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_STOCK_BLEND].id,
            &glsl->uniforms[VIDEO_SHADER_STOCK_BLEND]);
   }
   else
   {
      glsl->prg[VIDEO_SHADER_STOCK_BLEND] = glsl->prg[0];
      glsl->uniforms[VIDEO_SHADER_STOCK_BLEND] = glsl->uniforms[0];
   }

#ifdef HAVE_SHADERPIPELINE
#ifdef HAVE_OPENGLES
   if (gl_query_extension("GL_OES_standard_derivatives"))
   {
      shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy;
      shader_prog_info.fragment = stock_fragment_xmb;
   }
   else
   {
      shader_prog_info.vertex   = stock_vertex_xmb_ribbon_simple_legacy;
      shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple;
   }
#else
      shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_ribbon_modern : stock_vertex_xmb_ribbon_legacy;
      shader_prog_info.fragment = stock_fragment_xmb;
#endif
   shader_prog_info.is_file  = false;

   gl_glsl_compile_program(
         glsl,
         VIDEO_SHADER_MENU,
         &glsl->prg[VIDEO_SHADER_MENU],
         &shader_prog_info);
   gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU].id,
         &glsl->uniforms[VIDEO_SHADER_MENU]);

   shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_simple_modern : stock_vertex_xmb_ribbon_simple_legacy;
   shader_prog_info.fragment = stock_fragment_xmb_ribbon_simple;

   gl_glsl_compile_program(
         glsl,
         VIDEO_SHADER_MENU_2,
         &glsl->prg[VIDEO_SHADER_MENU_2],
         &shader_prog_info);
   gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_2].id,
         &glsl->uniforms[VIDEO_SHADER_MENU_2]);

#if defined(HAVE_OPENGLES)
   shader_prog_info.vertex   = stock_vertex_xmb_snow_modern;
#else
   shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy;
#endif
   shader_prog_info.fragment = stock_fragment_xmb_simple_snow;

   gl_glsl_compile_program(
         glsl,
         VIDEO_SHADER_MENU_3,
         &glsl->prg[VIDEO_SHADER_MENU_3],
         &shader_prog_info);
   gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_3].id,
         &glsl->uniforms[VIDEO_SHADER_MENU_3]);

#if defined(HAVE_OPENGLES)
   shader_prog_info.vertex   = stock_vertex_xmb_snow_modern;
#else
   shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy;
#endif
   shader_prog_info.fragment = stock_fragment_xmb_snow;

   gl_glsl_compile_program(
         glsl,
         VIDEO_SHADER_MENU_4,
         &glsl->prg[VIDEO_SHADER_MENU_4],
         &shader_prog_info);
   gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_4].id,
         &glsl->uniforms[VIDEO_SHADER_MENU_4]);

#if defined(HAVE_OPENGLES)
   shader_prog_info.vertex   = stock_vertex_xmb_snow_modern;
#else
   shader_prog_info.vertex   = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy;
#endif
   shader_prog_info.fragment = stock_fragment_xmb_bokeh;

   gl_glsl_compile_program(
         glsl,
         VIDEO_SHADER_MENU_5,
         &glsl->prg[VIDEO_SHADER_MENU_5],
         &shader_prog_info);
   gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_5].id,
         &glsl->uniforms[VIDEO_SHADER_MENU_5]);
#endif

   gl_glsl_reset_attrib(glsl);

   for (i = 0; i < GFX_MAX_SHADERS; i++)
   {
      glGenBuffers(1, &glsl->vbo[i].vbo_primary);
      glGenBuffers(1, &glsl->vbo[i].vbo_secondary);
   }

   return glsl;

error:
   gl_glsl_destroy_resources(glsl);

   if (conf)
      config_file_free(conf);
   if (glsl)
      free(glsl);

   return NULL;
}
Esempio n. 20
0
bool gl_glsl_init(const char *path)
{
#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__)
   // Load shader functions.
   LOAD_GL_SYM(CreateProgram);
   LOAD_GL_SYM(UseProgram);
   LOAD_GL_SYM(CreateShader);
   LOAD_GL_SYM(DeleteShader);
   LOAD_GL_SYM(ShaderSource);
   LOAD_GL_SYM(CompileShader);
   LOAD_GL_SYM(AttachShader);
   LOAD_GL_SYM(DetachShader);
   LOAD_GL_SYM(LinkProgram);
   LOAD_GL_SYM(GetUniformLocation);
   LOAD_GL_SYM(Uniform1i);
   LOAD_GL_SYM(Uniform1f);
   LOAD_GL_SYM(Uniform2fv);
   LOAD_GL_SYM(Uniform4fv);
   LOAD_GL_SYM(UniformMatrix4fv);
   LOAD_GL_SYM(GetShaderiv);
   LOAD_GL_SYM(GetShaderInfoLog);
   LOAD_GL_SYM(GetProgramiv);
   LOAD_GL_SYM(GetProgramInfoLog);
   LOAD_GL_SYM(DeleteProgram);
   LOAD_GL_SYM(GetAttachedShaders);
   LOAD_GL_SYM(GetAttribLocation);
   LOAD_GL_SYM(EnableVertexAttribArray);
   LOAD_GL_SYM(DisableVertexAttribArray);
   LOAD_GL_SYM(VertexAttribPointer);

   RARCH_LOG("Checking GLSL shader support ...\n");
   bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader
      && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader
      && pglDetachShader && pglLinkProgram && pglGetUniformLocation
      && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv
      && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog 
      && pglDeleteProgram && pglGetAttachedShaders
      && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray
      && pglVertexAttribPointer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      return false;
   }
#endif

   unsigned num_progs = 0;
   struct shader_program progs[RARCH_GLSL_MAX_SHADERS] = {{0}};
   if (path)
   {
      num_progs = get_xml_shaders(path, progs, RARCH_GLSL_MAX_SHADERS - 1);

      if (num_progs == 0)
      {
         RARCH_ERR("Couldn't find any valid shaders in XML file.\n");
         return false;
      }
   }
   else
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      num_progs = 1;
      progs[0].vertex   = strdup(stock_vertex_modern);
      progs[0].fragment = strdup(stock_fragment_modern);
      glsl_modern       = true;
   }

#ifdef HAVE_OPENGLES2
   if (!glsl_modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      return false;
   }
#endif

   struct shader_program stock_prog = {0};
   stock_prog.vertex   = strdup(glsl_modern ? stock_vertex_modern   : stock_vertex_legacy);
   stock_prog.fragment = strdup(glsl_modern ? stock_fragment_modern : stock_fragment_legacy);

   if (!compile_programs(&gl_program[0], &stock_prog, 1))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      return false;
   }

   for (unsigned i = 0; i < num_progs; i++)
   {
      gl_filter_type[i + 1]   = progs[i].filter;
      gl_scale[i + 1].type_x  = progs[i].type_x;
      gl_scale[i + 1].type_y  = progs[i].type_y;
      gl_scale[i + 1].scale_x = progs[i].scale_x;
      gl_scale[i + 1].scale_y = progs[i].scale_y;
      gl_scale[i + 1].abs_x   = progs[i].abs_x;
      gl_scale[i + 1].abs_y   = progs[i].abs_y;
      gl_scale[i + 1].valid   = progs[i].valid_scale;
   }

   if (!compile_programs(&gl_program[1], progs, num_progs))
      return false;

   // RetroArch custom two-pass with two different files.
   if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
   {
      unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1);
      if (secondary_progs == 1)
      {
         if (!compile_programs(&gl_program[2], progs, 1))
         {
            RARCH_ERR("Failed to compile second pass shader.\n");
            return false;
         }

         num_progs++;
      }
      else
      {
         RARCH_ERR("Did not find exactly one valid shader in secondary shader file.\n");
         return false;
      }
   }

   for (unsigned i = 0; i <= num_progs; i++)
      find_uniforms(gl_program[i], &gl_uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error())
      RARCH_WARN("Detected GL error in GLSL.\n");
#endif

   if (gl_tracker_info_cnt > 0)
   {
      struct state_tracker_info info = {0};
      info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
      info.info      = gl_tracker_info;
      info.info_elem = gl_tracker_info_cnt;

#ifdef HAVE_PYTHON
      info.script = gl_script_program;
      info.script_class   = *gl_tracker_script_class ? gl_tracker_script_class : NULL;
      info.script_is_file = false;
#endif

      gl_state_tracker = state_tracker_init(&info);
      if (!gl_state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }
   
   glsl_enable                      = true;
   gl_num_programs                  = num_progs;
   gl_program[gl_num_programs + 1]  = gl_program[0];
   gl_uniforms[gl_num_programs + 1] = gl_uniforms[0];

   gl_glsl_reset_attrib();

   return true;
}
Esempio n. 21
0
static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
#ifdef _WIN32
   gfx_set_dwm();
#endif

#ifdef RARCH_CONSOLE
   if (driver.video_data)
      return driver.video_data;
#endif

   gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t));
   if (!gl)
      return NULL;

   if (!gfx_ctx_init())
   {
      free(gl);
      return NULL;
   }

   unsigned full_x = 0, full_y = 0;
   gfx_ctx_get_video_size(&full_x, &full_y);
   RARCH_LOG("Detecting resolution %ux%u.\n", full_x, full_y);

   gfx_ctx_set_swap_interval(video->vsync ? 1 : 0, false);

   unsigned win_width = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      win_width = full_x;
      win_height = full_y;
   }

   if (!gfx_ctx_set_video_mode(win_width, win_height,
            g_settings.video.force_16bit ? 15 : 0, video->fullscreen))
   {
      free(gl);
      return NULL;
   }

#ifndef RARCH_CONSOLE
   gfx_ctx_update_window_title(true);

   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif

#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32)
   // Win32 GL lib doesn't have some functions needed for XML shaders.
   // Need to load dynamically :(
   if (!load_gl_proc())
   {
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }
#endif

   gl->vsync = video->vsync;
   gl->fullscreen = video->fullscreen;
   
   gl->full_x = full_x;
   gl->full_y = full_y;
   gl->win_width = win_width;
   gl->win_height = win_height;

   RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);

#if defined(HAVE_CG_MENU) && defined(RARCH_CONSOLE)
   RARCH_LOG("Initializing menu shader ...\n");
   gl_cg_set_menu_shader(default_paths.menu_shader_file);
#endif

   if (!gl_shader_init())
   {
      RARCH_ERR("Shader init failed.\n");
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }

   RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num());

#ifdef HAVE_FBO
   // Set up render to texture.
   gl_init_fbo(gl, RARCH_SCALE_BASE * video->input_scale,
         RARCH_SCALE_BASE * video->input_scale);
#endif
   
   gl->keep_aspect = video->force_aspect;

   // Apparently need to set viewport for passes when we aren't using FBOs.
   gl_shader_use(0);
   gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
   gl_shader_use(1);
   gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);

   bool force_smooth = false;
   if (gl_shader_filter_type(1, &force_smooth))
      gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST;
   else
      gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST;

   gl->texture_type = RARCH_GL_TEXTURE_TYPE;
   gl->texture_fmt = video->rgb32 ? RARCH_GL_FORMAT32 : RARCH_GL_FORMAT16;
   gl->base_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);

   glEnable(GL_TEXTURE_2D);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_DITHER);
   glClearColor(0, 0, 0, 1);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);
   glVertexPointer(2, GL_FLOAT, 0, vertex_ptr);

   memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords));
   glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords);
   glColorPointer(4, GL_FLOAT, 0, white_color);

   set_lut_texture_coords(tex_coords);

   gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
   gl->tex_h = RARCH_SCALE_BASE * video->input_scale;

#ifdef HAVE_OPENGL_TEXREF
   glGenBuffers(1, &gl->pbo);
   glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, gl->pbo);
   glBufferData(GL_TEXTURE_REFERENCE_BUFFER_SCE,
         gl->tex_w * gl->tex_h * gl->base_size * TEXTURES, NULL, GL_STREAM_DRAW);
#endif

   // Empty buffer that we use to clear out the texture with on res change.
   gl->empty_buf = calloc(gl->tex_w * gl->tex_h, gl->base_size);
   gl_init_textures(gl);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->last_width[i] = gl->tex_w;
      gl->last_height[i] = gl->tex_h;
   }

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->prev_info[i].tex = gl->texture[(gl->tex_index - (i + 1)) & TEXTURES_MASK];
      gl->prev_info[i].input_size[0] = gl->tex_w;
      gl->prev_info[i].tex_size[0] = gl->tex_w;
      gl->prev_info[i].input_size[1] = gl->tex_h;
      gl->prev_info[i].tex_size[1] = gl->tex_h;
      memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords)); 
   }

   gfx_ctx_input_driver(input, input_data);
   gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
      
   if (!gl_check_error())
   {
      gfx_ctx_destroy();
      free(gl);
      return NULL;
   }

   return gl;
}
Esempio n. 22
0
static bool gl_glsl_init(void *data, const char *path)
{
    unsigned i;
    config_file_t *conf        = NULL;
    glsl_shader_data_t *glsl   = NULL;
    const char *stock_vertex   = NULL;
    const char *stock_fragment = NULL;
    driver_t *driver           = driver_get_ptr();

    (void)data;

    glsl = (glsl_shader_data_t*)calloc(1, sizeof(glsl_shader_data_t));

    if (!glsl)
        return false;

#ifndef HAVE_OPENGLES2
    RARCH_LOG("Checking GLSL shader support ...\n");
    bool shader_support = glCreateProgram && glUseProgram && glCreateShader
                          && glDeleteShader && glShaderSource && glCompileShader && glAttachShader
                          && glDetachShader && glLinkProgram && glGetUniformLocation
                          && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
                          && glUniformMatrix4fv
                          && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
                          && glGetProgramInfoLog
                          && glDeleteProgram && glGetAttachedShaders
                          && glGetAttribLocation && glEnableVertexAttribArray
                          && glDisableVertexAttribArray
                          && glVertexAttribPointer
                          && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;

    if (!shader_support)
    {
        RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
        free(glsl);
        return false;
    }
#endif

    glsl->shader = (struct video_shader*)calloc(1, sizeof(*glsl->shader));
    if (!glsl->shader)
    {
        free(glsl);
        return false;
    }

    if (path)
    {
        bool ret;
        const char *path_ext = path_get_extension(path);

        if (!strcmp(path_ext, "glsl"))
        {
            strlcpy(glsl->shader->pass[0].source.path, path,
                    sizeof(glsl->shader->pass[0].source.path));
            glsl->shader->passes = 1;
            glsl->shader->modern = true;
            ret = true;
        }
        else if (!strcmp(path_ext, "glslp"))
        {
            conf = config_file_new(path);
            if (conf)
            {
                ret = video_shader_read_conf_cgp(conf, glsl->shader);
                glsl->shader->modern = true;
            }
            else
                ret = false;
        }
        else
            ret = false;

        if (!ret)
        {
            RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
            free(glsl->shader);
            free(glsl);
            return false;
        }
    }
    else
    {
        RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
        glsl->shader->passes = 1;
        glsl->shader->pass[0].source.string.vertex   =
            strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
        glsl->shader->pass[0].source.string.fragment =
            strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
        glsl->shader->modern = true;
    }

    video_shader_resolve_relative(glsl->shader, path);
    video_shader_resolve_parameters(conf, glsl->shader);

    if (conf)
    {
        config_file_free(conf);
        conf = NULL;
    }

    stock_vertex = (glsl->shader->modern) ?
                   stock_vertex_modern : stock_vertex_legacy;
    stock_fragment = (glsl->shader->modern) ?
                     stock_fragment_modern : stock_fragment_legacy;

    if (glsl_core)
    {
        stock_vertex = stock_vertex_core;
        stock_fragment = stock_fragment_core;
    }

#ifdef HAVE_OPENGLES2
    if (!glsl->shader->modern)
    {
        RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
        goto error;
    }
#else
    if (glsl_core && !glsl->shader->modern)
    {
        RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n");
        goto error;
    }
#endif

    /* Find all aliases we use in our GLSLP and add #defines for them so
     * that a shader can choose a fallback if we are not using a preset. */
    *glsl->glsl_alias_define = '\0';
    for (i = 0; i < glsl->shader->passes; i++)
    {
        if (*glsl->shader->pass[i].alias)
        {
            char define[128] = {0};

            snprintf(define, sizeof(define), "#define %s_ALIAS\n",
                     glsl->shader->pass[i].alias);
            strlcat(glsl->glsl_alias_define, define, sizeof(glsl->glsl_alias_define));
        }
    }

    if (!(glsl->gl_program[0] = compile_program(glsl, stock_vertex, stock_fragment, 0)))
    {
        RARCH_ERR("GLSL stock programs failed to compile.\n");
        goto error;
    }

    if (!compile_programs(glsl, &glsl->gl_program[1]))
        goto error;

    if (!gl_load_luts(glsl->shader, glsl->gl_teximage))
    {
        RARCH_ERR("[GL]: Failed to load LUTs.\n");
        goto error;
    }

    for (i = 0; i <= glsl->shader->passes; i++)
        find_uniforms(glsl, i, glsl->gl_program[i], &glsl->gl_uniforms[i]);

#ifdef GLSL_DEBUG
    if (!gl_check_error())
        RARCH_WARN("Detected GL error in GLSL.\n");
#endif

    if (glsl->shader->variables)
    {
        struct state_tracker_info info = {0};

        info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
        info.info      = glsl->shader->variable;
        info.info_elem = glsl->shader->variables;

#ifdef HAVE_PYTHON
        info.script = glsl->shader->script;
        info.script_class = *glsl->shader->script_class ?
                            glsl->shader->script_class : NULL;
#endif

        glsl->gl_state_tracker = state_tracker_init(&info);
        if (!glsl->gl_state_tracker)
            RARCH_WARN("Failed to init state tracker.\n");
    }

    glsl->gl_program[glsl->shader->passes  + 1] = glsl->gl_program[0];
    glsl->gl_uniforms[glsl->shader->passes + 1] = glsl->gl_uniforms[0];

    if (glsl->shader->modern)
    {
        glsl->gl_program[GL_SHADER_STOCK_BLEND] = compile_program(
                    glsl,
                    glsl_core ?
                    stock_vertex_core_blend : stock_vertex_modern_blend,
                    glsl_core ?
                    stock_fragment_core_blend : stock_fragment_modern_blend,
                    GL_SHADER_STOCK_BLEND);
        find_uniforms(glsl, 0, glsl->gl_program[GL_SHADER_STOCK_BLEND],
                      &glsl->gl_uniforms[GL_SHADER_STOCK_BLEND]);
    }
    else
    {
        glsl->gl_program [GL_SHADER_STOCK_BLEND] = glsl->gl_program[0];
        glsl->gl_uniforms[GL_SHADER_STOCK_BLEND] = glsl->gl_uniforms[0];
    }

    gl_glsl_reset_attrib(glsl);

    for (i = 0; i < GFX_MAX_SHADERS; i++)
    {
        glGenBuffers(1, &glsl->glsl_vbo[i].vbo_primary);
        glGenBuffers(1, &glsl->glsl_vbo[i].vbo_secondary);
    }

    driver->video_shader_data = glsl;

    return true;

error:
    gl_glsl_destroy_resources(glsl);

    if (glsl)
        free(glsl);

    return false;
}
Esempio n. 23
0
    void on_draw() override
    {
        glfwMakeContextCurrent(window);

        if (igm) igm->begin_frame();

        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(1.0f, 0.1f, 0.0f, 1.0f);

        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);

        ImGui::SliderFloat("Projectile Velocity", &turret.velocity, 0.f, 100.f);

        if (ImGui::Button("Fire"))
        {
            turret.projectile = BallisticProjectile();
            turret.projectile.p = turret.source.pose;
            turret.projectile.lastPos = turret.source.pose.position;
            turret.projectile.gravity = 0.0;

            /*
            float3 firingSolutionLow;
            float3 firingSolutionHigh;
            auto numSolutions = solve_ballistic_arc(turret.source.pose.position, turret.velocity, turret.target.pose.position, 9.8f, firingSolutionLow, firingSolutionHigh);
            */

            float3 fireVelocity;
            float gravity;
            auto canFire = solve_ballistic_arc_lateral(turret.source.pose.position, turret.velocity, turret.target.pose.position, 10.f, fireVelocity, gravity);

            //std::cout << "Num Solutions: " << numSolutions << std::endl;
            //std::cout << "Low Solution: " << firingSolutionLow << std::endl;
            std::cout << "Fire Velocity: " << fireVelocity << std::endl;

            if (canFire)
            {
                turret.projectile.gravity = gravity;
                turret.projectile.add_impulse(fireVelocity);
                turret.fired = true;
            }
        }

        ImGui::Spacing();

        if (ImGui::SliderInt("M", &ssM, 1, 30)) regeneratePointer = true;
        if (ImGui::SliderInt("N1", &ssN1, 1, 30)) regeneratePointer = true;
        if (ImGui::SliderInt("N2", &ssN2, 1, 30)) regeneratePointer = true;
        if (ImGui::SliderInt("N3", &ssN3, 1, 30)) regeneratePointer = true;

        ImGui::Spacing();

        ImGui::BeginGroup();

        if (ImGui::SliderFloat3("Position", &params.position.x, -5, 5))
            parabolicPointer = make_parabolic_pointer(worldSurface, params);

        if (ImGui::SliderFloat3("Velocity", &params.velocity.x, -1.f, 1.f))
            parabolicPointer = make_parabolic_pointer(worldSurface, params);

        if (ImGui::SliderFloat("Point Spacing", &params.pointSpacing, 0.5, 2.0))
            parabolicPointer = make_parabolic_pointer(worldSurface, params);

        if (ImGui::SliderFloat("Point Count", &params.pointCount, 16, 64))
            parabolicPointer = make_parabolic_pointer(worldSurface, params);

        ImGui::EndGroup();

        const auto proj = camera.get_projection_matrix((float) width / (float) height);
        const float4x4 view = camera.get_view_matrix();
        const float4x4 viewProj = mul(proj, view);

        glViewport(0, 0, width, height);

        skydome.render(viewProj, camera.get_eye_point(), camera.farClip);
        grid.render(proj, view);

        {
            simpleShader->bind();

            simpleShader->uniform("u_eye", camera.get_eye_point());
            simpleShader->uniform("u_viewProj", viewProj);

            simpleShader->uniform("u_emissive", float3(0, 0, 0));
            simpleShader->uniform("u_diffuse", float3(0.0f, 1.0f, 0.0f));

            for (int i = 0; i < 2; i++)
            {
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].position", lights[i].position);
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].color", lights[i].color);
            }

            for (const auto & model : shadedModels)
            {
                simpleShader->uniform("u_modelMatrix", model.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }

            {
                simpleShader->uniform("u_modelMatrix", turret.source.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(turret.source.get_model())));
                turret.source.draw();

                simpleShader->uniform("u_modelMatrix", turret.target.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(turret.target.get_model())));
                turret.target.draw();

                auto projectileMat = turret.projectile.p.matrix();
                simpleShader->uniform("u_modelMatrix", projectileMat);
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(projectileMat)));
                turret.bullet.draw();
            }

            simpleShader->unbind();
        }

        {
            normalDebugShader->bind();
            normalDebugShader->uniform("u_viewProj", viewProj);

            // Some debug models
            for (const auto & model : debugModels)
            {
                normalDebugShader->uniform("u_modelMatrix", model.get_model());
                normalDebugShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }

            // Supershape
            {
                normalDebugShader->uniform("u_modelMatrix", supershape.get_model());
                normalDebugShader->uniform("u_modelMatrixIT", inv(transpose(supershape.get_model())));
                supershape.draw();
            }

            // Parabolic pointer
            {
                normalDebugShader->uniform("u_modelMatrix", parabolicPointer.get_model());
                normalDebugShader->uniform("u_modelMatrixIT", inv(transpose(parabolicPointer.get_model())));
                parabolicPointer.draw();
            }

            // Parallel transport boxes
            for (int i = 0; i < ptfBoxes.size(); ++i)
            {
                auto & model = ptfBoxes[i];
                auto modelMat = ptf[i];
                normalDebugShader->uniform("u_modelMatrix", mul(modelMat, make_scaling_matrix(0.01)));
                normalDebugShader->uniform("u_modelMatrixIT", inv(transpose(modelMat)));
                model.draw();
            }

            normalDebugShader->unbind();
        }

        gl_check_error(__FILE__, __LINE__);
        if (igm) igm->end_frame();
        glfwSwapBuffers(window);
        frameCount++;
    }
Esempio n. 24
0
int gl_shader_check_error(GLhandleARB obj, GLenum obj_query, GLSLCheckMode m, const char *file, const int line)
{
	GLsizei length;
	GLcharARB buffer[255];
	GLenum glerr;
	GLint  param;
	int    res=0;

	glerr = gl_check_error(m, file, line);

	if(!obj)
		return glerr;

	if(obj_query != GL_OBJECT_TYPE_ARB            &&
		obj_query != GL_OBJECT_DELETE_STATUS_ARB   &&
		obj_query != GL_OBJECT_COMPILE_STATUS_ARB  &&
		obj_query != GL_OBJECT_LINK_STATUS_ARB     &&
		obj_query != GL_OBJECT_VALIDATE_STATUS_ARB
		)
	{
		osd_printf_warning("%s:%d: GL Error: gl_shader_check_error unsupported object query 0x%X\n", file, line, (unsigned int)obj_query);
		return -1;
	}

	pfn_glGetObjectParameterivARB(obj, obj_query, &param);

	switch(obj_query)
	{
		case GL_OBJECT_TYPE_ARB:
		if( param!=GL_PROGRAM_OBJECT_ARB && param!=GL_SHADER_OBJECT_ARB )
		{
			if ( CHECK_VERBOSE <= m )
				osd_printf_warning("%s:%d: GL Error: object type 0x%X generation failed\n", file, line, (unsigned int)(FPTR)obj);
			res=-1;
		} else if ( CHECK_ALWAYS_VERBOSE <= m )
		{
			if(param==GL_PROGRAM_OBJECT_ARB)
				osd_printf_warning("%s:%d: GL Error: object type 0x%X is PROGRAM, successful\n", file, line, (unsigned int)(FPTR)obj);
			else
				osd_printf_warning("%s:%d: GL Info: object type 0x%X is SHADER, successful\n", file, line, (unsigned int)(FPTR)obj);
		}
		break;
		case GL_OBJECT_DELETE_STATUS_ARB:
		if(param!=1)
		{
			if ( CHECK_ALWAYS_VERBOSE <= m )
				osd_printf_warning("%s:%d: GL Info: object 0x%X not yet marked for deletion\n", file, line, (unsigned int)(FPTR)obj);
		} else if ( CHECK_ALWAYS_VERBOSE <= m )
		{
			osd_printf_warning("%s:%d: GL Info: object 0x%X deletion successful\n", file, line, (unsigned int)(FPTR)obj);
		}
		break;
		case GL_OBJECT_COMPILE_STATUS_ARB:
		if(param!=1)
		{
			if ( CHECK_VERBOSE <= m )
				osd_printf_warning("%s:%d: GL Error: object 0x%X compilation failed\n", file, line, (unsigned int)(FPTR)obj);
			res=-1;
		} else if ( CHECK_ALWAYS_VERBOSE <= m )
		{
			osd_printf_warning("%s:%d: GL Info: object 0x%X compiled successful\n", file, line, (unsigned int)(FPTR)obj);
		}
		break;
		case GL_OBJECT_LINK_STATUS_ARB:
		if(param!=1)
		{
			if ( CHECK_VERBOSE <= m )
				osd_printf_warning("%s:%d: GL Error: object 0x%X linking failed\n", file, line, (unsigned int)(FPTR)obj);
			res=-1;
		} else if ( CHECK_ALWAYS_VERBOSE <= m )
		{
			osd_printf_warning("%s:%d: GL Info: object 0x%X linked successful\n", file, line, (unsigned int)(FPTR)obj);
		}
		break;
		case GL_OBJECT_VALIDATE_STATUS_ARB:
		if(param!=1)
		{
			if ( CHECK_VERBOSE <= m )
				osd_printf_warning("%s:%d: GL Error: object 0x%X validation failed\n", file, line, (unsigned int)(FPTR)obj);
			res=-1;
		} else if ( CHECK_ALWAYS_VERBOSE <= m )
		{
			osd_printf_warning("%s:%d: GL Info: object 0x%X validation successful\n", file, line, (unsigned int)(FPTR)obj);
		}
		break;
		}

	if ( res<0 || CHECK_ALWAYS_VERBOSE <= m )
	{
		length=0;
		pfn_glGetInfoLogARB(obj, sizeof(buffer), &length, buffer);
		if(length>0)
			osd_printf_warning("%s:%d glInfoLog: %s\n", file, line, buffer);
	}

	(void) glGetError(); // ;-)


	return res;
}
Esempio n. 25
0
static bool gl_glsl_init(void *data, const char *path)
{
   unsigned i;
   (void)data;
#ifndef HAVE_OPENGLES2
   RARCH_LOG("Checking GLSL shader support ...\n");
   bool shader_support = glCreateProgram && glUseProgram && glCreateShader
      && glDeleteShader && glShaderSource && glCompileShader && glAttachShader
      && glDetachShader && glLinkProgram && glGetUniformLocation
      && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv && glUniformMatrix4fv
      && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv && glGetProgramInfoLog 
      && glDeleteProgram && glGetAttachedShaders
      && glGetAttribLocation && glEnableVertexAttribArray && glDisableVertexAttribArray
      && glVertexAttribPointer
      && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      return false;
   }
#endif

   glsl_shader = (struct gfx_shader*)calloc(1, sizeof(*glsl_shader));
   if (!glsl_shader)
      return false;

   if (path)
   {
      bool ret;
      if (strcmp(path_get_extension(path), "glsl") == 0)
      {
         strlcpy(glsl_shader->pass[0].source.cg, path, sizeof(glsl_shader->pass[0].source.cg));
         glsl_shader->passes = 1;
         glsl_shader->modern = true;
         ret = true;
      }
      else if (strcmp(path_get_extension(path), "glslp") == 0)
      {
         config_file_t *conf = config_file_new(path);
         if (conf)
         {
            ret = gfx_shader_read_conf_cgp(conf, glsl_shader);
            glsl_shader->modern = true;
            config_file_free(conf);
         }
         else
            ret = false;
      }
      else
         ret = gfx_shader_read_xml(path, glsl_shader);

      if (!ret)
      {
         RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
         return false;
      }
   }
   else
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      glsl_shader->passes = 1;
      glsl_shader->pass[0].source.xml.vertex   = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
      glsl_shader->pass[0].source.xml.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
      glsl_shader->modern = true;
   }

   gfx_shader_resolve_relative(glsl_shader, path);

   const char *stock_vertex = glsl_shader->modern ?
      stock_vertex_modern : stock_vertex_legacy;
   const char *stock_fragment = glsl_shader->modern ?
      stock_fragment_modern : stock_fragment_legacy;

   if (glsl_core)
   {
      stock_vertex = stock_vertex_core;
      stock_fragment = stock_fragment_core;
   }

#ifdef HAVE_OPENGLES2
   if (!glsl_shader->modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      goto error;
   }
#else
   if (glsl_core && !glsl_shader->modern)
   {
      RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n");
      goto error;
   }
#endif

   if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0)))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      goto error;
   }

   if (!compile_programs(&gl_program[1]))
      goto error;

   if (!gl_load_luts(glsl_shader, gl_teximage))
   {
      RARCH_ERR("[GL]: Failed to load LUTs.\n");
      goto error;
   }

   for (i = 0; i <= glsl_shader->passes; i++)
      find_uniforms(i, gl_program[i], &gl_uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error())
      RARCH_WARN("Detected GL error in GLSL.\n");
#endif

   if (glsl_shader->variables)
   {
      struct state_tracker_info info = {0};
      info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
      info.info      = glsl_shader->variable;
      info.info_elem = glsl_shader->variables;

#ifdef HAVE_PYTHON
      info.script = glsl_shader->script;
      info.script_class = *glsl_shader->script_class ?
         glsl_shader->script_class : NULL;
#endif

      gl_state_tracker = state_tracker_init(&info);
      if (!gl_state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }
   
   glsl_enable = true;
   gl_program[glsl_shader->passes  + 1] = gl_program[0];
   gl_uniforms[glsl_shader->passes + 1] = gl_uniforms[0];

   if (glsl_shader->modern)
   {
      gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend,
            glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);
      find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
   }
   else
   {
      gl_program[GL_SHADER_STOCK_BLEND] = gl_program[0];
      gl_uniforms[GL_SHADER_STOCK_BLEND] = gl_uniforms[0];
   }

   gl_glsl_reset_attrib();

   for (i = 0; i < GFX_MAX_SHADERS; i++)
   {
      glGenBuffers(1, &glsl_vbo[i].vbo_primary);
      glGenBuffers(1, &glsl_vbo[i].vbo_secondary);
   }

   return true;

error:
   gl_glsl_deinit();
   return false;
}
Esempio n. 26
0
    ExperimentalApp() : GLFWApp(1280, 800, "Geometric Algorithm Development App")
    {
        glfwSwapInterval(0);

        igm.reset(new gui::ImGuiManager(window));
        gui::make_dark_theme();

        fixedTimer.start();

        lights[0] = {{0, 10, -10}, {0, 0, 1}};
        lights[1] = {{0, 10, 10}, {0, 1, 0}};

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);

        grid = RenderableGrid(1, 100, 100);
        cameraController.set_camera(&camera);
        camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0});

        simpleShader = make_watched_shader(shaderMonitor, "../assets/shaders/simple_vert.glsl", "assets/shaders/simple_frag.glsl");
        normalDebugShader = make_watched_shader(shaderMonitor, "../assets/shaders/normal_debug_vert.glsl", "assets/shaders/normal_debug_frag.glsl");

        Renderable debugAxis = Renderable(make_axis(), false, GL_LINES);
        debugAxis.pose = Pose(float4(0, 0, 0, 1), float3(0, 1, 0));
        debugModels.push_back(std::move(debugAxis));

        // Initial supershape settings
        supershape = Renderable(make_supershape_3d(16, 5, 7, 4, 12));
        supershape.pose.position = {0, 2, -2};

        // Initialize PTF stuff
        {
            std::array<float3, 4> controlPoints = {float3(0.0f, 0.0f, 0.0f), float3(0.667f, 0.25f, 0.0f), float3(1.33f, 0.25f, 0.0f), float3(2.0f, 0.0f, 0.0f)};
            ptf = make_parallel_transport_frame_bezier(controlPoints, 32);

            for (int i = 0; i < ptf.size(); ++i)
            {
                Renderable p = Renderable(make_cube());
                ptfBoxes.push_back(std::move(p));
            }
        }

        // Initialize Parabolic pointer stuff
        {
            // Set up the ground plane used as a nav mesh for the parabolic pointer
            worldSurface = make_plane(48, 48, 96, 96);
            for (auto & p : worldSurface.vertices)
            {
                float4x4 model = make_rotation_matrix({1, 0, 0}, -ANVIL_PI / 2);
                p = transform_coord(model, p);
            }
            worldSurfaceRenderable = Renderable(worldSurface);

            parabolicPointer = make_parabolic_pointer(worldSurface, params);
        }

        // Initialize objects for ballistic trajectory tests
        {
            turret.source = Renderable(make_tetrahedron());
            turret.source.pose = Pose({-5, 2, 5});

            turret.target = Renderable(make_cube());
            turret.target.pose = Pose({0, 0, 40});

            turret.bullet = Renderable(make_sphere(1.0f));
        }

        float4x4 tMat = mul(make_translation_matrix({3, 4, 5}), make_rotation_matrix({0, 0, 1}, ANVIL_PI / 2));
        auto p = make_pose_from_transform_matrix(tMat);
        std::cout << tMat << std::endl;
        std::cout << p << std::endl;

        gl_check_error(__FILE__, __LINE__);
    }
Esempio n. 27
0
static bool gl_glsl_init(const char *path)
{
#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__)
   // Load shader functions.
   LOAD_GL_SYM(CreateProgram);
   LOAD_GL_SYM(UseProgram);
   LOAD_GL_SYM(CreateShader);
   LOAD_GL_SYM(DeleteShader);
   LOAD_GL_SYM(ShaderSource);
   LOAD_GL_SYM(CompileShader);
   LOAD_GL_SYM(AttachShader);
   LOAD_GL_SYM(DetachShader);
   LOAD_GL_SYM(LinkProgram);
   LOAD_GL_SYM(GetUniformLocation);
   LOAD_GL_SYM(Uniform1i);
   LOAD_GL_SYM(Uniform1f);
   LOAD_GL_SYM(Uniform2fv);
   LOAD_GL_SYM(Uniform4fv);
   LOAD_GL_SYM(UniformMatrix4fv);
   LOAD_GL_SYM(GetShaderiv);
   LOAD_GL_SYM(GetShaderInfoLog);
   LOAD_GL_SYM(GetProgramiv);
   LOAD_GL_SYM(GetProgramInfoLog);
   LOAD_GL_SYM(DeleteProgram);
   LOAD_GL_SYM(GetAttachedShaders);
   LOAD_GL_SYM(GetAttribLocation);
   LOAD_GL_SYM(EnableVertexAttribArray);
   LOAD_GL_SYM(DisableVertexAttribArray);
   LOAD_GL_SYM(VertexAttribPointer);

   RARCH_LOG("Checking GLSL shader support ...\n");
   bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader
      && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader
      && pglDetachShader && pglLinkProgram && pglGetUniformLocation
      && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv
      && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog 
      && pglDeleteProgram && pglGetAttachedShaders
      && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray
      && pglVertexAttribPointer;

   if (!shader_support)
   {
      RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n");
      return false;
   }
#endif

   glsl_shader = (struct gfx_shader*)calloc(1, sizeof(*glsl_shader));
   if (!glsl_shader)
      return false;

   if (path)
   {
      bool ret;
      if (strcmp(path_get_extension(path), "glsl") == 0)
      {
         strlcpy(glsl_shader->pass[0].source.cg, path, sizeof(glsl_shader->pass[0].source.cg));
         glsl_shader->passes = 1;
         glsl_shader->modern = true;
         ret = true;
      }
      else if (strcmp(path_get_extension(path), "glslp") == 0)
      {
         config_file_t *conf = config_file_new(path);
         if (conf)
         {
            ret = gfx_shader_read_conf_cgp(conf, glsl_shader);
            glsl_shader->modern = true;
            config_file_free(conf);
         }
         else
            ret = false;
      }
      else
         ret = gfx_shader_read_xml(path, glsl_shader);

      if (!ret)
      {
         RARCH_ERR("[GL]: Failed to parse GLSL shader.\n");
         return false;
      }
   }
   else
   {
      RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
      glsl_shader->passes = 1;
      glsl_shader->pass[0].source.xml.vertex   = strdup(stock_vertex_modern);
      glsl_shader->pass[0].source.xml.fragment = strdup(stock_fragment_modern);
      glsl_shader->modern = true;
   }

   gfx_shader_resolve_relative(glsl_shader, path);

#ifdef HAVE_OPENGLES2
   if (!glsl_shader->modern)
   {
      RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n");
      return false;
   }
#endif

   const char *stock_vertex = glsl_shader->modern ?
      stock_vertex_modern : stock_vertex_legacy;
   const char *stock_fragment = glsl_shader->modern ?
      stock_fragment_modern : stock_fragment_legacy;

   if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0)))
   {
      RARCH_ERR("GLSL stock programs failed to compile.\n");
      gl_glsl_free_shader();
      return false;
   }

   if (!compile_programs(&gl_program[1]))
   {
      gl_glsl_free_shader();
      return false;
   }

   if (!load_luts())
   {
      RARCH_ERR("[GL]: Failed to load LUTs.\n");
      gl_glsl_free_shader();
      return false;
   }

   for (unsigned i = 0; i <= glsl_shader->passes; i++)
      find_uniforms(gl_program[i], &gl_uniforms[i]);

#ifdef GLSL_DEBUG
   if (!gl_check_error())
      RARCH_WARN("Detected GL error in GLSL.\n");
#endif

   if (glsl_shader->variables)
   {
      struct state_tracker_info info = {0};
      info.wram      = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
      info.info      = glsl_shader->variable;
      info.info_elem = glsl_shader->variables;

#ifdef HAVE_PYTHON
      info.script = glsl_shader->script;
      info.script_class = *glsl_shader->script_class ?
         glsl_shader->script_class : NULL;
#endif

      gl_state_tracker = state_tracker_init(&info);
      if (!gl_state_tracker)
         RARCH_WARN("Failed to init state tracker.\n");
   }
   
   glsl_enable = true;
   gl_program[glsl_shader->passes  + 1] = gl_program[0];
   gl_uniforms[glsl_shader->passes + 1] = gl_uniforms[0];

   if (glsl_shader->modern)
   {
      gl_program[GL_SHADER_STOCK_BLEND] = compile_program(stock_vertex_modern_blend,
            stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);

      find_uniforms(gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
   }
   else
   {
      gl_program[GL_SHADER_STOCK_BLEND] = gl_program[0];
      gl_uniforms[GL_SHADER_STOCK_BLEND] = gl_uniforms[0];
   }

   gl_glsl_reset_attrib();

   return true;
}
Esempio n. 28
0
    ExperimentalApp() : GLFWApp(1280, 720, "Shadow App")
    {
        glfwSwapInterval(0);

        gen = std::mt19937(rd());

        igm.reset(new gui::ImGuiManager(window));
        gui::make_dark_theme();

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);

        cameraController.set_camera(&camera);
        camera.farClip = 55.f;
        camera.look_at({0, 0, +15}, {0, 0, 0});

        // Debugging views
        uiSurface.bounds = {0, 0, (float) width, (float) height};
        uiSurface.add_child( {{0.0000f, +10},{0, +10},{0.1667f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.1667f, +10},{0, +10},{0.3334f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.3334f, +10},{0, +10},{0.5009f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.5000f, +10},{0, +10},{0.6668f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.6668f, +10},{0, +10},{0.8335f, -10},{0.133f, +10}});
        uiSurface.add_child( {{0.8335f, +10},{0, +10},{1.0000f, -10},{0.133f, +10}});
        uiSurface.layout();

        fullscreen_post_quad = make_fullscreen_quad();

        sceneShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/scene_vert.glsl", "assets/shaders/shadow/scene_frag.glsl");
        shadowmapShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/shadowmap_vert.glsl", "assets/shaders/shadow/shadowmap_frag.glsl");
        pointLightShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/point_light_vert.glsl", "assets/shaders/shadow/point_light_frag.glsl");
        gaussianBlurShader = make_watched_shader(shaderMonitor, "assets/shaders/gaussian_blur_vert.glsl", "assets/shaders/gaussian_blur_frag.glsl");

        skydome.recompute(2, 10.f, 1.15f);

        auto lightDir = skydome.get_light_direction();
        sunLight = std::make_shared<DirectionalLight>(lightDir, float3(.50f, .75f, .825f), 64.f);

        // todo spotLightB

        shadowDepthTexture.load_data(shadowmapResolution, shadowmapResolution, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
        shadowFramebuffer.attach(GL_DEPTH_ATTACHMENT, shadowDepthTexture);
        if (!shadowFramebuffer.check_complete()) throw std::runtime_error("incomplete shadow framebuffer");

        shadowBlurTexture.load_data(shadowmapResolution, shadowmapResolution, GL_R32F, GL_RGBA, GL_FLOAT, nullptr);
        shadowBlurFramebuffer.attach(GL_COLOR_ATTACHMENT0, shadowBlurTexture);
        if (!shadowBlurFramebuffer.check_complete()) throw std::runtime_error("incomplete blur framebuffer");

        auto spotLightA = std::make_shared<SpotLight>(float3(0.f, 10.f, 0.f), float3(0.f, -1.f, 0.f), float3(0.766f, 0.766f, 0.005f), 30.0f, float3(1.0f, 0.0f, 0.0001f));
        spotLights.push_back(spotLightA);

        // Single spotlight fbo
        for (int i = 0; i < 1; ++i)
        {
            auto buffer = std::make_shared<SpotLightFramebuffer>();
            buffer->create(shadowmapResolution);
            spotLightFramebuffers.push_back(buffer);
        }

        // Point light init
        {

            pointLight.reset(new PointLight(float3(0.f, 0.f, 0.f), float3(0, 1, 1), float3(1.0f, 0.05f, 0.0002f)));
            pointLightFramebuffer.reset(new PointLightFramebuffer());
            pointLightFramebuffer->create(float2(shadowmapResolution));

            pointLightSphere = std::make_shared<Renderable>(make_sphere(0.5f));
            sceneObjects.push_back(pointLightSphere);
        }

        viewA.reset(new GLTextureView(shadowDepthTexture.get_gl_handle()));
        viewB.reset(new GLTextureView(shadowBlurTexture.get_gl_handle()));
        viewC.reset(new GLTextureView(spotLightFramebuffers[0]->shadowDepthTexture.get_gl_handle()));
        viewD.reset(new GLTextureView(pointLightFramebuffer->depthBuffer.get_gl_handle()));

        auto lucy = load_geometry_from_ply("assets/models/stanford/lucy.ply");

        rescale_geometry(lucy, 8.0f);
        auto lucyBounds = lucy.compute_bounds();

        auto statue = std::make_shared<Renderable>(lucy);
        statue->pose.position = {0, 0, 0};
        //sceneObjects.push_back(statue);

        auto hollowCube = load_geometry_from_ply("assets/models/geometry/CubeHollowOpen.ply");
        for (auto & v : hollowCube.vertices) v *= 0.20f;
        auto hCube = std::make_shared<Renderable>(hollowCube);
        hCube->pose.position = float3(0, 0, 0);
        hCube->pose.orientation = make_rotation_quat_around_x(ANVIL_PI / 2);
        //sceneObjects.push_back(hCube);

        auto curvedMesh = make_curved_plane(2, 1, 8, 8);
        sceneObjects.push_back(std::make_shared<Renderable>(curvedMesh));

        //floor = std::make_shared<Renderable>(make_plane(32.f, 32.f, 64, 64), false);
        //floor->pose.orientation = make_rotation_quat_axis_angle({1, 0, 0}, -ANVIL_PI / 2);
        //floor->pose.position = {0, lucyBounds.min().y, 0};
        //sceneObjects.push_back(floor);

        gl_check_error(__FILE__, __LINE__);
    }
Esempio n. 29
0
    void on_draw() override
    {
        glfwMakeContextCurrent(window);
        
        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);

        int width, height;
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.1f, 0.1f, 0.5f, 1.0f);

        const auto proj = camera.get_projection_matrix((float) width / (float) height);
        const float4x4 view = camera.get_view_matrix();
        const float4x4 viewProj = mul(proj, view);
        
        skydome.render(viewProj, camera.get_eye_point(), camera.farClip);

        // Simple Shader
        {
            simpleShader->bind();
            
            simpleShader->uniform("u_viewProj", viewProj);
            simpleShader->uniform("u_eye", camera.get_eye_point());
            
            simpleShader->uniform("u_emissive", float3(.10f, 0.10f, 0.10f));
            simpleShader->uniform("u_diffuse", float3(0.4f, 0.4f, 0.4f));
            
            for (int i = 0; i < lights.size(); i++)
            {
                auto light = lights[i];
                
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].position", light.pose.position);
                simpleShader->uniform("u_lights[" + std::to_string(i) + "].color", light.color);
            }
            
            for (const auto & model : proceduralModels)
            {
                simpleShader->uniform("u_modelMatrix", model.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }
            
            for (const auto & model : cameraPositions)
            {
                simpleShader->uniform("u_modelMatrix", model.get_model());
                simpleShader->uniform("u_modelMatrixIT", inv(transpose(model.get_model())));
                model.draw();
            }
            gl_check_error(__FILE__, __LINE__);
            
            simpleShader->unbind();
        }
        
        grid.render(proj, view);

        gl_check_error(__FILE__, __LINE__);
        
        glfwSwapBuffers(window);
        
        frameCount++;
    }
Esempio n. 30
0
static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
#ifdef _WIN32
   gfx_set_dwm();
#endif

   if (!sdlwrap_init())
      return NULL;

   const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
   rarch_assert(video_info);
   unsigned full_x = video_info->current_w;
   unsigned full_y = video_info->current_h;
   RARCH_LOG("Detecting desktop resolution %ux%u.\n", full_x, full_y);

   sdlwrap_set_swap_interval(video->vsync ? 1 : 0, false);

   unsigned win_width = video->width;
   unsigned win_height = video->height;
   if (video->fullscreen && (win_width == 0) && (win_height == 0))
   {
      win_width = full_x;
      win_height = full_y;
   }

   if (!sdlwrap_set_video_mode(win_width, win_height,
            g_settings.video.force_16bit ? 15 : 0, video->fullscreen))
      return NULL;

   gfx_window_title_reset();
   char buf[128];
   if (gfx_window_title(buf, sizeof(buf)))
      sdlwrap_wm_set_caption(buf);

   // Remove that ugly mouse :D
   SDL_ShowCursor(SDL_DISABLE);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32)
   // Win32 GL lib doesn't have some functions needed for XML shaders.
   // Need to load dynamically :(
   if (!load_gl_proc())
   {
      sdlwrap_destroy();
      return NULL;
   }
#endif

   gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t));
   if (!gl)
   {
      sdlwrap_destroy();
      return NULL;
   }

   gl->vsync = video->vsync;
   gl->fullscreen = video->fullscreen;
   
   gl->full_x = full_x;
   gl->full_y = full_y;
   gl->win_width = win_width;
   gl->win_height = win_height;

   RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);

   if (!gl_shader_init())
   {
      RARCH_ERR("Shader init failed.\n");
      sdlwrap_destroy();
      free(gl);
      return NULL;
   }

   RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num());

#ifdef HAVE_FBO
   // Set up render to texture.
   gl_init_fbo(gl, RARCH_SCALE_BASE * video->input_scale,
         RARCH_SCALE_BASE * video->input_scale);
#endif
   
   gl->keep_aspect = video->force_aspect;

   // Apparently need to set viewport for passes when we aren't using FBOs.
   gl_shader_use(0);
   set_viewport(gl, gl->win_width, gl->win_height, false, true);
   gl_shader_use(1);
   set_viewport(gl, gl->win_width, gl->win_height, false, true);

   bool force_smooth;
   if (gl_shader_filter_type(1, &force_smooth))
      gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST;
   else
      gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST;

   gl->texture_type = GL_BGRA;
   gl->texture_fmt = video->rgb32 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_SHORT_1_5_5_5_REV;
   gl->base_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);

   glEnable(GL_TEXTURE_2D);
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_DITHER);
   glClearColor(0, 0, 0, 1);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glGenTextures(TEXTURES, gl->texture);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      glBindTexture(GL_TEXTURE_2D, gl->texture[i]);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter);
   }

   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);
   glVertexPointer(2, GL_FLOAT, 0, vertexes_flipped);

   memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords));
   glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords);

   glColorPointer(4, GL_FLOAT, 0, white_color);

   set_lut_texture_coords(tex_coords);

   gl->tex_w = RARCH_SCALE_BASE * video->input_scale;
   gl->tex_h = RARCH_SCALE_BASE * video->input_scale;

   // Empty buffer that we use to clear out the texture with on res change.
   gl->empty_buf = calloc(gl->tex_w * gl->tex_h, gl->base_size);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
      glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);
      glTexImage2D(GL_TEXTURE_2D,
            0, GL_RGBA, gl->tex_w, gl->tex_h, 0, gl->texture_type,
            gl->texture_fmt, gl->empty_buf ? gl->empty_buf : NULL);
   }
   glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->last_width[i] = gl->tex_w;
      gl->last_height[i] = gl->tex_h;
   }

   for (unsigned i = 0; i < TEXTURES; i++)
   {
      gl->prev_info[i].tex = gl->texture[(gl->tex_index - (i + 1)) & TEXTURES_MASK];
      gl->prev_info[i].input_size[0] = gl->tex_w;
      gl->prev_info[i].tex_size[0] = gl->tex_w;
      gl->prev_info[i].input_size[1] = gl->tex_h;
      gl->prev_info[i].tex_size[1] = gl->tex_h;
      memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords)); 
   }

   // Hook up SDL input driver to get SDL_QUIT events and RESIZE.
   sdl_input_t *sdl_input = (sdl_input_t*)input_sdl.init();
   if (sdl_input)
   {
      *input = &input_sdl;
      *input_data = sdl_input;
   }
   else
      *input = NULL;

   gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
      
   if (!gl_check_error())
   {
      sdlwrap_destroy();
      free(gl);
      return NULL;
   }

   return gl;
}