Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 6 files). Show all
Unified · Split
| @@ -3016,7 +3016,134 @@ void HeightfieldRenderer::init(Spanner* spanner) { · 3015 unmodified lines | |||
| 3016 | } | 3016 | } |
| 3017 | 3017 | ||
| 3018 | void HeightfieldRenderer::render(const glm::vec4& color, Mode mode) { | 3018 | void HeightfieldRenderer::render(const glm::vec4& color, Mode mode) { |
| 3019 | // create the buffer objects lazily | ||
| 3020 | Heightfield* heightfield = static_cast<Heightfield*>(_spanner); | ||
| 3021 | if (!heightfield->getHeight() || !Menu::getInstance()->isOptionChecked(MenuOption::RenderHeightfields)) { | ||
| 3022 | return; | ||
| 3023 | } | ||
| 3024 | int width = heightfield->getHeight()->getWidth(); | ||
| 3025 | int height = heightfield->getHeight()->getContents().size() / width; | ||
| 3026 | |||
| 3027 | int innerWidth = width - 2 * HeightfieldBuffer::HEIGHT_BORDER; | ||
| 3028 | int innerHeight = height - 2 * HeightfieldBuffer::HEIGHT_BORDER; | ||
| 3029 | int vertexCount = width * height; | ||
| 3030 | int rows = height - 1; | ||
| 3031 | int columns = width - 1; | ||
| 3032 | int indexCount = rows * columns * 3 * 2; | ||
| 3033 | BufferPair& bufferPair = _bufferPairs[IntPair(width, height)]; | ||
| 3034 | if (!bufferPair.first.isCreated()) { | ||
| 3035 | QVector<HeightfieldPoint> vertices(vertexCount); | ||
| 3036 | HeightfieldPoint* point = vertices.data(); | ||
| 3037 | |||
| 3038 | float xStep = 1.0f / (innerWidth - 1); | ||
| 3039 | float zStep = 1.0f / (innerHeight - 1); | ||
| 3040 | float z = -zStep; | ||
| 3041 | float sStep = 1.0f / innerWidth; | ||
| 3042 | float tStep = 1.0f / innerHeight; | ||
| 3043 | float t = -tStep / 2.0f; | ||
| 3044 | for (int i = 0; i < height; i++, z += zStep, t += tStep) { | ||
| 3045 | float x = -xStep; | ||
| 3046 | float s = -sStep / 2.0f; | ||
| 3047 | const float SKIRT_LENGTH = 0.25f; | ||
| 3048 | float baseY = (i == 0 || i == height - 1) ? -SKIRT_LENGTH : 0.0f; | ||
| 3049 | for (int j = 0; j < width; j++, point++, x += xStep, s += sStep) { | ||
| 3050 | point->vertex = glm::vec3(x, (j == 0 || j == width - 1) ? -SKIRT_LENGTH : baseY, z); | ||
| 3051 | point->textureCoord = glm::vec2(s, t); | ||
| 3052 | } | ||
| 3053 | } | ||
| 3054 | |||
| 3055 | bufferPair.first.setUsagePattern(QOpenGLBuffer::StaticDraw); | ||
| 3056 | bufferPair.first.create(); | ||
| 3057 | bufferPair.first.bind(); | ||
| 3058 | bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint)); | ||
| 3059 | |||
| 3060 | QVector<int> indices(indexCount); | ||
| 3061 | int* index = indices.data(); | ||
| 3062 | for (int i = 0; i < rows; i++) { | ||
| 3063 | int lineIndex = i * width; | ||
| 3064 | int nextLineIndex = (i + 1) * width; | ||
| 3065 | for (int j = 0; j < columns; j++) { | ||
| 3066 | *index++ = lineIndex + j; | ||
| 3067 | *index++ = nextLineIndex + j; | ||
| 3068 | *index++ = nextLineIndex + j + 1; | ||
| 3069 | |||
| 3070 | *index++ = nextLineIndex + j + 1; | ||
| 3071 | *index++ = lineIndex + j + 1; | ||
| 3072 | *index++ = lineIndex + j; | ||
| 3073 | } | ||
| 3074 | } | ||
| 3075 | |||
| 3076 | bufferPair.second = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); | ||
| 3077 | bufferPair.second.create(); | ||
| 3078 | bufferPair.second.bind(); | ||
| 3079 | bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int)); | ||
| 3080 | |||
| 3081 | } else { | ||
| 3082 | bufferPair.first.bind(); | ||
| 3083 | bufferPair.second.bind(); | ||
| 3084 | } | ||
| 3085 | glPushMatrix(); | ||
| 3086 | glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z); | ||
| 3087 | glm::vec3 axis = glm::axis(heightfield->getRotation()); | ||
| 3088 | glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z); | ||
| 3089 | glScalef(heightfield->getScale(), heightfield->getScale() * heightfield->getAspectY(), | ||
| 3090 | heightfield->getScale() * heightfield->getAspectZ()); | ||
| 3091 | |||
| 3092 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); | ||
| 3093 | |||
| 3094 | glEnableClientState(GL_VERTEX_ARRAY); | ||
| 3095 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 3096 | |||
| 3097 | HeightfieldPoint* point = 0; | ||
| 3098 | glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); | ||
| 3099 | glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); | ||
| 3100 | |||
| 3101 | glDisable(GL_BLEND); | ||
| 3102 | glEnable(GL_CULL_FACE); | ||
| 3103 | glEnable(GL_ALPHA_TEST); | ||
| 3104 | glAlphaFunc(GL_EQUAL, 0.0f); | ||
| 3105 | |||
| 3106 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | ||
| 3107 | |||
| 3108 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind(); | ||
| 3109 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue( | ||
| 3110 | DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), 1.0f / innerWidth, 1.0f / innerHeight, | ||
| 3111 | 2.0f / (innerWidth * innerHeight)); | ||
| 3112 | if (heightfield->getColor()) { | ||
| 3113 | int colorWidth = heightfield->getColor()->getWidth(); | ||
| 3114 | int colorHeight = heightfield->getColor()->getContents().size() / (colorWidth * DataBlock::COLOR_BYTES); | ||
| 3115 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue( | ||
| 3116 | DefaultMetavoxelRendererImplementation::getBaseColorScaleLocation(), (float)innerWidth / colorWidth, | ||
| 3117 | (float)innerHeight / colorHeight); | ||
| 3118 | } | ||
| 3119 | |||
| 3120 | glBindTexture(GL_TEXTURE_2D, _heightTextureID); | ||
| 3019 | 3121 | ||
| 3122 | glActiveTexture(GL_TEXTURE1); | ||
| 3123 | glBindTexture(GL_TEXTURE_2D, _colorTextureID); | ||
| 3124 | |||
| 3125 | glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); | ||
| 3126 | |||
| 3127 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 3128 | glActiveTexture(GL_TEXTURE0); | ||
| 3129 | |||
| 3130 | glBindTexture(GL_TEXTURE_2D, 0); | ||
| 3131 | |||
| 3132 | DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().release(); | ||
| 3133 | |||
| 3134 | glDisable(GL_ALPHA_TEST); | ||
| 3135 | glDisable(GL_CULL_FACE); | ||
| 3136 | glEnable(GL_BLEND); | ||
| 3137 | |||
| 3138 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
| 3139 | glDisableClientState(GL_VERTEX_ARRAY); | ||
| 3140 | |||
| 3141 | Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); | ||
| 3142 | |||
| 3143 | glPopMatrix(); | ||
| 3144 | |||
| 3145 | bufferPair.first.release(); | ||
| 3146 | bufferPair.second.release(); | ||
| 3020 | } | 3147 | } |
| 3021 | 3148 | ||
| 3022 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { | 3149 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { |
| @@ -3075,3 +3202,6 @@ void HeightfieldRenderer::applyMaterial(const HeightfieldMaterialPointer& materi · 52 unmodified lines | |||
| 3075 | } | 3202 | } |
| 3076 | glBindTexture(GL_TEXTURE_2D, 0); | 3203 | glBindTexture(GL_TEXTURE_2D, 0); |
| 3077 | } | 3204 | } |
| 3205 | |||
| 3206 | QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs; | ||
| 3207 | |||