geometryrenderer.cpp 9.48 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
schultezub's avatar
schultezub committed
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2013, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
schultezub's avatar
schultezub committed
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
schultezub's avatar
schultezub committed
12
// 
13
14
15
16
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
schultezub's avatar
schultezub committed
17
// 
18
19
20
21
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
schultezub's avatar
schultezub committed
22
23
24
25
26
27
28
29
30
31
// 
// ================================================================================================

#include "geometryrenderer.h"

#include "tgt/glmath.h"
#include "tgt/logmanager.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"

32
#include "core/datastructures/imagedata.h"
33
#include "core/datastructures/renderdata.h"
schultezub's avatar
schultezub committed
34
#include "core/datastructures/meshgeometry.h"
35
#include "core/pipeline/processordecoratorshading.h"
schultezub's avatar
schultezub committed
36

schultezub's avatar
schultezub committed
37
namespace campvis {
38
39
40
41
42
43
44
45
46
47
    static const GenericOption<GLenum> renderOptions[7] = {
        GenericOption<GLenum>("points", "GL_POINTS", GL_POINTS),
        GenericOption<GLenum>("lines", "GL_LINES", GL_LINES),
        GenericOption<GLenum>("linestrip", "GL_LINE_STRIP", GL_LINE_STRIP),
        GenericOption<GLenum>("triangles", "GL_TRIANGLES", GL_TRIANGLES),
        GenericOption<GLenum>("trianglefan", "GL_TRIANGLE_FAN", GL_TRIANGLE_FAN),
        GenericOption<GLenum>("trianglestrip", "GL_TRIANGLE_STRIP", GL_TRIANGLE_STRIP),
        GenericOption<GLenum>("polygon", "GL_POLYGON", GL_POLYGON)
    };

schultezub's avatar
schultezub committed
48
    const std::string GeometryRenderer::loggerCat_ = "CAMPVis.modules.vis.GeometryRenderer";
schultezub's avatar
schultezub committed
49

50
51
    GeometryRenderer::GeometryRenderer(IVec2Property* viewportSizeProp)
        : VisualizationProcessor(viewportSizeProp)
52
53
54
        , p_geometryID("geometryID", "Input Geometry ID", "gr.input", DataNameProperty::READ)
        , p_renderTargetID("p_renderTargetID", "Output Image", "gr.output", DataNameProperty::WRITE)
        , p_camera("camera", "Camera")
Sebastian Pölsterl's avatar
Sebastian Pölsterl committed
55
        , p_renderMode("RenderMode", "Render Mode", renderOptions, 7, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES)
56
57
58
59
60
61
62
63
        , p_useSolidColor("UseSolidColor", "Use Solid Color", true, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES)
        , p_solidColor("SolidColor", "Solid Color", tgt::vec4(1.f, .5f, 0.f, 1.f), tgt::vec4(0.f), tgt::vec4(1.f))
        , p_pointSize("PointSize", "Point Size", 3.f, .1f, 10.f)
        , p_lineWidth("LineWidth", "Line Width", 1.f, .1f, 10.f)
        , p_showWireframe("ShowWireframe", "Show Wireframe", true, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_PROPERTIES)
        , p_wireframeColor("WireframeColor", "Wireframe Color", tgt::vec4(1.f, 1.f, 1.f, 1.f), tgt::vec4(0.f), tgt::vec4(1.f))
        , _pointShader(0)
        , _meshShader(0)
schultezub's avatar
schultezub committed
64
    {
65
66
        addDecorator(new ProcessorDecoratorShading());

67
68
69
        addProperty(&p_geometryID);
        addProperty(&p_renderTargetID);
        addProperty(&p_camera);
70
71
72
73
74
75
76
77
78
79

        addProperty(&p_renderMode);

        addProperty(&p_useSolidColor);
        addProperty(&p_solidColor);

        addProperty(&p_pointSize);
        addProperty(&p_lineWidth);
        addProperty(&p_showWireframe);
        addProperty(&p_wireframeColor);
80
81

        decoratePropertyCollection(this);
schultezub's avatar
schultezub committed
82
83
84
85
86
87
88
89
    }

    GeometryRenderer::~GeometryRenderer() {

    }

    void GeometryRenderer::init() {
        VisualizationProcessor::init();
90
        _pointShader = ShdrMgr.load("modules/vis/glsl/geometryrenderer.vert", "modules/vis/glsl/geometryrenderer.frag", generateGlslHeader(false));
91
        _meshShader = ShdrMgr.load("modules/vis/glsl/geometryrenderer.vert", "modules/vis/glsl/geometryrenderer.geom", "modules/vis/glsl/geometryrenderer.frag", generateGlslHeader(true));
schultezub's avatar
schultezub committed
92
93
94
    }

    void GeometryRenderer::deinit() {
95
96
        ShdrMgr.dispose(_pointShader);
        _pointShader = 0;
97
98
99
        ShdrMgr.dispose(_meshShader);
        _meshShader = 0;

schultezub's avatar
schultezub committed
100
101
102
        VisualizationProcessor::deinit();
    }

103
    void GeometryRenderer::updateResult(DataContainer& data) {
104
        ScopedTypedData<GeometryData> proxyGeometry(data, p_geometryID.getValue());
schultezub's avatar
schultezub committed
105

106
107
108
109
110
111
112
113
114
115
116
117
        if (proxyGeometry != 0 && _pointShader != 0 && _meshShader != 0) {
            // select correct shader
            tgt::Shader* leShader = 0;
            if (p_renderMode.getOptionValue() == GL_POINTS || p_renderMode.getOptionValue() == GL_LINES || p_renderMode.getOptionValue() == GL_LINE_STRIP)
                leShader = _pointShader;
            else
                leShader = _meshShader;

            // calculate viewport matrix for NDC -> viewport conversion
            tgt::vec2 halfViewport = tgt::vec2(getEffectiveViewportSize()) / 2.f;
            tgt::mat4 viewportMatrix = tgt::mat4::createTranslation(tgt::vec3(halfViewport, 0.f)) * tgt::mat4::createScale(tgt::vec3(halfViewport, 1.f));

schultezub's avatar
schultezub committed
118
            // set modelview and projection matrices
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
            leShader->activate();
            leShader->setIgnoreUniformLocationError(true);
            decorateRenderProlog(data, leShader);
            leShader->setUniform("_projectionMatrix", p_camera.getValue().getProjectionMatrix());
            leShader->setUniform("_viewMatrix", p_camera.getValue().getViewMatrix());
            leShader->setUniform("_viewportMatrix", viewportMatrix);

            leShader->setUniform("_computeNormals", proxyGeometry->getNormalsBuffer() == 0);

            leShader->setUniform("_useSolidColor", p_useSolidColor.getValue());
            leShader->setUniform("_solidColor", p_solidColor.getValue());
            leShader->setUniform("_wireframeColor", p_wireframeColor.getValue());
            leShader->setUniform("_lineWidth", p_lineWidth.getValue());

            leShader->setUniform("_cameraPosition", p_camera.getValue().getPosition());
            leShader->setIgnoreUniformLocationError(false);

136
137
138
            FramebufferActivationGuard fag(this);
            createAndAttachColorTexture();
            createAndAttachDepthTexture();
schultezub's avatar
schultezub committed
139

140
            glEnable(GL_DEPTH_TEST);
schultezub's avatar
schultezub committed
141
142
143
            glDepthFunc(GL_LESS);
            glClearDepth(1.0f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144
145
            if (p_renderMode.getOptionValue() == GL_POINTS)
                glPointSize(p_pointSize.getValue());
146
147
            else if (p_renderMode.getOptionValue() == GL_LINES || p_renderMode.getOptionValue() == GL_LINE_STRIP)
                glLineWidth(p_lineWidth.getValue());
148

149
            proxyGeometry->render(p_renderMode.getOptionValue());
schultezub's avatar
schultezub committed
150

151
152
            if (p_renderMode.getOptionValue() == GL_POINTS)
                glPointSize(1.f);
153
154
155
            else if (p_renderMode.getOptionValue() == GL_LINES || p_renderMode.getOptionValue() == GL_LINE_STRIP)
                glLineWidth(1.f);

156
157
            decorateRenderEpilog(leShader);
            leShader->deactivate();
158
            glDisable(GL_DEPTH_TEST);
schultezub's avatar
schultezub committed
159
160
            LGL_ERROR;

161
            data.addData(p_renderTargetID.getValue(), new RenderData(_fbo));
schultezub's avatar
schultezub committed
162
163
164
165
166
        }
        else {
            LERROR("No suitable input geometry found.");
        }

167
        validate(INVALID_RESULT);
schultezub's avatar
schultezub committed
168
169
    }

170
    std::string GeometryRenderer::generateGlslHeader(bool hasGeometryShader) const {
171
        std::string toReturn = getDecoratedHeader();
172

173
        if (hasGeometryShader && p_showWireframe.getValue())
174
175
176
177
178
            toReturn += "#define WIREFRAME_RENDERING\n";

        if (hasGeometryShader)
            toReturn += "#define HAS_GEOMETRY_SHADER\n";

179
180
181
        return toReturn;
    }

182
    void GeometryRenderer::updateShader() {
183
184
185
186
        _pointShader->setHeaders(generateGlslHeader(false));
        _pointShader->rebuild();
        _meshShader->setHeaders(generateGlslHeader(true));
        _meshShader->rebuild();
187
188
189
        validate(INVALID_SHADER);
    }

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    void GeometryRenderer::updateProperties(DataContainer& dataContainer) {
        p_solidColor.setVisible(p_useSolidColor.getValue());

        switch (p_renderMode.getOptionValue()) {
            case GL_POINTS:
                p_pointSize.setVisible(true);
                p_lineWidth.setVisible(false);
                p_showWireframe.setVisible(false);
                break;
            case GL_LINES: // fallthrough
            case GL_LINE_STRIP:
                p_pointSize.setVisible(false);
                p_lineWidth.setVisible(true);
                p_showWireframe.setVisible(false);
                break;
            case GL_TRIANGLES: // fallthrough
            case GL_TRIANGLE_FAN: // fallthrough
            case GL_TRIANGLE_STRIP: // fallthrough
            case GL_POLYGON:
                p_pointSize.setVisible(false);
                p_lineWidth.setVisible(p_showWireframe.getValue());
                p_showWireframe.setVisible(true);
                break;
        }

        p_wireframeColor.setVisible(p_showWireframe.getValue());
    }

schultezub's avatar
schultezub committed
218
}