void Scene::warmupCache(int numRecs) { int x, y; float point[3]; float normal[3]; for(int i = 0; i < numRecs; ++i) { x = rand() % windWidth; y = rand() % windHeight; int offset = (y*windWidth + x)*3; point[0] = objectCoords[offset]; point[1] = objectCoords[offset +1]; point[2] = objectCoords[offset +2]; normal[0] = objectNormals[offset]; normal[1] = objectNormals[offset +1]; normal[2] = objectNormals[offset +2]; /*std::cout << "generating record at: (" << x << ", " << y << ") with worldCoord: (" << point[0] << ", " << point[1] << ", " << point[2] << ") and normal: (" << normal[0] << ", " << normal[1] << ", " << normal[2] << ")" << std::endl;*/ generateRecord(point, normal); } }
size_t USBDataFilev2012::readBlock(const string& str, int index) { USBDataBlock* ptrBlock = (USBDataBlock*) (str.data() + index); size_t nLength = (size_t) ntohl(ptrBlock->nDataLength); TRACE("block length %d, code %d",nLength,ptrBlock->cDataCode); if (nLength + index > str.size()) { ERROR("bad block size"); throw USBDataFileException("bad block size"); } VTDRRecord* ptrRecord = NULL; char szBlockName[64] = { 0 }; VTDRRecord::gb2312toutf8((const char*) ptrBlock->cDataName, sizeof(ptrBlock->cDataName), szBlockName, 64); TRACE("blockName:%s",szBlockName); size_t n = 0; if (nLength == 0) { TRACE("skip block"); nDataBlockNumber++; } while (nLength > n) { ptrRecord = generateRecord((VTDRRecord::DataCode) ptrBlock->cDataCode); if (!ptrRecord) { throw USBDataFileException("generate record fail"); } n += ptrRecord->Read(str.data() + sizeof(USBDataBlock) + index + n); TRACE("Read:%d[Def:%d]",n,nLength); if (nLength < n) { ERROR("bad data size"); //throw USBDataFileException("bad data size"); } string buf; ptrRecord->Dump(buf); TRACE("\n%s",buf.c_str()); m_strDecodeText.append(buf); PushData(ptrRecord); }; return nLength + sizeof(USBDataBlock); }
void Scene::splatRecords() { /*irradianceRecord rec1, rec2, rec3; rec1.pos[0] = 2.1766; rec1.pos[1] = 1.8176; rec1.pos[2] = 5.1762; rec1.norm[0] = -.573576; rec1.norm[1] = 0; rec1.norm[2] = -.819152; rec1.irradiance[0] = 1; rec1.irradiance[1] = 0; rec1.irradiance[2] = 0; rec1.hmd = 1.0; records.clear(); records.push_back(rec1); */ float eye[3]; float eyedir[3]; float up[3] = {0.0, 1.0, 0.0}; view->getEye(eye); view->getCenter(eyedir); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, splatBufFBOID); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, splatTex, 0); glViewport(0, 0, windWidth, windHeight); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE);//add all the contributions together glUseProgram(splatProgram); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); viewProjSetup(eye, eyedir, up, 45.0, 1.0, defaultFront, defaultBack); float color[4] = {1, 0, 1, 1}; glPointSize(5); glColor4fv(color); //set up samplers glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, coordTexBase[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, coordTexBase[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, coordTexBase[2]); float ws[2] = {windWidth, windHeight}; std::cout << splatWindSizeUniform << std::endl; glUniform2fv(splatWindSizeUniform, 1, ws); glUniform1f(splatAUniform, a); glUniform1i(splatWorldPosUniform, 0); glUniform1i(splatWorldNormUniform, 1); glUniform1i(splatDiffuseUniform, 2); for(size_t i = 0; i < records.size(); ++i) { glUniform1f(splatUniform,records[i].hmd*a); glUniform1f(splatHmdUniform, records[i].hmd); glBegin(GL_QUADS); for(int j = 0; j < 4; ++j) { glVertexAttrib1f(splatAttribute, 3 - j); glNormal3fv(records[i].norm); glColor3fv(records[i].irradiance); glVertex3fv(records[i].pos); } glEnd(); } glFlush(); //glutSwapBuffers(); std::cout << records.size() << "records splatted" << std::endl; Helpers::getGLErrors("end of splat"); glIsShader(999); glIsTexture(222); std::cout << "after first records splatted " << timer.split() << std::endl; //now do another frag shader pass //now read the buffer back and to the CPU traversal glBindTexture(GL_TEXTURE_2D, splatTex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, splatBuffer); int startNewRecords = records.size(); float * newpos; float * newnorm; double modelviewmat[16]; double projectionmat[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelviewmat); matrix4x4 modmat(modelviewmat); glGetDoublev(GL_PROJECTION_MATRIX, projectionmat); matrix4x4 projmat(projectionmat); double identity[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; vector3d xyz, norm, eyeCoord, perpLeft, perpDown; float upv[3] = {0, 1, 0}, right[3] = {1, 0, 0}; vector3d upvec(upv); vector3d rightvec(right); vector3d botleft, topright; vector3d projbotLeft, projtopRight; float hmd; double x1, y1, z1, x2, y2, z2;//for gluproject GLint vp[4] = {0, 0, windWidth, windHeight}; int xmin, xmax, ymin, ymax; for(size_t y = 0; y < windHeight; ++y) { for(size_t x = 0; x < windWidth; ++x) { if(splatBuffer[(y*windWidth +x)*4 + 3] < a) { newpos = &objectCoords[(y*windWidth +x)*3]; newnorm = &objectNormals[(y*windWidth +x)*3]; generateRecord(newpos, newnorm); hmd = records.back().hmd; //do a simple cpusplat to update nearby weights //mimic the v and f shaders almost exactly xyz = vector3d(newpos); norm = vector3d(newnorm); eyeCoord = modmat.mult(xyz); perpLeft = (((eyeCoord.normalize()).cross(upvec)).normalize()).scale(a*hmd); perpDown = (((eyeCoord.normalize()).cross(rightvec)).normalize()).scale(a*hmd); botleft = eyeCoord + perpLeft + perpDown; topright = eyeCoord - perpLeft - perpDown; gluProject(botleft.xyz[0], botleft.xyz[1], botleft.xyz[2], identity, projectionmat, vp, &x1, &y1, &z1); gluProject(topright.xyz[0], topright.xyz[1], topright.xyz[2], identity, projectionmat, vp, &x2, &y2, &z2); //bottom left is actually bottom right // top right is actually top left //WTF!! xmin = std::max(0, int(x2)); xmax = std::min(int(windWidth), int(ceil(x1))); ymin = std::max(0, int(y1)); ymax = std::min(int(windHeight), int(ceil(y2))); //std::cout << "updating range: x1 x2, y1 y2: " << xmin << //' ' << xmax << ' ' << ymin << ' ' << ymax << std::endl; //splat the w coord int offset; float w, dist, sqrtnrm, dot; for(int fragy = ymin; fragy < ymax; ++fragy) { for(int fragx = xmin; fragx < xmax; ++fragx) { //compute distance: offset = (fragy*windWidth + fragx)*3; dist = sqrt(pow(newpos[0] - objectCoords[offset], 2) + pow(newpos[1] - objectCoords[offset+1],2)+ pow(newpos[2] - objectCoords[offset+2],2)); if(dist >= a*hmd) continue; dot = newnorm[0]*objectNormals[offset] + newnorm[1]*objectNormals[offset +1] + newnorm[2]*objectNormals[offset +2]; dot = std::min(1.0f, dot); sqrtnrm = sqrt(1.0 - dot); w = 1.0/((dist/hmd) + sqrtnrm); if (w >= 1.0/a) { splatBuffer[(fragy*windWidth +fragx)*4 + 3] += w; } } } } } } std::cout << "cpu traversal" << timer.split() << std::endl; std::cout << "about to splat new records" << std::endl; glUseProgram(splatProgram); //splat the newly added records for(size_t i = startNewRecords; i < records.size(); ++i) { glUniform1f(splatUniform,records[i].hmd*a); glUniform1f(splatHmdUniform, records[i].hmd); glBegin(GL_QUADS); for(int j = 0; j < 4; ++j) { glVertexAttrib1f(splatAttribute, 3 - j); glNormal3fv(records[i].norm); glColor3fv(records[i].irradiance); glVertex3fv(records[i].pos); } glEnd(); } std::cout << records.size() - startNewRecords << " new records created" << std::endl; glFlush(); }