//----------------------------------------------------------------------------- // Shader - Shader From a Buffer //----------------------------------------------------------------------------- bool shader::loadBuffer( const char* buffer, int length, int shaderType ) { GLint shaderStatus(0); GLuint shaderId( 0 ); if ( !programId ) { programId = glCreateProgram(); if ( !programId ) { std::cerr << "ERROR: Unable to create a shader program." << std::endl; return false; } } shaderId = glCreateShader( shaderType ); // Fragment shader or Vertex Shader glShaderSource( shaderId, 1, (const GLchar**)&buffer, (const GLint*)&length ); glCompileShader( shaderId ); glGetShaderiv( shaderId, GL_COMPILE_STATUS, &shaderStatus ); if ( shaderStatus != GL_TRUE ) { printShaderError( 0, shaderId ); return false; } glAttachShader( programId, shaderId ); shaderIds.push_back( shaderId ); printGlError("General shader loading error"); return true; }
/****************************************************************************** * Main ******************************************************************************/ int main() { if ( !init() ) { terminate(); return -1; } hge::window& pWindow = gameSystem::getSystemWindow(); pLogic->startRunning(); pRenderer->startRunning(); while ( pLogic->isRunning() && !pWindow.wantsToClose() ) { pLogic->tick(); pRenderer->tick(); pWindow.flip(); } pRenderer->stopRunning(); printGlError("Post main-loop error"); terminate(); return 0; }
/****************************************************************************** * dsLightSphere light initialization ******************************************************************************/ void dsLightSphere::setLightBuffer( const dsPointLight* lights, unsigned lightCount ) { glBindBuffer( GL_ARRAY_BUFFER, vbo[1] ); glBufferData( GL_ARRAY_BUFFER, lightCount * sizeof( dsPointLight ), nullptr, GL_DYNAMIC_DRAW ); glBufferSubData( GL_ARRAY_BUFFER, 0, lightCount * sizeof( dsPointLight ), lights ); printGlError( "Error while uploading point light parameter data."); numInstances = lightCount; }
/****************************************************************************** * dsLightSphere light Manipulation ******************************************************************************/ void dsLightSphere::setLight( unsigned index, const dsPointLight& pl ) { HL_ASSERT( index < numInstances ); glBindBuffer( GL_ARRAY_BUFFER, vbo[1] ); glBufferSubData( GL_ARRAY_BUFFER, index * sizeof( dsPointLight ), sizeof( dsPointLight ), &pl ); printGlError( "Error while uploading point light data."); }
//----------------------------------------------------------------------------- // Shader - Compilation //----------------------------------------------------------------------------- bool shader::compile() { if (shaderIds.empty()) { std::cerr << "WARNING: Attempted to compile a shader program without input" << std::endl; return false; } GLint shaderStatus(0); glLinkProgram(programId); glGetProgramiv(programId, GL_LINK_STATUS, &shaderStatus); if (shaderStatus != GL_TRUE) { std::cerr << "\nWARNING: A GLSL Shader Error has occurred\n"; for ( int i = 0; i < shaderIds.size(); ++i ) printShaderError(programId, shaderIds[ i ]); return false; } printGlError("Error compiling shader"); return true; }
bool dsLightSphere::init() { terminate(); std::vector< vec3 > vertices( 60 ); { std::vector< GLuint > indices = { 0,11,5, 0,5,1, 0,1,7, 0,7,10, 0,10,11, 1,5,9, 5,11,4, 11,10,2, 10,7,6, 7,1,8, 3,9,4, 3,4,2, 3,2,6, 3,6,8, 3,8,9, 4,9,5, 2,4,11, 6,2,10, 8,6,7, 9,8,1 }; // 60 elements // build an icosahedron const float t = (1.f + sqrt(5.f))/2.f; //const float s = 1.f / sqrt(1.f + t*t); // create the 12 vertices std::vector< vec3 > points = { vec3(-1.f, t, 0.f), vec3(1.f, t, 0.f), vec3(-1.f, -t, 0.f), vec3(1.f, -t, 0.f), vec3(0.f, -1.f, t), vec3(0.f, 1.f, t), vec3(0.f, -1.f, -t), vec3(0.f, 1.f, -t), vec3(t, 0.f, -1.f), vec3(t, 0.f, 1.f), vec3(-t, 0.f, -1.f), vec3(-t, 0.f, 1.f) }; // create 20 triangles (60 vertices) for( unsigned i = 0; i < indices.size(); ++i ) { vertices[i] = points[ indices[i] ]; } vertices = std::move( subdivide( vertices ) ); } if (!vao) { glGenVertexArrays( 1, &vao ); } if (!vbo[0]) { glGenBuffers( 2, vbo ); } if ( !vao || !vbo[0] || !vbo[1] ) { std::cerr << "An error occurred while initializing the sphere primitives" << std::endl; terminate(); return false; } glBindVertexArray( vao ); glBindBuffer( GL_ARRAY_BUFFER, vbo[0] ); // Subdivided icosahedrons have been measured to use 240 vertices glBufferData( GL_ARRAY_BUFFER, sizeof(vec3)*240, vertices.data(), GL_STATIC_DRAW ); printGlError( "Error while sending sphere primitive data to the GPU."); glEnableVertexAttribArray( pipeline::HGE_ATTRIB_VERTEX ); glEnableVertexAttribArray( pipeline::HGE_ATTRIB_TEXTURE ); glVertexAttribPointer( pipeline::HGE_ATTRIB_VERTEX, ARRAY_COUNT_FROM_SIZE( vec3::v ), GL_FLOAT, GL_FALSE, sizeof( vec3 ), (GLvoid*)offsetof( vec3, v ) ); /* * Begin Setting instanced attributes */ glBindBuffer( GL_ARRAY_BUFFER, vbo[1] ); glBufferData( GL_ARRAY_BUFFER, sizeof( dsPointLight ), nullptr, GL_DYNAMIC_DRAW ); /* Set the scaling data location */ glEnableVertexAttribArray( SCALE_ATTRIB ); glEnableVertexAttribArray( POS_ATTRIB ); glEnableVertexAttribArray( COLOR_ATTRIB ); glEnableVertexAttribArray( PARAM_ATTRIB ); glVertexAttribPointer( SCALE_ATTRIB, 1, GL_FLOAT, GL_FALSE, sizeof( dsPointLight ), (GLvoid*)offsetof( dsPointLight, dsPointLight::scale ) ); glVertexAttribDivisor( SCALE_ATTRIB, 1 ); /* Set the position data location */ glVertexAttribPointer( POS_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof( dsPointLight ), (GLvoid*)offsetof( dsPointLight, dsPointLight::position ) ); glVertexAttribDivisor( POS_ATTRIB, 1 ); /* Set the color data location */ glVertexAttribPointer( COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof( dsPointLight ), (GLvoid*)offsetof( dsPointLight, dsPointLight::color ) ); glVertexAttribDivisor( COLOR_ATTRIB, 1 ); /* Set the light attribute data location */ glVertexAttribPointer( PARAM_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof( dsPointLight ), (GLvoid*)offsetof( dsPointLight, dsPointLight::attributes ) ); glVertexAttribDivisor( PARAM_ATTRIB, 1 ); printGlError( "Error while setting light attribute information."); glBindVertexArray( 0 ); return true; }
void printGlError(GLenum err, const std::string& situation) { printGlError(err, situation.c_str()); }
void checkForGlError(const char* situation) { printGlError(glGetError(), situation); }
void render_gl() { const glVec WHITE_COLOR(1.0f,1.0f,1.0f,1.0f); const glVec GREY_COLOR(0.6f,0.6f,0.6f,0.6f); const glVec I_COLOR(1.0f,0.0f,0.0f,1.0f); const glVec J_COLOR(0.0f,1.0f,0.0f,1.0f); const glVec L_COLOR(0.0f,0.0f,1.0f,1.0f); const glVec O_COLOR(1.0f,1.0f,0.0f,1.0f); const glVec S_COLOR(1.0f,0.0f,1.0f,1.0f); const glVec T_COLOR(0.0f,1.0f,1.0f,1.0f); const glVec Z_COLOR(0.5f,1.0f,0.5f,1.0f); const DataBuffer &gameState=GAME_STATE.buffer.swap_and_read(); SDL_GL_SwapBuffers(); printGlError(); glClear(GL_COLOR_BUFFER_BIT); // Draw blocks set in field glUniform4fv(GL_STATE.tintUniform, 1, GREY_COLOR.data); for(unsigned i=0;i<FIELD_WIDTH;++i) { for(unsigned j=0;j<FIELD_VIEW_HEIGHT;++j) { if(gameState.field.get(i,j)) { glUniform2f(GL_STATE.offsetUniform,(GLfloat)i,(GLfloat)j); glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0); } } } // Draw current piece arrayt blocks=gameState.current.getBlocks(); switch(gameState.current.getType()) { case I: glUniform4fv(GL_STATE.tintUniform, 1, I_COLOR.data); break; case J: glUniform4fv(GL_STATE.tintUniform, 1, J_COLOR.data); break; case L: glUniform4fv(GL_STATE.tintUniform, 1, L_COLOR.data); break; case O: glUniform4fv(GL_STATE.tintUniform, 1, O_COLOR.data); break; case S: glUniform4fv(GL_STATE.tintUniform, 1, S_COLOR.data); break; case T: glUniform4fv(GL_STATE.tintUniform, 1, T_COLOR.data); break; case Z: glUniform4fv(GL_STATE.tintUniform, 1, Z_COLOR.data); break; default: std::cerr << "Unhandled case in enumerated switch statement!\n"; break; } for(auto block : blocks) { glUniform2f(GL_STATE.offsetUniform,(GLfloat)block.x,(GLfloat)block.y); glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0); } }