void GLInstancingRenderer::updateCamera() { GLint err = glGetError(); b3Assert(err==GL_NO_ERROR); int m_forwardAxis(2); float m_frustumZNear=1; float m_frustumZFar=10000.f; // m_azi=m_azi+0.01; b3Scalar rele = m_data->m_ele * b3Scalar(0.01745329251994329547);// rads per deg b3Scalar razi = m_data->m_azi * b3Scalar(0.01745329251994329547);// rads per deg b3Quaternion rot(m_data->m_cameraUp,razi); b3Vector3 eyePos = b3MakeVector3(0,0,0); eyePos[m_forwardAxis] = -m_data->m_cameraDistance; b3Vector3 forward = b3MakeVector3(eyePos[0],eyePos[1],eyePos[2]); if (forward.length2() < B3_EPSILON) { forward.setValue(1.f,0.f,0.f); } b3Vector3 right = m_data->m_cameraUp.cross(forward); b3Quaternion roll(right,-rele); eyePos = b3Matrix3x3(rot) * b3Matrix3x3(roll) * eyePos; m_data->m_cameraPosition[0] = eyePos.x; m_data->m_cameraPosition[1] = eyePos.y; m_data->m_cameraPosition[2] = eyePos.z; m_data->m_cameraPosition += m_data->m_cameraTargetPosition; if (m_screenWidth == 0 && m_screenHeight == 0) return; b3Scalar aspect; b3Vector3 extents; aspect = m_screenWidth / (b3Scalar)m_screenHeight; extents.setValue(aspect * 1.0f, 1.0f,0); if (m_screenWidth > m_screenHeight) { b3CreateFrustum(-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar,projectionMatrix); } else { b3CreateFrustum(-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar,projectionMatrix); } b3CreateLookAt(m_data->m_cameraPosition,m_data->m_cameraTargetPosition,m_data->m_cameraUp,modelviewMatrix); }
void GLInstancingRenderer::renderSceneInternal(int renderMode) { // glEnable(GL_DEPTH_TEST); GLint dims[4]; glGetIntegerv(GL_VIEWPORT, dims); //we need to get the viewport dims, because on Apple Retina the viewport dimension is different from screenWidth //printf("dims=%d,%d,%d,%d\n",dims[0],dims[1],dims[2],dims[3]); // Accept fragment if it closer to the camera than the former one //glDepthFunc(GL_LESS); // Cull triangles which normal is not towards the camera //glEnable(GL_CULL_FACE); B3_PROFILE("GLInstancingRenderer::RenderScene"); { B3_PROFILE("init"); init(); } GLint err = glGetError(); b3Assert(err==GL_NO_ERROR); float depthProjectionMatrix[4][4]; GLfloat depthModelViewMatrix[4][4]; //GLfloat depthModelViewMatrix2[4][4]; // Compute the MVP matrix from the light's point of view if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE) { if (!m_data->m_shadowMap) { glActiveTexture(GL_TEXTURE0); glGenTextures(1,&m_data->m_shadowTexture); glBindTexture(GL_TEXTURE_2D,m_data->m_shadowTexture); //glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT16,m_screenWidth,m_screenHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,0); //glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32,m_screenWidth,m_screenHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,0); glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, shadowMapWidth, shadowMapHeight, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); float l_ClampColor[] = {1.0, 1.0, 1.0, 1.0}; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, l_ClampColor); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); m_data->m_shadowMap=new GLRenderToTexture(); m_data->m_shadowMap->init(shadowMapWidth, shadowMapHeight,m_data->m_shadowTexture,RENDERTEXTURE_DEPTH); } m_data->m_shadowMap->enable(); glViewport(0,0,shadowMapWidth,shadowMapHeight); //glClearColor(1,1,1,1); glClear(GL_DEPTH_BUFFER_BIT); //glClearColor(0.3,0.3,0.3,1); // m_data->m_shadowMap->disable(); // return; // glEnable(GL_CULL_FACE); // glCullFace(GL_BACK); // Cull back-facing triangles -> draw only front-facing triangles GLint err = glGetError(); b3Assert(err==GL_NO_ERROR); } static b3Vector3 lightPos = b3MakeVector3(-5.f,200,-40);//20,15,10);//-13,6,2);// = b3Vector3(0.5f,2,2); // lightPos.y+=0.1f; b3CreateOrtho(-shadowMapWorldSize,shadowMapWorldSize,-shadowMapWorldSize,shadowMapWorldSize,1,300,depthProjectionMatrix);//-14,14,-14,14,1,200, depthProjectionMatrix); float depthViewMatrix[4][4]; b3Vector3 center = b3MakeVector3(0,0,0); b3Vector3 up =b3MakeVector3(0,1,0); b3CreateLookAt(lightPos,center,up,&depthViewMatrix[0][0]); //b3CreateLookAt(lightPos,m_data->m_cameraTargetPosition,b3Vector3(0,1,0),(float*)depthModelViewMatrix2); GLfloat depthModelMatrix[4][4]; b3CreateDiagonalMatrix(1.f,depthModelMatrix); b3Matrix4x4Mul(depthViewMatrix, depthModelMatrix, depthModelViewMatrix); GLfloat depthMVP[4][4]; b3Matrix4x4Mul(depthProjectionMatrix,depthModelViewMatrix,depthMVP); GLfloat biasMatrix[4][4]={ 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 }; GLfloat depthBiasMVP[4][4]; b3Matrix4x4Mul(biasMatrix,depthMVP,depthBiasMVP); //float m_frustumZNear=0.1; //float m_frustumZFar=100.f; //b3CreateFrustum(-m_frustumZNear, m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar,(float*)depthProjectionMatrix); //b3CreateLookAt(lightPos,m_data->m_cameraTargetPosition,b3Vector3(0,0,1),(float*)depthModelViewMatrix); { B3_PROFILE("updateCamera"); updateCamera(); } err = glGetError(); b3Assert(err==GL_NO_ERROR); // glBindBuffer(GL_ARRAY_BUFFER, 0); { B3_PROFILE("glFlush2"); glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo); glFlush(); } err = glGetError(); b3Assert(err==GL_NO_ERROR); int totalNumInstances = 0; for (int i=0;i<m_graphicsInstances.size();i++) { totalNumInstances+=m_graphicsInstances[i]->m_numGraphicsInstances; } int curOffset = 0; GLuint lastBindTexture = 0; for (int i=0;i<m_graphicsInstances.size();i++) { b3GraphicsInstance* gfxObj = m_graphicsInstances[i]; if (gfxObj->m_numGraphicsInstances) { glActiveTexture(GL_TEXTURE0); GLuint curBindTexture = 0; if (gfxObj->m_texturehandle) curBindTexture = gfxObj->m_texturehandle; else curBindTexture = m_data->m_defaultTexturehandle; //if (lastBindTexture != curBindTexture) { glBindTexture(GL_TEXTURE_2D,curBindTexture); } lastBindTexture = curBindTexture; err = glGetError(); b3Assert(err==GL_NO_ERROR); // int myOffset = gfxObj->m_instanceOffset*4*sizeof(float); int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4); // int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3); glBindVertexArray(gfxObj->m_cube_vao); int vertexStride = 9*sizeof(float); int vertexBase = gfxObj->m_vertexArrayOffset*vertexStride; glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid*)vertexBase); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_maxShapeCapacityInBytes)); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE)); int uvoffset = 7*sizeof(float)+vertexBase; int normaloffset = 4*sizeof(float)+vertexBase; glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)uvoffset); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)normaloffset); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE)); glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*3*sizeof(float)+m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); glEnableVertexAttribArray(5); glEnableVertexAttribArray(6); glVertexAttribDivisorARB(0, 0); glVertexAttribDivisorARB(1, 1); glVertexAttribDivisorARB(2, 1); glVertexAttribDivisorARB(3, 0); glVertexAttribDivisorARB(4, 0); glVertexAttribDivisorARB(5, 1); glVertexAttribDivisorARB(6, 1); int indexCount = gfxObj->m_numIndices; int indexOffset = 0; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gfxObj->m_index_vbo); { B3_PROFILE("glDrawElementsInstanced"); if (gfxObj->m_primitiveType==B3_GL_POINTS) { glUseProgram(instancingShaderPointSprite); glUniformMatrix4fv(ProjectionMatrixPointSprite, 1, false, &projectionMatrix[0]); glUniformMatrix4fv(ModelViewMatrixPointSprite, 1, false, &modelviewMatrix[0]); glUniform1f(screenWidthPointSprite,m_screenWidth); //glUniform1i(uniform_texture_diffusePointSprite, 0); err = glGetError(); b3Assert(err==GL_NO_ERROR); glPointSize(20); #ifndef __APPLE__ glEnable(GL_POINT_SPRITE_ARB); // glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); #endif glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glDrawElementsInstanced(GL_POINTS, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances); } else { switch (renderMode) { case B3_DEFAULT_RENDERMODE: { glUseProgram(instancingShader); glUniformMatrix4fv(ProjectionMatrix, 1, false, &projectionMatrix[0]); glUniformMatrix4fv(ModelViewMatrix, 1, false, &modelviewMatrix[0]); glUniform1i(uniform_texture_diffuse, 0); glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances); break; } case B3_CREATE_SHADOWMAP_RENDERMODE: { glUseProgram(createShadowMapInstancingShader); glUniformMatrix4fv(createShadow_depthMVP, 1, false, &depthMVP[0][0]); glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances); break; } case B3_USE_SHADOWMAP_RENDERMODE: { glUseProgram(useShadowMapInstancingShader); glUniformMatrix4fv(useShadow_ProjectionMatrix, 1, false, &projectionMatrix[0]); glUniformMatrix4fv(useShadow_ModelViewMatrix, 1, false, &modelviewMatrix[0]); float MVP[16]; b3Matrix4x4Mul16(projectionMatrix,modelviewMatrix,MVP); glUniformMatrix4fv(useShadow_MVP, 1, false, &MVP[0]); glUniformMatrix4fv(useShadow_DepthBiasModelViewMatrix, 1, false, &depthBiasMVP[0][0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_data->m_shadowTexture); glUniform1i(useShadow_shadowMap,1); glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances); break; } default: { // b3Assert(0); } }; } //glDrawElementsInstanced(GL_LINE_LOOP, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances); } } curOffset+= gfxObj->m_numGraphicsInstances; } { B3_PROFILE("glFlush"); glFlush(); } if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE) { // writeTextureToPng(shadowMapWidth,shadowMapHeight,"shadowmap.png",4); m_data->m_shadowMap->disable(); glViewport(dims[0],dims[1],dims[2],dims[3]); } err = glGetError(); b3Assert(err==GL_NO_ERROR); { B3_PROFILE("glUseProgram(0);"); glUseProgram(0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindVertexArray(0); } err = glGetError(); b3Assert(err==GL_NO_ERROR); }
void SimpleCamera::getCameraViewMatrix(float viewMatrix[16]) const { b3CreateLookAt(m_data->m_cameraPosition,m_data->m_cameraTargetPosition,m_data->m_cameraUp,viewMatrix); }