mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 16:14:01 +02:00
More work on avatar voxels.
This commit is contained in:
parent
7425b39237
commit
6c975f9c6f
6 changed files with 121 additions and 19 deletions
34
interface/resources/shaders/skin_voxels.vert
Normal file
34
interface/resources/shaders/skin_voxels.vert
Normal file
|
@ -0,0 +1,34 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// skin_voxels.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/31/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
const int MAX_BONES = 32;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
uniform mat4 boneMatrices[MAX_BONES];
|
||||
|
||||
attribute vec4 boneIndices;
|
||||
attribute vec4 boneWeights;
|
||||
|
||||
void main(void) {
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 normal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 boneMatrix = boneMatrices[int(boneIndices[i])];
|
||||
float boneWeight = boneWeights[i];
|
||||
position += boneMatrix * gl_Vertex * boneWeight;
|
||||
normal += boneMatrix * vec4(gl_Normal, 0.0) * boneWeight;
|
||||
}
|
||||
position = gl_ModelViewProjectionMatrix * position;
|
||||
normal = normalize(gl_ModelViewMatrix * normal);
|
||||
|
||||
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
|
||||
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||
gl_Position = position;
|
||||
}
|
|
@ -88,7 +88,8 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||
_interactingOther(NULL),
|
||||
_cumulativeMouseYaw(0.0f),
|
||||
_isMouseTurningRight(false)
|
||||
_isMouseTurningRight(false),
|
||||
_voxels(this)
|
||||
{
|
||||
|
||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||
|
|
|
@ -8,13 +8,18 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "AvatarVoxelSystem.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
const float AVATAR_TREE_SCALE = 1.0f;
|
||||
const int MAX_VOXELS_PER_AVATAR = 2000;
|
||||
const int BONE_INDEX_ELEMENTS_PER_VOXEL = 4 * VERTICES_PER_VOXEL;
|
||||
const int BONE_WEIGHT_ELEMENTS_PER_VOXEL = 4 * VERTICES_PER_VOXEL;
|
||||
const int BONE_INDEX_ELEMENTS_PER_VERTEX = 4;
|
||||
const int BONE_INDEX_ELEMENTS_PER_VOXEL = BONE_INDEX_ELEMENTS_PER_VERTEX * VERTICES_PER_VOXEL;
|
||||
const int BONE_WEIGHT_ELEMENTS_PER_VERTEX = 4;
|
||||
const int BONE_WEIGHT_ELEMENTS_PER_VOXEL = BONE_WEIGHT_ELEMENTS_PER_VERTEX * VERTICES_PER_VOXEL;
|
||||
|
||||
AvatarVoxelSystem::AvatarVoxelSystem() : VoxelSystem(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR) {
|
||||
AvatarVoxelSystem::AvatarVoxelSystem(Avatar* avatar) :
|
||||
VoxelSystem(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR),
|
||||
_avatar(avatar) {
|
||||
}
|
||||
|
||||
AvatarVoxelSystem::~AvatarVoxelSystem() {
|
||||
|
@ -24,6 +29,11 @@ AvatarVoxelSystem::~AvatarVoxelSystem() {
|
|||
delete[] _writeBoneWeightsArray;
|
||||
}
|
||||
|
||||
ProgramObject* AvatarVoxelSystem::_skinProgram = 0;
|
||||
int AvatarVoxelSystem::_boneMatricesLocation;
|
||||
int AvatarVoxelSystem::_boneIndicesLocation;
|
||||
int AvatarVoxelSystem::_boneWeightsLocation;
|
||||
|
||||
void AvatarVoxelSystem::init() {
|
||||
VoxelSystem::init();
|
||||
|
||||
|
@ -43,6 +53,18 @@ void AvatarVoxelSystem::init() {
|
|||
glGenBuffers(1, &_vboBoneWeightsID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneWeightsID);
|
||||
glBufferData(GL_ARRAY_BUFFER, BONE_WEIGHT_ELEMENTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
// load our skin program if this is the first avatar system to initialize
|
||||
if (_skinProgram != 0) {
|
||||
return;
|
||||
}
|
||||
_skinProgram = new ProgramObject();
|
||||
_skinProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/skin_voxels.vert");
|
||||
_skinProgram->link();
|
||||
|
||||
_boneMatricesLocation = _skinProgram->uniformLocation("boneMatrices");
|
||||
_boneIndicesLocation = _skinProgram->attributeLocation("boneIndices");
|
||||
_boneWeightsLocation = _skinProgram->attributeLocation("boneWeights");
|
||||
}
|
||||
|
||||
void AvatarVoxelSystem::render(bool texture) {
|
||||
|
@ -53,11 +75,15 @@ void AvatarVoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::v
|
|||
float voxelScale, const nodeColor& color) {
|
||||
VoxelSystem::updateNodeInArrays(nodeIndex, startVertex, voxelScale, color);
|
||||
|
||||
for (int j = 0; j < BONE_INDEX_ELEMENTS_PER_VOXEL; j++) {
|
||||
GLubyte* writeBoneIndicesAt = _writeBoneIndicesArray + (nodeIndex * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (nodeIndex * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||
*(writeBoneIndicesAt + j) = 0;
|
||||
*(writeBoneWeightsAt + j) = 0.0f;
|
||||
GLubyte* writeBoneIndicesAt = _writeBoneIndicesArray + (nodeIndex * BONE_INDEX_ELEMENTS_PER_VOXEL);
|
||||
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (nodeIndex * BONE_WEIGHT_ELEMENTS_PER_VOXEL);
|
||||
for (int i = 0; i < VERTICES_PER_VOXEL; i++) {
|
||||
GLubyte boneIndices[] = { 0, 0, 0, 0};
|
||||
glm::vec4 boneWeights = glm::vec4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
for (int j = 0; j < BONE_INDEX_ELEMENTS_PER_VERTEX; j++) {
|
||||
*(writeBoneIndicesAt + i * BONE_INDEX_ELEMENTS_PER_VERTEX + j) = boneIndices[j];
|
||||
*(writeBoneWeightsAt + i * BONE_WEIGHT_ELEMENTS_PER_VERTEX + j) = boneWeights[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,3 +121,25 @@ void AvatarVoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferInd
|
|||
glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readBoneWeightsFrom);
|
||||
}
|
||||
|
||||
void AvatarVoxelSystem::bindProgram(bool texture) {
|
||||
_skinProgram->bind();
|
||||
|
||||
QMatrix4x4 boneMatrices[1];
|
||||
|
||||
_skinProgram->setUniformValueArray(_boneMatricesLocation, boneMatrices, sizeof(boneMatrices) / sizeof(boneMatrices[0]));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneIndicesID);
|
||||
_skinProgram->setAttributeBuffer(_boneIndicesLocation, GL_UNSIGNED_BYTE, 0, BONE_INDEX_ELEMENTS_PER_VERTEX);
|
||||
_skinProgram->enableAttributeArray(_boneIndicesLocation);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboBoneWeightsID);
|
||||
_skinProgram->setAttributeBuffer(_boneWeightsLocation, GL_FLOAT, 0, BONE_WEIGHT_ELEMENTS_PER_VERTEX);
|
||||
_skinProgram->enableAttributeArray(_boneWeightsLocation);
|
||||
}
|
||||
|
||||
void AvatarVoxelSystem::releaseProgram(bool texture) {
|
||||
_skinProgram->release();
|
||||
_skinProgram->disableAttributeArray(_boneIndicesLocation);
|
||||
_skinProgram->disableAttributeArray(_boneWeightsLocation);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
|
||||
#include "VoxelSystem.h"
|
||||
|
||||
class Avatar;
|
||||
|
||||
class AvatarVoxelSystem : public VoxelSystem {
|
||||
public:
|
||||
|
||||
AvatarVoxelSystem();
|
||||
AvatarVoxelSystem(Avatar* avatar);
|
||||
virtual ~AvatarVoxelSystem();
|
||||
|
||||
virtual void init();
|
||||
|
@ -26,9 +28,13 @@ protected:
|
|||
float voxelScale, const nodeColor& color);
|
||||
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void bindProgram(bool texture);
|
||||
virtual void releaseProgram(bool texture);
|
||||
|
||||
private:
|
||||
|
||||
Avatar* _avatar;
|
||||
|
||||
GLubyte* _readBoneIndicesArray;
|
||||
GLfloat* _readBoneWeightsArray;
|
||||
GLubyte* _writeBoneIndicesArray;
|
||||
|
@ -37,7 +43,10 @@ private:
|
|||
GLuint _vboBoneIndicesID;
|
||||
GLuint _vboBoneWeightsID;
|
||||
|
||||
ProgramObject* _skinProgram;
|
||||
static ProgramObject* _skinProgram;
|
||||
static int _boneMatricesLocation;
|
||||
static int _boneIndicesLocation;
|
||||
static int _boneWeightsLocation;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__AvatarVoxelSystem__) */
|
||||
|
|
|
@ -625,10 +625,7 @@ void VoxelSystem::render(bool texture) {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
|
||||
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
|
||||
|
||||
if (texture) {
|
||||
_perlinModulateProgram->bind();
|
||||
glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID);
|
||||
}
|
||||
bindProgram(texture);
|
||||
|
||||
// for performance, disable blending and enable backface culling
|
||||
glDisable(GL_BLEND);
|
||||
|
@ -643,10 +640,7 @@ void VoxelSystem::render(bool texture) {
|
|||
glEnable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (texture) {
|
||||
_perlinModulateProgram->release();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
releaseProgram(texture);
|
||||
|
||||
// deactivate vertex and color arrays after drawing
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
@ -663,6 +657,20 @@ void VoxelSystem::render(bool texture) {
|
|||
pthread_mutex_unlock(&_bufferWriteLock);
|
||||
}
|
||||
|
||||
void VoxelSystem::bindProgram(bool texture) {
|
||||
if (texture) {
|
||||
_perlinModulateProgram->bind();
|
||||
glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelSystem::releaseProgram(bool texture) {
|
||||
if (texture) {
|
||||
_perlinModulateProgram->release();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int VoxelSystem::_nodeCount = 0;
|
||||
|
||||
void VoxelSystem::killLocalVoxels() {
|
||||
|
|
|
@ -87,6 +87,8 @@ protected:
|
|||
float voxelScale, const nodeColor& color);
|
||||
virtual void copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd);
|
||||
virtual void bindProgram(bool texture);
|
||||
virtual void releaseProgram(bool texture);
|
||||
|
||||
private:
|
||||
// disallow copying of VoxelSystem objects
|
||||
|
|
Loading…
Reference in a new issue