mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Merge pull request #3741 from ey6es/master
Use 3D geometry (cones, spheres) for rendering point and spot lights for deferred shading, exiting the fragment shaders early on depth fail.
This commit is contained in:
commit
7e36c51edc
8 changed files with 202 additions and 68 deletions
|
@ -11,50 +11,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// find the right "right" direction
|
||||
vec3 firstRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(0.0, 1.0, 0.0));
|
||||
vec3 secondRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(1.0, 0.0, 0.0));
|
||||
vec3 right = mix(firstRightCandidate, secondRightCandidate, step(length(firstRightCandidate), length(secondRightCandidate)));
|
||||
right = normalize(right);
|
||||
|
||||
// and the "up"
|
||||
vec3 up = cross(right, gl_LightSource[1].spotDirection);
|
||||
|
||||
// and the "back," which depends on whether this is a spot light
|
||||
vec3 back = -gl_LightSource[1].spotDirection * step(gl_LightSource[1].spotCosCutoff, 0.0);
|
||||
|
||||
// find the eight corners of the bounds
|
||||
vec4 c0 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + back), 1.0);
|
||||
vec4 c1 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + back), 1.0);
|
||||
vec4 c2 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + back), 1.0);
|
||||
vec4 c3 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + back), 1.0);
|
||||
vec4 c4 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c5 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c6 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c7 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
|
||||
// find their projected extents
|
||||
vec2 extents = max(
|
||||
max(max(gl_Vertex.xy * (c0.xy / max(c0.w, 0.001)), gl_Vertex.xy * (c1.xy / max(c1.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c2.xy / max(c2.w, 0.001)), gl_Vertex.xy * (c3.xy / max(c3.w, 0.001)))),
|
||||
max(max(gl_Vertex.xy * (c4.xy / max(c4.w, 0.001)), gl_Vertex.xy * (c5.xy / max(c5.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c6.xy / max(c6.w, 0.001)), gl_Vertex.xy * (c7.xy / max(c7.w, 0.001)))));
|
||||
|
||||
// make sure they don't extend beyond the screen
|
||||
extents = min(extents, vec2(1.0, 1.0));
|
||||
|
||||
gl_Position = vec4(gl_Vertex.xy * extents, 0.0, 1.0);
|
||||
gl_TexCoord[0] = vec4(dot(gl_Position, gl_ObjectPlaneS[3]), dot(gl_Position, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
gl_Position = ftransform();
|
||||
vec4 projected = gl_Position / gl_Position.w;
|
||||
gl_TexCoord[0] = vec4(dot(projected, gl_ObjectPlaneS[3]), dot(projected, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,13 @@ uniform vec2 depthTexCoordScale;
|
|||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// get the depth and exit early if it doesn't pass the test
|
||||
float depth = texture2D(depthMap, gl_TexCoord[0].st).r;
|
||||
if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
float z = near / (depth * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
|
|
|
@ -39,8 +39,13 @@ uniform vec2 depthTexCoordScale;
|
|||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// get the depth and exit early if it doesn't pass the test
|
||||
float depth = texture2D(depthMap, gl_TexCoord[0].st).r;
|
||||
if (depth < gl_FragCoord.z) {
|
||||
discard;
|
||||
}
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
float z = near / (depth * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
|
|
|
@ -126,6 +126,7 @@ void OculusManager::connect() {
|
|||
|
||||
if (!_camera) {
|
||||
_camera = new Camera;
|
||||
configureCamera(*_camera, 0, 0); // no need to use screen dimensions; they're ignored
|
||||
}
|
||||
|
||||
if (!_programInitialized) {
|
||||
|
@ -420,7 +421,7 @@ void OculusManager::endFrameTiming() {
|
|||
//Sets the camera FoV and aspect ratio
|
||||
void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenHeight) {
|
||||
#ifdef HAVE_LIBOVR
|
||||
camera.setAspectRatio((float)_renderTargetSize.w / _renderTargetSize.h);
|
||||
camera.setAspectRatio(_renderTargetSize.w * 0.5f / _renderTargetSize.h);
|
||||
camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -73,6 +73,12 @@ void DeferredLightingEffect::renderWireCube(float size) {
|
|||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderSolidCone(float base, float height, int slices, int stacks) {
|
||||
bindSimpleProgram();
|
||||
Application::getInstance()->getGeometryCache()->renderCone(base, height, slices, stacks);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient,
|
||||
const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation,
|
||||
float linearAttenuation, float quadraticAttenuation) {
|
||||
|
@ -216,11 +222,18 @@ void DeferredLightingEffect::render() {
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
||||
glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients);
|
||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients);
|
||||
|
||||
// enlarge the scales slightly to account for tesselation
|
||||
const float SCALE_EXPANSION = 0.1f;
|
||||
|
||||
const glm::vec3& eyePoint = Application::getInstance()->getDisplayViewFrustum()->getPosition();
|
||||
|
||||
if (!_pointLights.isEmpty()) {
|
||||
_pointLight.bind();
|
||||
_pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal);
|
||||
|
@ -238,7 +251,28 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);
|
||||
|
||||
renderFullscreenQuad();
|
||||
glPushMatrix();
|
||||
|
||||
float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION);
|
||||
if (glm::distance(eyePoint, glm::vec3(light.position)) < expandedRadius) {
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
renderFullscreenQuad();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
} else {
|
||||
glTranslatef(light.position.x, light.position.y, light.position.z);
|
||||
Application::getInstance()->getGeometryCache()->renderSphere(expandedRadius, 64, 64);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
_pointLights.clear();
|
||||
|
||||
|
@ -265,7 +299,34 @@ void DeferredLightingEffect::render() {
|
|||
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent);
|
||||
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff));
|
||||
|
||||
renderFullscreenQuad();
|
||||
glPushMatrix();
|
||||
|
||||
float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION);
|
||||
float edgeRadius = expandedRadius / glm::cos(light.cutoff);
|
||||
if (glm::distance(eyePoint, glm::vec3(light.position)) < edgeRadius) {
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
renderFullscreenQuad();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
} else {
|
||||
glTranslatef(light.position.x, light.position.y, light.position.z);
|
||||
glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light.direction);
|
||||
glm::vec3 axis = glm::axis(spotRotation);
|
||||
glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z);
|
||||
glTranslatef(0.0f, 0.0f, -light.radius * (1.0f + SCALE_EXPANSION * 0.5f));
|
||||
Application::getInstance()->getGeometryCache()->renderCone(expandedRadius * glm::tan(light.cutoff),
|
||||
expandedRadius, 64, 32);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
_spotLights.clear();
|
||||
|
||||
|
@ -285,6 +346,8 @@ void DeferredLightingEffect::render() {
|
|||
|
||||
freeFBO->release();
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// now transfer the lit region to the primary fbo
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glColorMask(true, true, true, false);
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
|
||||
//// Renders a wireframe cube with the simple program.
|
||||
void renderWireCube(float size);
|
||||
|
||||
//// Renders a solid cone with the simple program.
|
||||
void renderSolidCone(float base, float height, int slices, int stacks);
|
||||
|
||||
/// Adds a point light to render for the current frame.
|
||||
void addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
|
|
|
@ -110,15 +110,18 @@ void GeometryCache::renderHemisphere(int slices, int stacks) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
const int NUM_VERTICES_PER_TRIANGLE = 3;
|
||||
const int NUM_TRIANGLES_PER_QUAD = 2;
|
||||
const int NUM_VERTICES_PER_TRIANGULATED_QUAD = NUM_VERTICES_PER_TRIANGLE * NUM_TRIANGLES_PER_QUAD;
|
||||
const int NUM_COORDS_PER_VERTEX = 3;
|
||||
const int NUM_BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int NUM_BYTES_PER_INDEX = sizeof(GLushort);
|
||||
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
||||
VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)];
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
const int NUM_VERTICES_PER_TRIANGLE = 3;
|
||||
const int NUM_TRIANGLES_PER_QUAD = 2;
|
||||
int indices = slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE * (stacks - 1) + slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE;
|
||||
if (vbo.first == 0) {
|
||||
const int NUM_COORDS_PER_VERTEX = 3;
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
int indices = slices * stacks * NUM_VERTICES_PER_TRIANGULATED_QUAD;
|
||||
if (vbo.first == 0) {
|
||||
GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX];
|
||||
GLfloat* vertex = vertexData;
|
||||
|
||||
|
@ -148,8 +151,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -192,8 +194,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -239,8 +240,7 @@ void GeometryCache::renderSquare(int xDivisions, int yDivisions) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -263,8 +263,7 @@ void GeometryCache::renderSquare(int xDivisions, int yDivisions) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -313,8 +312,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
|
@ -337,8 +335,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
const int BYTES_PER_INDEX = sizeof(GLushort);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
|
@ -360,6 +357,106 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) {
|
|||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderCone(float base, float height, int slices, int stacks) {
|
||||
VerticesIndices& vbo = _halfCylinderVBOs[IntPair(slices, stacks)];
|
||||
int vertices = (stacks + 2) * slices;
|
||||
int baseTriangles = slices - 2;
|
||||
int indices = NUM_VERTICES_PER_TRIANGULATED_QUAD * slices * stacks + NUM_VERTICES_PER_TRIANGLE * baseTriangles;
|
||||
if (vbo.first == 0) {
|
||||
GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX * 2];
|
||||
GLfloat* vertex = vertexData;
|
||||
// cap
|
||||
for (int i = 0; i < slices; i++) {
|
||||
float theta = TWO_PI * i / slices;
|
||||
|
||||
//normals
|
||||
*(vertex++) = 0.0f;
|
||||
*(vertex++) = 0.0f;
|
||||
*(vertex++) = -1.0f;
|
||||
|
||||
// vertices
|
||||
*(vertex++) = cosf(theta);
|
||||
*(vertex++) = sinf(theta);
|
||||
*(vertex++) = 0.0f;
|
||||
}
|
||||
// body
|
||||
for (int i = 0; i <= stacks; i++) {
|
||||
float z = (float)i / stacks;
|
||||
float radius = 1.0f - z;
|
||||
|
||||
for (int j = 0; j < slices; j++) {
|
||||
float theta = TWO_PI * j / slices;
|
||||
|
||||
//normals
|
||||
*(vertex++) = cosf(theta) / SQUARE_ROOT_OF_2;
|
||||
*(vertex++) = sinf(theta) / SQUARE_ROOT_OF_2;
|
||||
*(vertex++) = 1.0f / SQUARE_ROOT_OF_2;
|
||||
|
||||
// vertices
|
||||
*(vertex++) = radius * cosf(theta);
|
||||
*(vertex++) = radius * sinf(theta);
|
||||
*(vertex++) = z;
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, 2 * vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < baseTriangles; i++) {
|
||||
*(index++) = 0;
|
||||
*(index++) = i + 1;
|
||||
*(index++) = i + 2;
|
||||
}
|
||||
for (int i = 1; i <= stacks; i++) {
|
||||
GLushort bottom = i * slices;
|
||||
GLushort top = bottom + slices;
|
||||
for (int j = 0; j < slices; j++) {
|
||||
int next = (j + 1) % slices;
|
||||
|
||||
*(index++) = bottom + j;
|
||||
*(index++) = top + next;
|
||||
*(index++) = top + j;
|
||||
|
||||
*(index++) = bottom + j;
|
||||
*(index++) = bottom + next;
|
||||
*(index++) = top + next;
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
int stride = NUM_VERTICES_PER_TRIANGULATED_QUAD * sizeof(float);
|
||||
glNormalPointer(GL_FLOAT, stride, 0);
|
||||
glVertexPointer(NUM_COORDS_PER_VERTEX, GL_FLOAT, stride, (const void *)(NUM_COORDS_PER_VERTEX * sizeof(float)));
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(base, base, height);
|
||||
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderGrid(int xDivisions, int yDivisions) {
|
||||
QOpenGLBuffer& buffer = _gridBuffers[IntPair(xDivisions, yDivisions)];
|
||||
int vertices = (xDivisions + 1 + yDivisions + 1) * 2;
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
void renderSphere(float radius, int slices, int stacks);
|
||||
void renderSquare(int xDivisions, int yDivisions);
|
||||
void renderHalfCylinder(int slices, int stacks);
|
||||
void renderCone(float base, float height, int slices, int stacks);
|
||||
void renderGrid(int xDivisions, int yDivisions);
|
||||
|
||||
/// Loads geometry from the specified URL.
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
QHash<IntPair, VerticesIndices> _sphereVBOs;
|
||||
QHash<IntPair, VerticesIndices> _squareVBOs;
|
||||
QHash<IntPair, VerticesIndices> _halfCylinderVBOs;
|
||||
QHash<IntPair, VerticesIndices> _coneVBOs;
|
||||
QHash<IntPair, QOpenGLBuffer> _gridBuffers;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
|
|
Loading…
Reference in a new issue