Implemented KRMat4::LookAt
KREngine object no longer requires a width and height passed into init. KRCamera no longer requires a width and height passed into the constructor; it now automatically resizes its buffers to match the active render target. --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40128
This commit is contained in:
@@ -42,9 +42,9 @@
|
|||||||
#import "KRBoundingVolume.h"
|
#import "KRBoundingVolume.h"
|
||||||
#import "KRStockGeometry.h"
|
#import "KRStockGeometry.h"
|
||||||
|
|
||||||
KRCamera::KRCamera(KRContext &context, GLint width, GLint height) : KRContextObject(context) {
|
KRCamera::KRCamera(KRContext &context) : KRContextObject(context) {
|
||||||
backingWidth = width;
|
backingWidth = 0;
|
||||||
backingHeight = height;
|
backingHeight = 0;
|
||||||
|
|
||||||
|
|
||||||
double const PI = 3.141592653589793f;
|
double const PI = 3.141592653589793f;
|
||||||
@@ -96,6 +96,12 @@ KRCamera::KRCamera(KRContext &context, GLint width, GLint height) : KRContextObj
|
|||||||
|
|
||||||
|
|
||||||
m_cShadowBuffers = 0;
|
m_cShadowBuffers = 0;
|
||||||
|
compositeDepthTexture = 0;
|
||||||
|
compositeColorTexture = 0;
|
||||||
|
lightAccumulationTexture = 0;
|
||||||
|
compositeFramebuffer = 0;
|
||||||
|
lightAccumulationBuffer = 0;
|
||||||
|
|
||||||
|
|
||||||
memset(shadowFramebuffer, sizeof(GLuint) * 3, 0);
|
memset(shadowFramebuffer, sizeof(GLuint) * 3, 0);
|
||||||
memset(shadowDepthTexture, sizeof(GLuint) * 3, 0);
|
memset(shadowDepthTexture, sizeof(GLuint) * 3, 0);
|
||||||
@@ -104,8 +110,6 @@ KRCamera::KRCamera(KRContext &context, GLint width, GLint height) : KRContextObj
|
|||||||
|
|
||||||
m_skyBoxName = "";
|
m_skyBoxName = "";
|
||||||
m_pSkyBoxTexture = NULL;
|
m_pSkyBoxTexture = NULL;
|
||||||
|
|
||||||
createBuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KRCamera::~KRCamera() {
|
KRCamera::~KRCamera() {
|
||||||
@@ -139,6 +143,8 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
|
|||||||
GLint defaultFBO;
|
GLint defaultFBO;
|
||||||
GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO));
|
GLDEBUG(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO));
|
||||||
|
|
||||||
|
createBuffers();
|
||||||
|
|
||||||
m_pContext->rotateBuffers(true);
|
m_pContext->rotateBuffers(true);
|
||||||
KRMat4 invViewMatrix = viewMatrix;
|
KRMat4 invViewMatrix = viewMatrix;
|
||||||
invViewMatrix.invert();
|
invViewMatrix.invert();
|
||||||
@@ -157,7 +163,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
|
|||||||
|
|
||||||
lightDirection.normalize();
|
lightDirection.normalize();
|
||||||
|
|
||||||
allocateShadowBuffers();
|
allocateShadowBuffers(m_cShadowBuffers);
|
||||||
int iOffset=m_iFrame % m_cShadowBuffers;
|
int iOffset=m_iFrame % m_cShadowBuffers;
|
||||||
for(int iShadow2=iOffset; iShadow2 < m_cShadowBuffers + iOffset; iShadow2++) {
|
for(int iShadow2=iOffset; iShadow2 < m_cShadowBuffers + iOffset; iShadow2++) {
|
||||||
int iShadow = iShadow2 % m_cShadowBuffers;
|
int iShadow = iShadow2 % m_cShadowBuffers;
|
||||||
@@ -202,6 +208,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
|
|||||||
|
|
||||||
|
|
||||||
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) {
|
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) {
|
||||||
|
|
||||||
setViewportSize(KRVector2(backingWidth, backingHeight));
|
setViewportSize(KRVector2(backingWidth, backingHeight));
|
||||||
|
|
||||||
|
|
||||||
@@ -497,6 +504,16 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightD
|
|||||||
|
|
||||||
|
|
||||||
void KRCamera::createBuffers() {
|
void KRCamera::createBuffers() {
|
||||||
|
GLint renderBufferWidth = 0, renderBufferHeight = 0;
|
||||||
|
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderBufferWidth));
|
||||||
|
GLDEBUG(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderBufferHeight));
|
||||||
|
|
||||||
|
if(renderBufferWidth != backingWidth || renderBufferHeight != backingHeight) {
|
||||||
|
backingWidth = renderBufferWidth;
|
||||||
|
backingHeight = renderBufferHeight;
|
||||||
|
|
||||||
|
destroyBuffers();
|
||||||
|
|
||||||
// ===== Create offscreen compositing framebuffer object =====
|
// ===== Create offscreen compositing framebuffer object =====
|
||||||
GLDEBUG(glGenFramebuffers(1, &compositeFramebuffer));
|
GLDEBUG(glGenFramebuffers(1, &compositeFramebuffer));
|
||||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
|
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
|
||||||
@@ -537,12 +554,13 @@ void KRCamera::createBuffers() {
|
|||||||
GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
|
GLDEBUG(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
|
||||||
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0));
|
GLDEBUG(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lightAccumulationTexture, 0));
|
||||||
|
|
||||||
allocateShadowBuffers();
|
allocateShadowBuffers(m_cShadowBuffers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRCamera::allocateShadowBuffers() {
|
void KRCamera::allocateShadowBuffers(int cBuffers) {
|
||||||
// First deallocate buffers no longer needed
|
// First deallocate buffers no longer needed
|
||||||
for(int iShadow = m_cShadowBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) {
|
for(int iShadow = cBuffers; iShadow < KRENGINE_MAX_SHADOW_BUFFERS; iShadow++) {
|
||||||
if (shadowDepthTexture[iShadow]) {
|
if (shadowDepthTexture[iShadow]) {
|
||||||
GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow));
|
GLDEBUG(glDeleteTextures(1, shadowDepthTexture + iShadow));
|
||||||
shadowDepthTexture[iShadow] = 0;
|
shadowDepthTexture[iShadow] = 0;
|
||||||
@@ -555,7 +573,7 @@ void KRCamera::allocateShadowBuffers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate newly required buffers
|
// Allocate newly required buffers
|
||||||
for(int iShadow = 0; iShadow < m_cShadowBuffers; iShadow++) {
|
for(int iShadow = 0; iShadow < cBuffers; iShadow++) {
|
||||||
if(!shadowDepthTexture[iShadow]) {
|
if(!shadowDepthTexture[iShadow]) {
|
||||||
shadowValid[iShadow] = false;
|
shadowValid[iShadow] = false;
|
||||||
|
|
||||||
@@ -580,8 +598,7 @@ void KRCamera::allocateShadowBuffers() {
|
|||||||
|
|
||||||
void KRCamera::destroyBuffers()
|
void KRCamera::destroyBuffers()
|
||||||
{
|
{
|
||||||
m_cShadowBuffers = 0;
|
allocateShadowBuffers(0);
|
||||||
allocateShadowBuffers();
|
|
||||||
|
|
||||||
if (compositeDepthTexture) {
|
if (compositeDepthTexture) {
|
||||||
GLDEBUG(glDeleteTextures(1, &compositeDepthTexture));
|
GLDEBUG(glDeleteTextures(1, &compositeDepthTexture));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class KRContext;
|
|||||||
|
|
||||||
class KRCamera : public KRContextObject {
|
class KRCamera : public KRContextObject {
|
||||||
public:
|
public:
|
||||||
KRCamera(KRContext &context, GLint width, GLint height);
|
KRCamera(KRContext &context);
|
||||||
virtual ~KRCamera();
|
virtual ~KRCamera();
|
||||||
|
|
||||||
GLint backingWidth, backingHeight;
|
GLint backingWidth, backingHeight;
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
void renderFrame(KRScene &scene, KRMat4 &viewMatrix);
|
void renderFrame(KRScene &scene, KRMat4 &viewMatrix);
|
||||||
void renderShadowBuffer(KRScene &scene, int iShadow);
|
void renderShadowBuffer(KRScene &scene, int iShadow);
|
||||||
void invalidateShadowBuffers();
|
void invalidateShadowBuffers();
|
||||||
void allocateShadowBuffers();
|
void allocateShadowBuffers(int cBuffers);
|
||||||
void createBuffers();
|
void createBuffers();
|
||||||
|
|
||||||
KRVector3 getPosition() const;
|
KRVector3 getPosition() const;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F
|
|||||||
@property(nonatomic, assign) KRCamera *camera;
|
@property(nonatomic, assign) KRCamera *camera;
|
||||||
@property(nonatomic, retain) NSString *debug_text;
|
@property(nonatomic, retain) NSString *debug_text;
|
||||||
|
|
||||||
- (id)initForWidth: (GLuint)width Height: (GLuint)height;
|
- (id)init;
|
||||||
- (BOOL)loadResource:(NSString *)path;
|
- (BOOL)loadResource:(NSString *)path;
|
||||||
|
|
||||||
// Parameter enumeration interface
|
// Parameter enumeration interface
|
||||||
|
|||||||
@@ -51,13 +51,13 @@ using namespace std;
|
|||||||
@synthesize debug_text = _debug_text;
|
@synthesize debug_text = _debug_text;
|
||||||
double const PI = 3.141592653589793f;
|
double const PI = 3.141592653589793f;
|
||||||
|
|
||||||
- (id)initForWidth: (GLuint)width Height: (GLuint)height
|
- (id)init
|
||||||
{
|
{
|
||||||
_camera = NULL;
|
_camera = NULL;
|
||||||
_context = NULL;
|
_context = NULL;
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
_context = new KRContext();
|
_context = new KRContext();
|
||||||
_camera = new KRCamera(*_context, width, height);
|
_camera = new KRCamera(*_context);
|
||||||
_parameter_names = [@{
|
_parameter_names = [@{
|
||||||
@"camera_fov" : @0,
|
@"camera_fov" : @0,
|
||||||
@"shadow_quality" : @1,
|
@"shadow_quality" : @1,
|
||||||
|
|||||||
@@ -303,3 +303,31 @@ KRVector3 KRMat4::DotWDiv(const KRMat4 &m, const KRVector3 &v) {
|
|||||||
r /= DotW(m, v);
|
r /= DotW(m, v);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRMat4 KRMat4::LookAt(const KRVector3 &cameraPos, const KRVector3 &lookAtPos, const KRVector3 &upDirection)
|
||||||
|
{
|
||||||
|
KRMat4 matLookat;
|
||||||
|
KRVector3 lookat_z_axis = lookAtPos - cameraPos;
|
||||||
|
lookat_z_axis.normalize();
|
||||||
|
KRVector3 lookat_x_axis = KRVector3::Cross(upDirection, lookat_z_axis);
|
||||||
|
lookat_x_axis.normalize();
|
||||||
|
KRVector3 lookat_y_axis = KRVector3::Cross(lookat_z_axis, lookat_x_axis);
|
||||||
|
|
||||||
|
matLookat.getPointer()[0] = lookat_x_axis.x;
|
||||||
|
matLookat.getPointer()[1] = lookat_y_axis.x;
|
||||||
|
matLookat.getPointer()[2] = lookat_z_axis.x;
|
||||||
|
|
||||||
|
matLookat.getPointer()[4] = lookat_x_axis.y;
|
||||||
|
matLookat.getPointer()[5] = lookat_y_axis.y;
|
||||||
|
matLookat.getPointer()[6] = lookat_z_axis.y;
|
||||||
|
|
||||||
|
matLookat.getPointer()[8] = lookat_x_axis.z;
|
||||||
|
matLookat.getPointer()[9] = lookat_y_axis.z;
|
||||||
|
matLookat.getPointer()[10] = lookat_z_axis.z;
|
||||||
|
|
||||||
|
matLookat.getPointer()[12] = -KRVector3::Dot(lookat_x_axis, cameraPos);
|
||||||
|
matLookat.getPointer()[13] = -KRVector3::Dot(lookat_y_axis, cameraPos);
|
||||||
|
matLookat.getPointer()[14] = -KRVector3::Dot(lookat_z_axis, cameraPos);
|
||||||
|
|
||||||
|
return matLookat;
|
||||||
|
}
|
||||||
@@ -105,6 +105,8 @@ public:
|
|||||||
static KRVector3 Dot(const KRMat4 &m, const KRVector3 &v);
|
static KRVector3 Dot(const KRMat4 &m, const KRVector3 &v);
|
||||||
static float DotW(const KRMat4 &m, const KRVector3 &v);
|
static float DotW(const KRMat4 &m, const KRVector3 &v);
|
||||||
static KRVector3 DotWDiv(const KRMat4 &m, const KRVector3 &v);
|
static KRVector3 DotWDiv(const KRMat4 &m, const KRVector3 &v);
|
||||||
|
|
||||||
|
static KRMat4 LookAt(const KRVector3 &cameraPos, const KRVector3 &lookAtPos, const KRVector3 &upDirection);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KRMAT4_I
|
#endif // KRMAT4_I
|
||||||
Reference in New Issue
Block a user