[953] | 1 | |
---|
[825] | 2 | #include "Nv.h" |
---|
| 3 | #include <GL/gl.h> |
---|
| 4 | #include "PointSetRenderer.h" |
---|
| 5 | #include <PCASplit.h> |
---|
[915] | 6 | #include <Image.h> |
---|
| 7 | #include <ImageLoaderFactory.h> |
---|
| 8 | #include <ImageLoader.h> |
---|
[825] | 9 | #include <stdio.h> |
---|
| 10 | #include <R2/R2FilePath.h> |
---|
| 11 | |
---|
[827] | 12 | #define USE_TEXTURE |
---|
| 13 | //#define USE_SHADER |
---|
| 14 | #define POINT_SIZE 5 |
---|
| 15 | |
---|
[825] | 16 | PointSetRenderer::PointSetRenderer() |
---|
| 17 | { |
---|
| 18 | _shader = new PointShader(); |
---|
[1111] | 19 | const char *path = R2FilePath::getInstance()->getPath("particle2.bmp"); |
---|
| 20 | if (path == NULL) { |
---|
| 21 | fprintf(stderr, "ERROR : pointset file not found - %s\n", path); |
---|
[825] | 22 | fflush(stdout); |
---|
| 23 | return; |
---|
| 24 | } |
---|
| 25 | |
---|
| 26 | ImageLoader* loader = ImageLoaderFactory::getInstance()->createLoader("bmp"); |
---|
| 27 | Image* image = loader->load(path, Image::IMG_RGBA); |
---|
[1111] | 28 | delete [] path; |
---|
[827] | 29 | unsigned char* bytes = (unsigned char*) image->getImageBuffer(); |
---|
[953] | 30 | if (bytes) { |
---|
| 31 | for (unsigned int y = 0; y < image->getHeight(); ++y) { |
---|
| 32 | for (unsigned int x = 0; x < image->getWidth(); ++x, bytes +=4) { |
---|
[827] | 33 | bytes[3] = (bytes[0] == 0)? 0 : 255; |
---|
[953] | 34 | } |
---|
| 35 | } |
---|
[827] | 36 | } |
---|
| 37 | |
---|
[953] | 38 | if (image) { |
---|
| 39 | _pointTexture = new Texture2D(image->getWidth(), image->getHeight(), |
---|
| 40 | GL_UNSIGNED_BYTE, GL_LINEAR, |
---|
| 41 | 4, (float*) image->getImageBuffer()); |
---|
| 42 | } else { |
---|
[825] | 43 | printf("fail to load image [%s]\n", "particles2.bmp"); |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | delete loader; |
---|
| 47 | _bucketSort = new PCA::BucketSort(1024); |
---|
| 48 | } |
---|
| 49 | |
---|
| 50 | void PointSetRenderer::renderPoints(PCA::Point* points, int length) |
---|
| 51 | { |
---|
| 52 | PCA::Point* p = points; |
---|
| 53 | for (int i = 0; i < length; ++i) |
---|
| 54 | { |
---|
| 55 | glColor4f(p->color.x, p->color.y, p->color.z, p->color.w); |
---|
| 56 | glVertex3f(p->position.x, p->position.y, p->position.z); |
---|
| 57 | |
---|
| 58 | ++p; |
---|
| 59 | } |
---|
| 60 | } |
---|
| 61 | |
---|
| 62 | void PointSetRenderer::renderCluster(PCA::ClusterList** bucket, int size, int level) |
---|
| 63 | { |
---|
| 64 | float quadratic[] = { 1.0f, 0.0f, 0.01f }; |
---|
| 65 | |
---|
[827] | 66 | glEnable(GL_POINT_SPRITE_ARB); |
---|
[825] | 67 | glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic); |
---|
| 68 | glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f); |
---|
| 69 | glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 1.0f); |
---|
| 70 | glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, 100); |
---|
[827] | 71 | #ifdef USE_TEXTURE |
---|
[825] | 72 | glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); |
---|
[827] | 73 | #endif |
---|
[825] | 74 | |
---|
| 75 | glEnable(GL_POINT_SPRITE_ARB); |
---|
| 76 | |
---|
| 77 | bool setSize = false; |
---|
| 78 | glBegin(GL_POINTS); |
---|
| 79 | |
---|
| 80 | PCA::ClusterList* p; |
---|
| 81 | for (int i = size - 1; i >= 0; --i) |
---|
| 82 | { |
---|
| 83 | p = bucket[i]; |
---|
| 84 | if (p) |
---|
| 85 | { |
---|
| 86 | if (!setSize) |
---|
| 87 | { |
---|
[827] | 88 | #ifdef USE_SHADER |
---|
[825] | 89 | _shader->setScale(p->data->points[0].size); |
---|
[827] | 90 | #endif |
---|
[825] | 91 | setSize = true; |
---|
| 92 | } |
---|
| 93 | } |
---|
| 94 | |
---|
| 95 | while (p) |
---|
| 96 | { |
---|
| 97 | renderPoints(p->data->points, p->data->numOfPoints); |
---|
| 98 | |
---|
| 99 | p = p->next; |
---|
| 100 | } |
---|
| 101 | |
---|
| 102 | } |
---|
| 103 | |
---|
| 104 | glEnd(); |
---|
| 105 | |
---|
| 106 | glDisable(GL_POINT_SPRITE_ARB); |
---|
[827] | 107 | glPointSize(1); |
---|
[825] | 108 | |
---|
| 109 | } |
---|
| 110 | |
---|
[827] | 111 | void PointSetRenderer::render(PCA::ClusterAccel* cluster, const Mat4x4& mat, int sortLevel, const Vector3& scale, const Vector3& origin) |
---|
[825] | 112 | { |
---|
| 113 | _bucketSort->init(); |
---|
| 114 | _bucketSort->sort(cluster, mat, sortLevel); |
---|
| 115 | |
---|
[827] | 116 | glDisable(GL_TEXTURE_2D); |
---|
| 117 | |
---|
| 118 | #ifdef USE_TEXTURE |
---|
[825] | 119 | _pointTexture->activate(); |
---|
[827] | 120 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
---|
| 121 | #endif |
---|
| 122 | |
---|
| 123 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
---|
| 124 | //glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
---|
| 125 | glEnable(GL_BLEND); |
---|
| 126 | |
---|
| 127 | glDisable(GL_LIGHTING); |
---|
| 128 | glEnable(GL_COLOR_MATERIAL); |
---|
| 129 | |
---|
| 130 | glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
---|
| 131 | glPushMatrix(); |
---|
| 132 | float s = 1.0f / scale.x; |
---|
| 133 | Vector3 shift(origin.x + scale.x * 0.5, origin.x + scale.x * 0.5, origin.x + scale.x * 0.5); |
---|
| 134 | glScalef(s, scale.y / scale.x * s, scale.z / scale.x * s); |
---|
| 135 | |
---|
| 136 | //glTranslatef(-shift.x, -shift.y, -shift.z); |
---|
| 137 | |
---|
| 138 | #ifdef USE_SHADER |
---|
[825] | 139 | _shader->bind(); |
---|
[827] | 140 | #else |
---|
| 141 | glPointSize(POINT_SIZE); |
---|
| 142 | #endif |
---|
[825] | 143 | renderCluster(_bucketSort->getBucket(), _bucketSort->getSize(), 4); |
---|
[827] | 144 | #ifdef USE_SHADER |
---|
| 145 | _shader->unbind(); |
---|
| 146 | #else |
---|
| 147 | glPointSize(1.0f); |
---|
| 148 | #endif |
---|
| 149 | |
---|
[825] | 150 | glPopMatrix(); |
---|
| 151 | |
---|
[827] | 152 | glDisable(GL_COLOR_MATERIAL); |
---|
| 153 | glEnable(GL_LIGHTING); |
---|
| 154 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); |
---|
| 155 | glDisable(GL_BLEND); |
---|
| 156 | |
---|
| 157 | #ifdef USE_TEXTURE |
---|
| 158 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
---|
[825] | 159 | _pointTexture->deactivate(); |
---|
[827] | 160 | #endif |
---|
[825] | 161 | } |
---|
| 162 | |
---|