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 | 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 | 3149 | void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) { |
| @@ -3075,3 +3202,6 @@ void HeightfieldRenderer::applyMaterial(const HeightfieldMaterialPointer& materi · 52 unmodified lines | ||
| 3075 | 3202 | } |
| 3076 | 3203 | glBindTexture(GL_TEXTURE_2D, 0); |
| 3077 | 3204 | } |
| 3205 | + | |
| 3206 | +QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs; | |
| 3207 | + | |