/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/BPointSeq.h" //#include "mg/Pvector.h" //#include "mg/AttribedGel.h" //#include "mg/DNameControl.h" //#include "mg/Curve.h" #include "mgGL/Texture.h" #include "mgGL/OpenGLView.h" #include "mgGL/glslprogram.h" #include "mgGL/VBOLeafBuilder.h" //#include "mgGL/VBO.h" #include "mgGL/VBOLeaf.h" namespace{static const float white[4]={1.,1.,1.,1.};}//Highlight back color. namespace{ GLenum glErr;}; //////////////////////// mgVBOLeaf ////////////////////////////// mgVBOLeaf::mgVBOLeaf() :m_vertexArrayID(0),m_size(1.),m_color(MGColor::UNDEFINED), // TODO Check!! m_bufferID(0), m_count(0),m_primitiveMode(0),m_texture(0),m_drawType(mgGLSL::Primitive),//m_functionID(0), m_ColorSpecified(false),m_NormalSpecified(false),m_TextureSpecified(false) ,m_stippleFactor(-1),m_LineStipplePattern(0),m_lightMode(-1){ ; } mgVBOLeaf::mgVBOLeaf(GLfloat size,MGColor& color) :m_vertexArrayID(0),m_size(size),m_color(color), m_bufferID(0), m_count(0),m_primitiveMode(0),m_texture(0),m_drawType(mgGLSL::Primitive),//m_functionID(0), m_ColorSpecified(false),m_NormalSpecified(false),m_TextureSpecified(false) ,m_stippleFactor(-1),m_LineStipplePattern(0),m_lightMode(-1){ ; } mgVBOLeaf::mgVBOLeaf(const mgVBOLeaf& vbol) :m_vertexArrayID(0),m_size(vbol.m_size),m_color(vbol.m_color), m_bufferID(0),m_count(0),m_primitiveMode(0),m_texture(0),m_drawType(mgGLSL::Primitive),//m_functionID(0), m_ColorSpecified(false),m_NormalSpecified(false),m_TextureSpecified(false) ,m_stippleFactor(vbol.m_stippleFactor),m_LineStipplePattern(vbol.m_LineStipplePattern) ,m_lightMode(vbol.m_lightMode){ ; } mgVBOLeaf::mgVBOLeaf(const mgVBOLeafBuilder& builder) :m_vertexArrayID(0),m_size(builder.sizeStatic()),m_color(builder.colorStatic()), m_bufferID(0),m_primitiveMode(builder.typeBegin()), m_texture(builder.getTexture()),m_drawType(builder.getDrawType()),//m_functionID(builder.getFunctionID()), m_ColorSpecified(false),m_NormalSpecified(false),m_TextureSpecified(false) ,m_stippleFactor(builder.m_stippleFactor) ,m_LineStipplePattern(builder.m_LineStipplePattern),m_lightMode(builder.m_lightMode){ //HGLRC hRC = ::wglGetCurrentContext(); //HDC hDC = ::wglGetCurrentDC(); //std::cout<<"VBOLeaf:: wglDC, HDC "<< hDC <<"," << hRC << std::endl; m_count=(unsigned)builder.m_VertexData.size(); if(m_count==0) return; if(m_primitiveMode==GL_QUAD_STRIP) m_primitiveMode=GL_TRIANGLE_STRIP; glErr=glGetError(); glGenBuffers(1,&m_bufferID); if((glErr=glGetError()) != GL_NO_ERROR){ CString msg(gluErrorString(glErr)); COUT<<"mgVBOLeaf::constructor::glGenBuffers::"<<(TCAST)msg<=m_count){ m_ColorSpecified=true; sizeC=baseSize*4; sizeTotal+=sizeC; } if(builder.m_NormalData.size()>=m_count){ m_NormalSpecified=true; sizeN=baseSize*3; sizeTotal+=sizeN; } if(builder.m_TextureData.size()>=m_count){ m_TextureSpecified=true; sizeT=baseSize*2; sizeTotal+=sizeT; } glBindBuffer(GL_ARRAY_BUFFER,m_bufferID); glBufferData(GL_ARRAY_BUFFER,sizeTotal,0,GL_STATIC_DRAW); //vPosition for(unsigned i=0; i0.){ //Point size if(viewMode==MGCL::HIGHLIGHT){ glDisable(GL_PROGRAM_POINT_SIZE); glPointSize(size); }else{ glEnable(GL_PROGRAM_POINT_SIZE); glslP->setUniform(mgGLSLProgram::pointSize,size); } }else if(m_primitiveMode==GL_LINES || m_primitiveMode==GL_LINE_STRIP || m_primitiveMode==GL_LINE_LOOP){ //Line width mgGLSL::execStaticLineWidth(size); mgGLSL::execStaticLineStipple(m_stippleFactor,m_LineStipplePattern); }else{ //Polygon mode(m_size defines what kinds of polygon mode be applied). if(m_size<0.) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); else if(m_size<=m_PolygonModePointSizeBase){ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glLineWidth(size); }else{ glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); glPointSize(m_size-m_PolygonModePointSizeBase); } } } ///描画関数draw()は、is_made()であれば、作成し、表示処理をする。 ///!is_made()(描画データ作成済み)であれば、すでに作成されたmgVBOElementの描画を行う。 ///mgVBOLeafでは常に作成すみであり表示処理をおこなう。 void mgVBOLeaf::draw(MGCL::VIEWMODE viewMode) { if(is_no_display()) return; if(m_bufferID==0) return; if(m_vertexArrayID==0) glGenVertexArrays(1,&m_vertexArrayID); glBindVertexArray(m_vertexArrayID); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); // glsl->setUniform(mgGLSLProgram::functionID, m_functionID); glsl->setUniform(mgGLSLProgram::DrawType, m_drawType); if(texture_is_bound()) m_texture->use(); glBindBuffer(GL_ARRAY_BUFFER,m_bufferID); assert(glIsBuffer(m_bufferID)); int vPositionLoc=mgGLSLProgram::vPosition; glVertexAttribPointer(vPositionLoc,3,GL_FLOAT,GL_FALSE,0,(GLvoid*)0); glEnableVertexAttribArray(vPositionLoc); mgGLSL::pushStaticGLAttrib(); execStaticAttrib(viewMode,false); unsigned offset=0; unsigned baseSize=sizeof(float)*m_count; offset+=baseSize*3; if(m_ColorSpecified){ int vColorLoc=mgGLSLProgram::vColor; glVertexAttribPointer(vColorLoc,4,GL_FLOAT,GL_FALSE,0,(GLvoid*)offset); glEnableVertexAttribArray(vColorLoc); offset+=baseSize*4; } if(m_NormalSpecified){ int vNormalLoc=glsl->getvNormalLocation(); if(vNormalLoc>=0){ glVertexAttribPointer(vNormalLoc,3,GL_FLOAT,GL_FALSE,0,(GLvoid*)offset); glEnableVertexAttribArray(vNormalLoc); } offset+=baseSize*3; } if(m_TextureSpecified){ int vTextureLoc=glsl->getvTextureCoordLocation(); if(vTextureLoc>=0){ glVertexAttribPointer(vTextureLoc,2,GL_FLOAT,GL_FALSE,0,(GLvoid*)offset); glEnableVertexAttribArray(vTextureLoc); } } glDrawArrays(m_primitiveMode,0,(GLsizei)m_count); mgGLSL::popStaticGLAttrib(); glBindBuffer(GL_ARRAY_BUFFER,0); }; ///描画関数selectionDraw()は、Object選択のための表示処理をする。 ///通常のdrawとの相違:///Colorとしてm_bufferIDを用い、size処理以外の ///attributesの処理(normal, texture, color)をしない。 void mgVBOLeaf::selectionDraw(MGCL::VIEWMODE viewMode){ if(is_no_display()) return; if(m_bufferID==0) return; if(m_vertexArrayID==0) glGenVertexArrays(1,&m_vertexArrayID); glBindVertexArray(m_vertexArrayID); glBindBuffer(GL_ARRAY_BUFFER,m_bufferID); assert(glIsBuffer(m_bufferID)); int vPositionLoc=mgGLSLProgram::vPosition; glVertexAttribPointer(vPositionLoc,3,GL_FLOAT,GL_FALSE,0,(GLvoid*)0); glEnableVertexAttribArray(vPositionLoc); execStaticAttrib(viewMode,true); glDrawArrays(m_primitiveMode,0,(GLsizei)m_count); glBindBuffer(GL_ARRAY_BUFFER,0); }; ///m_primitiveMode=GL_QUAD_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN ///のときにのみ有効でそのPolygonMode(GL_POINT, GL_LINE, GL_FILL)を指定する. ///setPolygonModeしていないmgVBOLeafはGL_FILLとされる。 void mgVBOLeaf::setPolygonMode(GLenum mode){ if(m_primitiveMode==GL_TRIANGLES || m_primitiveMode==GL_TRIANGLE_STRIP || m_primitiveMode==GL_TRIANGLE_FAN){ GLfloat size=m_size; if(size>m_PolygonModePointSizeBase) size-=m_PolygonModePointSizeBase; else if(size<0.) size*=-1.; if(mode==GL_FILL){ m_size=-size; }else if(mode==GL_POINT){ m_size=size+m_PolygonModePointSizeBase; }else m_size=size; } } void mgVBOLeaf::setLightMode(int mode){ m_lightMode=mode; } ///Line stipple属性をセットする。 ///When factor=0 is input, line pattern is disabled. This means the line is solid. ///When factor<0, the stipple attribute is undefined. This means the attribute ///is defined by the environment. ///When factor<=0, pattern is unnecessary. void mgVBOLeaf::setLineStipple(short int factor, GLushort pattern){ m_stippleFactor=factor; m_LineStipplePattern=pattern; } void mgVBOLeaf::setStaticAttribLineWidth( GLfloat size///size<=0. はundefinedを示す ){ m_size=size; } void mgVBOLeaf::setStaticAttribPointSize( GLfloat size///size<=0. はundefinedを示す ){ m_size=size; } ///作成済のmgVBOLeafのIDの位置のVertex dataをPのデータに置き換える。 ///0<= ID & Ps){ int num=(int)Ps.size();assert(startID+num<=m_count); float* area=new float[num*3]; //vPosition update. for(int i=0, i3=0; igetTextureID()!=0) return true; } return false; }