Shader * Shader::loadShader(string name) { Shader * s = new Shader(); for (int i = 0; i < 5; i++) name.pop_back(); s->name = name; string vertPath = name + ".vert"; string fragPath = name + ".frag"; //Start with a handle for the shader program... GLhandleARB shaderProgramHandle = glCreateProgramObjectARB (); //glBindAttribLocation (shaderProgramHandle, 0, "mg_vertex"); //glBindAttribLocation (shaderProgramHandle, 1, "uv"); // use glGetAttribLocation instead GLhandleARB vertObject = makeShader(vertPath.c_str(), GL_VERTEX_SHADER); GLhandleARB fragObject = makeShader(fragPath.c_str(), GL_FRAGMENT_SHADER); glAttachObjectARB(shaderProgramHandle, vertObject); glAttachObjectARB(shaderProgramHandle, fragObject); glLinkProgramARB (shaderProgramHandle); //Find out if compilation worked and return the program handle if it did... int status; glGetObjectParameterivARB (shaderProgramHandle, GL_OBJECT_LINK_STATUS_ARB, &status); if (status != 0) { //return shaderProgramHandle; //Everything OK... s->shaderProgram = shaderProgramHandle; s->vertexShader = vertObject; s->fragmentShader = fragObject; return s; } //It didn't, so log error information... //::log ("\nFailed to link shader \"%s\"...", name.c_str ()); int length = 0; glGetObjectParameterivARB (shaderProgramHandle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); glBindFragDataLocation(shaderProgramHandle, 0, "outColour"); const long MAXIMUM_LOG_STRING = 1024; char logString [MAXIMUM_LOG_STRING]; GLsizei messageLength = min (length, MAXIMUM_LOG_STRING); if (messageLength > 0) { glGetInfoLogARB (shaderProgramHandle, messageLength, 0, logString); } //and detach what was previously attached and discard the program handle that was obtained... glDetachObjectARB(shaderProgramHandle, fragObject); glDetachObjectARB(shaderProgramHandle, vertObject); glDeleteObjectARB (shaderProgramHandle); //Should also detach the attached handles... return NULL; }
ShaderManager::ShaderProgram* ShaderManager::makeShaderProgram(const char* programName, const char* vertexShaderFile, const char* fragmentShaderFile){ //Create the shaders with filename as name Shader* vsShader = makeShader(vertexShaderFile, Vertex, vertexShaderFile); Shader* fsShader = makeShader(fragmentShaderFile, Fragment, fragmentShaderFile); if( vsShader == 0 || fsShader == 0 ) return 0; ShaderProgram* newProgram = new ShaderProgram(); shaderPrograms.insert(ShaderProgramContainer::value_type(programName, newProgram)); newProgram->attachShader(vsShader); newProgram->attachShader(fsShader); return newProgram; }
static int initShaders(void){ vertex_shader = makeShader( GL_VERTEX_SHADER, "noop.v.glsl"); if (vertex_shader == 0) return 0; fragment_shader = makeShader( GL_FRAGMENT_SHADER, "noop.f.glsl"); if (fragment_shader == 0) return 0; program = makeProgram(vertex_shader, fragment_shader); if (program == 0) return 0; glUseProgram(program); }
static void draw_gradients(SkCanvas* canvas, sk_sp<SkShader> (*makeShader)(const SkPoint[2], const SkMatrix&), const SkPoint ptsArray[][2], int numImages) { // Use some nice prime numbers for the rectangle and matrix with // different scaling along the x and y axes (which is the bug this // test addresses, where incorrect order of operations mixed up the axes) SkRect rectGrad = { SkIntToScalar(43), SkIntToScalar(61), SkIntToScalar(181), SkIntToScalar(167) }; SkMatrix shaderMat; shaderMat.setScale(rectGrad.width(), rectGrad.height()); shaderMat.postTranslate(rectGrad.left(), rectGrad.top()); canvas->save(); for (int i = 0; i < numImages; i++) { // Advance line downwards if necessary. if (i % IMAGES_X == 0 && i != 0) { canvas->restore(); canvas->translate(0, TESTGRID_Y); canvas->save(); } SkPaint paint; paint.setShader(makeShader(*ptsArray, shaderMat)); canvas->drawRect(rectGrad, paint); // Advance to next position. canvas->translate(TESTGRID_X, 0); ptsArray++; } canvas->restore(); }
DEF_TEST(serial_procs_picture, reporter) { auto p1 = make_pic([](SkCanvas* c) { // need to be large enough that drawPictures doesn't "unroll" us for (int i = 0; i < 20; ++i) { c->drawColor(SK_ColorRED); } }); // now use custom serialization auto p0 = make_pic([](SkCanvas* c) { c->drawColor(SK_ColorBLUE); }); test_pictures(reporter, p0, 1, false); // test inside effect p0 = make_pic([p1](SkCanvas* c) { SkPaint paint; SkTileMode tm = SkTileMode::kClamp; paint.setShader(p1->makeShader(tm, tm)); c->drawPaint(paint); }); test_pictures(reporter, p0, 1, true); // test nested picture p0 = make_pic([p1](SkCanvas* c) { c->drawColor(SK_ColorRED); c->drawPicture(p1); c->drawColor(SK_ColorBLUE); }); test_pictures(reporter, p0, 1, true); }
//----------------------------------------------------------------------------- // compil //----------------------------------------------------------------------------- int Shader::compil( const char *vertex, const char *fragment ) { m_program = glCreateProgramObjectARB(); if( !makeShader(vertex, GL_VERTEX_SHADER_ARB) ) { //QMessageBox::critical(NULL, "Error", "Can't compil the vertex shader !"); return SHADER_VERTEX_ERROR; } if( !makeShader(fragment, GL_FRAGMENT_SHADER_ARB) ) { //QMessageBox::critical(NULL, "Error", "Can't compil this pixel shader !"); return SHADER_FRAGMENT_ERROR; } glLinkProgram(m_program); return SHADER_SUCCESS; }
int main(int argc, char **argv) { EnumGenerator::generate2(); // qDebug() << Enum::__ENUM_CLASS::Item0.name(); // qDebug() << ListEnum::Item0.id() << ListEnum::Item0.toString(); // Test t = Test::v1; // Test::v1.key(); QCoreApplication app(argc, argv); makeShader(); // EnumGenerator::generate(); return 0; }
GLuint compile_shaders(void) { GLuint program; int result = 0; program = glCreateProgram(); makeShader(GL_VERTEX_SHADER, "Shaders/VertexShader.vert", program); //makeShader(GL_TESS_CONTROL_SHADER, "TessControlShader.glsl", program); //makeShader(GL_TESS_EVALUATION_SHADER, "TessEvalShader.glsl", program); //makeShader(GL_GEOMETRY_SHADER, "GeomShader.glsl", program); makeShader(GL_FRAGMENT_SHADER, "Shaders/FragmentShader.frag", program); glLinkProgram(program); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPointSize(5.0f); return program; }
QTestWindow() { setSurfaceType(QSurface::OpenGLSurface); QSurfaceFormat format; // Qt Quick may need a depth and stencil buffer. Always make sure these are available. format.setDepthBufferSize(16); format.setStencilBufferSize(8); format.setVersion(4, 3); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setOption(QSurfaceFormat::DebugContext); format.setSwapInterval(0); setFormat(format); _qGlContext.setFormat(format); _qGlContext.create(); show(); makeCurrent(); setupDebugLogger(this); gpu::Context::init<gpu::GLBackend>(); _context = std::make_shared<gpu::Context>(); auto shader = makeShader(unlit_vert, unlit_frag, gpu::Shader::BindingSet{}); auto state = std::make_shared<gpu::State>(); state->setMultisampleEnable(true); state->setDepthTest(gpu::State::DepthTest { true }); _pipeline = gpu::Pipeline::create(shader, state); // Clear screen gpu::Batch batch; batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLORS, { 1.0, 0.0, 0.5, 1.0 }); _context->render(batch); DependencyManager::set<GeometryCache>(); DependencyManager::set<DeferredLightingEffect>(); resize(QSize(800, 600)); _time.start(); }
void PtexViewer::render(int selx, int sely) { if (!_shaderProgram) makeShader(); if (_options.bgColorLight) glClearColor(0.8,0.8,0.8,1); else glClearColor(0.0,0.0,0.0,1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); float width = vp[2]; float height = vp[3]; float winasp = width/height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); bool selectMode = selx>=0 && sely>=0; if (selectMode) gluPickMatrix((double)selx,(double)vp[3]-sely,3,3,vp); if (!_mode3d||_displayFace>=0) { float sc = _cam.getDistance()/2; glOrtho(-sc, sc, -sc/winasp, sc/winasp, -100, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(-_cam.getLookAt()[0],-_cam.getLookAt()[1],-_cam.getLookAt()[2]); } else { _cam.applyProjectionTransform(winasp, _bounds); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); _cam.applyModelViewTransform(); } glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0,1.0); glColor4f(1.0, 1.0, 1.0, 1.0); glUseProgramObjectARB(_shaderProgram); _geometry.draw(_displayFace); glUseProgramObjectARB(0); if (!selectMode && _options.showGridLines) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glColor4f(0.0, 0.0, 0.0, 0.25); _geometry.draw(_displayFace); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_DEPTH_TEST); if (selectMode) return; // Display text information char str[64]; if (_options.bgColorLight) glColor3f(0.0, 0.0, 0.0); else glColor3f(0.9, 0.9, 0.9); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!_options.envMode) { if (_numFaces==1) strcpy(str, "1 face"); else sprintf(str,"%i faces",_numFaces); renderChars(-0.8,-0.92,GLUT_BITMAP_8_BY_13,str); if (_displayFace>=0 && _numFaces!=1) { sprintf(str,"Face ID: %i",_displayFace); renderChars(-0.8,0.92,GLUT_BITMAP_8_BY_13,str); } if (_numFaces==1) { int ures = _geometry.getFace(0)->ures; int vres = _geometry.getFace(0)->vres; sprintf(str,"Res: %i x %i",ures,vres); renderChars(-0.8,0.92,GLUT_BITMAP_8_BY_13,str); } else if (_displayFace>=0) { int ures = _geometry.getFace(_displayFace)->ures; int vres = _geometry.getFace(_displayFace)->vres; sprintf(str,"Face Res: %i x %i",ures,vres); renderChars(-0.2,0.92,GLUT_BITMAP_8_BY_13,str); } renderChars(0.25,-0.92,GLUT_BITMAP_8_BY_13,(char*)_typeStr.c_str()); } }
void DisplayOzone::drawWithTexture(Buffer *buffer) { FunctionsGL *gl = mFunctionsGL; StateManagerGL *sm = getRenderer()->getStateManager(); if (!mProgram) { const GLchar *vertexSource = "#version 100\n" "attribute vec3 vertex;\n" "uniform vec2 center;\n" "uniform vec2 windowSize;\n" "uniform vec2 borderSize;\n" "uniform float depth;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " vec2 pos = vertex.xy * (windowSize + borderSize * vertex.z);\n" " gl_Position = vec4(center + pos, depth, 1);\n" " texCoord = vec3(pos / windowSize * vec2(.5, -.5) + vec2(.5, .5), vertex.z);\n" "}\n"; const GLchar *fragmentSource = "#version 100\n" "precision mediump float;\n" "uniform sampler2D tex;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " if (texCoord.z > 0.)\n" " {\n" " float c = abs((texCoord.z * 2.) - 1.);\n" " gl_FragColor = vec4(c, c, c, 1);\n" " }\n" " else\n" " {\n" " gl_FragColor = texture2D(tex, texCoord.xy);\n" " }\n" "}\n"; mVertexShader = makeShader(GL_VERTEX_SHADER, vertexSource); mFragmentShader = makeShader(GL_FRAGMENT_SHADER, fragmentSource); mProgram = gl->createProgram(); gl->attachShader(mProgram, mVertexShader); gl->attachShader(mProgram, mFragmentShader); gl->bindAttribLocation(mProgram, 0, "vertex"); gl->linkProgram(mProgram); GLint linked; gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked); ASSERT(linked); mCenterUniform = gl->getUniformLocation(mProgram, "center"); mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize"); mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize"); mDepthUniform = gl->getUniformLocation(mProgram, "depth"); GLint texUniform = gl->getUniformLocation(mProgram, "tex"); sm->useProgram(mProgram); gl->uniform1i(texUniform, 0); // clang-format off const GLfloat vertices[] = { // window corners, and window border inside corners 1, -1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0, // window border outside corners 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, }; // clang-format on gl->genBuffers(1, &mVertexBuffer); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // window border triangle strip const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0}; gl->genBuffers(1, &mIndexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW); } else { sm->useProgram(mProgram); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); } // convert from pixels to "-1 to 1" space const NativeWindow *n = buffer->getNative(); double x = n->x * 2. / mWidth - 1; double y = n->y * 2. / mHeight - 1; double halfw = n->width * 1. / mWidth; double halfh = n->height * 1. / mHeight; double borderw = n->borderWidth * 2. / mWidth; double borderh = n->borderHeight * 2. / mHeight; gl->uniform2f(mCenterUniform, x + halfw, y + halfh); gl->uniform2f(mWindowSizeUniform, halfw, halfh); gl->uniform2f(mBorderSizeUniform, borderw, borderh); gl->uniform1f(mDepthUniform, n->depth / 1e6); sm->setBlendEnabled(false); sm->setCullFaceEnabled(false); sm->setStencilTestEnabled(false); sm->setScissorTestEnabled(false); sm->setDepthTestEnabled(true); sm->setColorMask(true, true, true, true); sm->setDepthMask(true); sm->setDepthRange(0, 1); sm->setDepthFunc(GL_LESS); sm->setViewport(gl::Rectangle(0, 0, mWidth, mHeight)); sm->activeTexture(0); GLuint tex = buffer->getTexture(); sm->bindTexture(GL_TEXTURE_2D, tex); gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); gl->enableVertexAttribArray(0); sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB()); gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->drawElements(GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_INT, 0); sm->deleteTexture(tex); }
void SetupRC() { SpriteManager *sprites = SpriteManager::instance(); Vector p(0.0f,0.0f,-1.0f); player = new Player("resources/Models/cube.ogl", p); sprites->AddSprite( player); std::string filename="resources/Models/cube.ogl"; test = new Model(filename); /* Vector v((GLfloat)(0), (GLfloat)(0), (GLfloat) (5) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v) ); */ for (int i=0; i<30; i++) { Vector v((GLfloat)(0), (GLfloat)(i *3 ), (GLfloat) (10) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v, i*8, i*2, i*5) ); } glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); shader.vertexShader = makeShader( GL_VERTEX_SHADER, "resources/Shaders/identity.vs"); if(shader.vertexShader == 0){ printf("failed to make vertex shader"); exit(0); } shader.fragmentShader = makeShader(GL_FRAGMENT_SHADER, "resources/Shaders/identity.fs"); if(shader.fragmentShader == 0){ printf("failed to make fragment shader"); exit(0); } shader.program = makeProgram(shader.vertexShader, shader.fragmentShader); if(shader.program == 0){ printf("failed to make program"); exit(0); } shader.uniforms.colour = glGetUniformLocation( shader.program, "colour"); if( shader.uniforms.colour == -1){ printf( "failed to locate uniform colour location"); exit(0); } shader.uniforms.modelViewProjectionMatrix = glGetUniformLocation(shader.program, "modelViewProjectionMatrix"); if( shader.uniforms.modelViewProjectionMatrix == -1){ printf("failed to locate uniform modelViewProjectionMatrix"); exit(0); } shader.attributes.pos = glGetAttribLocation( shader.program, "position"); }
DrawTexture::DrawTexture(uint32_t width, uint32_t height, const char* const szArgs, const std::string sBasePath) : GL3LoadTestSample(width, height, szArgs, sBasePath) { std::string filename; GLfloat* pfQuadTexCoords = quad_texture; GLfloat fTmpTexCoords[sizeof(quad_texture)/sizeof(GLfloat)]; GLenum target; GLboolean isMipmapped; GLenum glerror; GLubyte* pKvData; GLuint kvDataLen; GLint sign_s = 1, sign_t = 1; GLint i; GLuint gnColorFs, gnDecalFs, gnVs; GLsizeiptr offset; KTX_dimensions dimensions; KTX_error_code ktxresult; KTX_hash_table kvtable; bInitialized = false; gnTexture = 0; filename = getAssetPath() + szArgs; ktxresult = ktxLoadTextureN(filename.c_str(), &gnTexture, &target, &dimensions, &isMipmapped, &glerror, &kvDataLen, &pKvData); if (KTX_SUCCESS == ktxresult) { ktxresult = ktxHashTable_Deserialize(kvDataLen, pKvData, &kvtable); if (KTX_SUCCESS == ktxresult) { GLchar* pValue; GLuint valueLen; if (KTX_SUCCESS == ktxHashTable_FindValue(kvtable, KTX_ORIENTATION_KEY, &valueLen, (void**)&pValue)) { char s, t; if (sscanf(pValue, /*valueLen,*/ KTX_ORIENTATION2_FMT, &s, &t) == 2) { if (s == 'l') sign_s = -1; if (t == 'd') sign_t = -1; } } ktxHashTable_Destroy(kvtable); free(pKvData); } if (sign_s < 0 || sign_t < 0) { // Transform the texture coordinates to get correct image // orientation. int iNumCoords = sizeof(quad_texture) / sizeof(float); for (i = 0; i < iNumCoords; i++) { fTmpTexCoords[i] = quad_texture[i]; if (i & 1) { // odd, i.e. a y coordinate if (sign_t < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } else { // an x coordinate if (sign_s < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } } pfQuadTexCoords = fTmpTexCoords; } uTexWidth = dimensions.width; uTexHeight = dimensions.height; if (isMipmapped) // Enable bilinear mipmapping. // TO DO: application can consider inserting a key,value pair in // the KTX file that indicates what type of filtering to use. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); assert(GL_NO_ERROR == glGetError()); } else { std::stringstream message; message << "Load of texture from \"" << filename << "\" failed: "; if (ktxresult == KTX_GL_ERROR) { message << std::showbase << "GL error " << std::hex << glerror << " occurred."; } else { message << ktxErrorString(ktxresult); } throw std::runtime_error(message.str()); } glClearColor(0.4f, 0.4f, 0.5f, 1.0f); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &gnVbo); glBindBuffer(GL_ARRAY_BUFFER, gnVbo); // Create the buffer data store glBufferData(GL_ARRAY_BUFFER, sizeof(frame_position) + sizeof(frame_color) + sizeof(quad_position) + sizeof(quad_color) + sizeof(quad_texture), NULL, GL_STATIC_DRAW); glGenVertexArrays(2, gnVaos); // Interleave data copying and attrib pointer setup so offset is only // computed once. // Setup VAO and buffer the data for frame glBindVertexArray(gnVaos[FRAME]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_position), frame_position); glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_color), frame_color); glVertexAttribPointer(1, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_color); // Setup VAO for quad glBindVertexArray(gnVaos[QUAD]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_position), quad_position); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_color), quad_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_texture), pfQuadTexCoords); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); glBindVertexArray(0); try { makeShader(GL_VERTEX_SHADER, pszVs, &gnVs); makeShader(GL_FRAGMENT_SHADER, pszColorFs, &gnColorFs); makeProgram(gnVs, gnColorFs, &gnColProg); gulMvMatrixLocCP = glGetUniformLocation(gnColProg, "mvmatrix"); gulPMatrixLocCP = glGetUniformLocation(gnColProg, "pmatrix"); makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs); makeProgram(gnVs, gnDecalFs, &gnTexProg); } catch (std::exception& e) { (void)e; // To quiet unused variable warnings from some compilers. throw; } gulMvMatrixLocTP = glGetUniformLocation(gnTexProg, "mvmatrix"); gulPMatrixLocTP = glGetUniformLocation(gnTexProg, "pmatrix"); gulSamplerLocTP = glGetUniformLocation(gnTexProg, "sampler"); glUseProgram(gnTexProg); // We're using the default texture unit 0 glUniform1i(gulSamplerLocTP, 0); glDeleteShader(gnVs); glDeleteShader(gnColorFs); glDeleteShader(gnDecalFs); // Set the quad's mv matrix to scale by the texture size. // With the pixel-mapping ortho projection set below, the texture will // be rendered at actual size just like DrawTex*OES. quadMvMatrix = glm::scale(glm::mat4(), glm::vec3((float)uTexWidth / 2, (float)uTexHeight / 2, 1)); assert(GL_NO_ERROR == glGetError()); bInitialized = true; }
void atInitialize_01_draw_texture(void** ppAppData, const char* const szArgs, const char* const szBasePath) { const char* filename; GLfloat* pfQuadTexCoords = quad_texture; GLfloat fTmpTexCoords[sizeof(quad_texture)/sizeof(GLfloat)]; GLuint texture = 0; GLenum target; GLboolean isMipmapped; GLenum glerror; GLubyte* pKvData; GLuint kvDataLen; GLint sign_s = 1, sign_t = 1; GLint i; GLuint gnColorFs, gnDecalFs, gnVs; GLsizeiptr offset; KTX_dimensions dimensions; KTX_error_code ktxerror; KTX_hash_table kvtable; DrawTexture* pData = (DrawTexture*)atMalloc(sizeof(DrawTexture), 0); atAssert(pData); atAssert(ppAppData); *ppAppData = pData; pData->bInitialized = GL_FALSE; pData->gnTexture = 0; filename = atStrCat(szBasePath, szArgs); if (filename != NULL) { ktxerror = ktxLoadTextureN(filename, &pData->gnTexture, &target, &dimensions, &isMipmapped, &glerror, &kvDataLen, &pKvData); if (KTX_SUCCESS == ktxerror) { ktxerror = ktxHashTable_Deserialize(kvDataLen, pKvData, &kvtable); if (KTX_SUCCESS == ktxerror) { GLchar* pValue; GLuint valueLen; if (KTX_SUCCESS == ktxHashTable_FindValue(kvtable, KTX_ORIENTATION_KEY, &valueLen, (void**)&pValue)) { char s, t; if (sscanf(pValue, /*valueLen,*/ KTX_ORIENTATION2_FMT, &s, &t) == 2) { if (s == 'l') sign_s = -1; if (t == 'd') sign_t = -1; } } ktxHashTable_Destroy(kvtable); free(pKvData); } if (sign_s < 0 || sign_t < 0) { // Transform the texture coordinates to get correct image orientation. int iNumCoords = sizeof(quad_texture) / sizeof(float); for (i = 0; i < iNumCoords; i++) { fTmpTexCoords[i] = quad_texture[i]; if (i & 1) { // odd, i.e. a y coordinate if (sign_t < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } else { // an x coordinate if (sign_s < 1) { fTmpTexCoords[i] = fTmpTexCoords[i] * -1 + 1; } } } pfQuadTexCoords = fTmpTexCoords; } pData->iTexWidth = dimensions.width; pData->iTexHeight = dimensions.height; if (isMipmapped) /* Enable bilinear mipmapping */ /* TO DO: application can consider inserting a key,value pair in the KTX * that indicates what type of filtering to use. */ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); atAssert(GL_NO_ERROR == glGetError()); } else { char message[1024]; int maxchars = sizeof(message)/sizeof(char); int nchars; nchars = snprintf(message, maxchars, "Load of texture \"%s\" failed: ", filename); maxchars -= nchars; if (ktxerror == KTX_GL_ERROR) { nchars += snprintf(&message[nchars], maxchars, "GL error %#x occurred.", glerror); } else { nchars += snprintf(&message[nchars], maxchars, "%s.", ktxErrorString(ktxerror)); } atMessageBox(message, "Texture load failed", AT_MB_OK|AT_MB_ICONERROR); pData->iTexWidth = pData->iTexHeight = 50; pData->gnTexture = 0; } atFree((void*)filename, NULL); } /* else Out of memory. In which case, a message box is unlikely to work. */ glClearColor(0.4f, 0.4f, 0.5f, 1.0f); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &pData->gnVbo); glBindBuffer(GL_ARRAY_BUFFER, pData->gnVbo); // Create the buffer data store glBufferData(GL_ARRAY_BUFFER, sizeof(frame_position) + sizeof(frame_color) + sizeof(quad_position) + sizeof(quad_color) + sizeof(quad_texture), NULL, GL_STATIC_DRAW); glGenVertexArrays(2, pData->gnVaos); // Interleave data copying and attrib pointer setup so offset is only computed once. // Setup VAO and buffer the data for frame glBindVertexArray(pData->gnVaos[FRAME]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_position), frame_position); glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(frame_color), frame_color); glVertexAttribPointer(1, 3, GL_BYTE, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(frame_color); // Setup VAO for quad glBindVertexArray(pData->gnVaos[QUAD]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_position), quad_position); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_position); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_color), quad_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(quad_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(quad_texture), pfQuadTexCoords); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); glBindVertexArray(0); if (makeShader(GL_VERTEX_SHADER, pszVs, &gnVs)) { if (makeShader(GL_FRAGMENT_SHADER, pszColorFs, &gnColorFs)) { if (makeProgram(gnVs, gnColorFs, &pData->gnColProg)) { pData->gulMvMatrixLocCP = glGetUniformLocation(pData->gnColProg, "mvmatrix"); pData->gulPMatrixLocCP = glGetUniformLocation(pData->gnColProg, "pmatrix"); } } if (makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs)) { if (makeProgram(gnVs, gnDecalFs, &pData->gnTexProg)) { pData->gulMvMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "mvmatrix"); pData->gulPMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "pmatrix"); pData->gulSamplerLocTP = glGetUniformLocation(pData->gnTexProg, "sampler"); glUseProgram(pData->gnTexProg); // We're using the default texture unit 0 glUniform1i(pData->gulSamplerLocTP, 0); } } glDeleteShader(gnVs); glDeleteShader(gnColorFs); glDeleteShader(gnDecalFs); } // Set the quad's mv matrix to scale by the texture size. // With the pixel-mapping ortho projection set below, the texture will // be rendered at actual size just like DrawTex*OES. for (i = 0; i < 16; i++) { pData->fQuadMvMatrix[i] = atIdentity[i]; pData->fFrameMvMatrix[i] = atIdentity[i]; } pData->fQuadMvMatrix[0*4 + 0] = (float)pData->iTexWidth / 2; pData->fQuadMvMatrix[1*4 + 1] = (float)pData->iTexHeight / 2; atAssert(GL_NO_ERROR == glGetError()); pData->bInitialized = GL_TRUE; }
int main(int argc, char ** argv) { auto pathToRom = std::string(); if (argc == 2) { pathToRom = argv[1]; } else { printf("Chip8 Error: Wrong number of arguments\n"); return -1; } sf::SoundBuffer beepSnd; if (! beepSnd.loadFromFile("data/sounds/beep.wav")) { printf("Chip8 Error: Can't load the beeping sound.\n"); return -1; } sf::Sound sndSrc; sndSrc.setBuffer(beepSnd); sndSrc.setLoop(false); auto window = setupWindow(WIDTH, HEIGHT, TITLE); cee::Chip8 chip; chip.loadProgram(readAllBytes(pathToRom.c_str())); constexpr GLfloat pxVerts[] = { -1.0f, 1.0f, 0.0f, // Top Left 1.0f, 1.0f, 0.0f, // Top Right -1.0f, -1.0f, 0.0f, // Bottom Left 1.0f, -1.0f, 0.0f // Bottom Right }; constexpr GLuint pxIndices[] = { 0, 1, 2, 2, 1, 3 }; // Initialize the VAO and other buffers associated // with drawing an emulated pixel. GLuint vao, vbo, ibo; glGenVertexArrays(1, &vao); glBindVertexArray(vao); { glGenBuffers(1, &vbo); glGenBuffers(1, &ibo); // VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(pxVerts), &pxVerts, GL_STATIC_DRAW); // IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pxIndices), &pxIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); } glBindVertexArray(0); // Current Vertex Shader const auto pxVertexSrc = readAllChars("data/shaders/px_vertex.glsl"); const auto pxVertex = makeShader(GL_VERTEX_SHADER, pxVertexSrc); // Current Fragment Shader const auto pxFragmentSrc = readAllChars("data/shaders/px_fragment.glsl"); const auto pxFragment = makeShader(GL_FRAGMENT_SHADER, pxFragmentSrc); // Current Shader Program const auto pxProgram = makeProgram({pxVertex, pxFragment}); glUseProgram(pxProgram); glfwShowWindow(window); while (! glfwWindowShouldClose(window)) { chip.updateKeys(getKeyStates(window)); chip.updateCycle(); if (chip.isBeeping() && sndSrc.getStatus() != sf::SoundSource::Playing) sndSrc.play(); // Clear back buffer and background color. glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glBindVertexArray(vao); const auto gfx = chip.getGfx(); for (int i = 0; i < 32; ++i) { // Maps the width resolution [0-HEIGHT] to [-1.0-1.0] auto y = - mapRangeHeight(i); auto l = i * 64; for (int j = 0; j < 64; ++j) { if (gfx[l + j] == 1) { // Maps the width resolution [0-WIDTH] to [-1.0-1.0] auto x = mapRangeWidth(j); auto ident = glGetUniformLocation(pxProgram, "PxModel"); auto model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(x, y, 0.0f)); model = glm::scale(model, glm::vec3(PX_WIDTH, PX_HEIGHT, 1.0f)); glUniformMatrix4fv(ident, 1, GL_FALSE, glm::value_ptr(model)); glDrawElements(GL_TRIANGLES, sizeof(pxIndices), GL_UNSIGNED_INT, nullptr); } } } glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); } // Cleanup resources glDeleteProgram(pxProgram); glDeleteShader(pxVertex); glDeleteShader(pxFragment); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &vbo); glfwTerminate(); return 0; }
void meshModels::cacheCylinder(float vertsX[], float vertsY[], float depth) { dir = TRUE; cacheEndCap( vertsX, vertsY, 0.0f); dir = FALSE; cacheEndCap( vertsX, vertsY, depth); dir = FALSE; // objects to build our vertices in vertex_t vertA, vertB, vertC; polygon_t poly; int i = 0; int j; int faceCount; // find out how many verts we have int vcount = model.verts.size(); int endGon = vcount; // and saving the starting vertice index for later //record all three points as a triangle in our structure poly.a = vcount; poly.b = vcount +1; poly.c = vcount +2; // we need to start with two verts because then //we only need to add 2 verts to get 2 new triangles in the for loop // build our first vertex vertA.x = vertsX[i]; vertA.y = vertsY[i]; vertA.z = 0.0f; // push it into our array model.verts.reserve(poly.a); model.verts.push_back(vertA); //build our third vertex vertB.x = vertsX[i]; vertB.y = vertsY[i]; vertB.z = depth; // push it into our array model.verts.reserve(poly.b); model.verts.push_back(vertB); i++; // build a cylinder 2 triangles at a time for( j = 0; j < 62; ++j) { // ensure our array iterator is not too large if(i>=32) i = 0; //record all three points as a triangle in our structure poly.a = vcount; poly.b = vcount +1; poly.c = vcount +2; //build our second vertex vertC.x = vertsX[i]; vertC.y = vertsY[i]; vertC.z = 0.0f; // push it into our array model.verts.reserve(poly.c); model.verts.push_back(vertC); // record the triangle model.polys.reserve(j); model.polys.push_back(poly); faceCount = model.polys.size()-1; calculateFaceNormal(faceCount); j++; // advance to the next polygon // vertex A is really the old vertex b so lets record the change here poly.a = poly.b; vertB.x = vertsX[i]; vertB.y = vertsY[i]; vertB.z = depth; poly.b = model.verts.size(); // set the iterator for the new vertex model.verts.reserve(poly.b); model.verts.push_back(vertB); // VertC is the same and remains unchanged // lets store our triangle model.polys.reserve(j); model.polys.push_back(poly); faceCount = model.polys.size()-1; calculateFaceNormal(faceCount); vcount = vcount +2; i++; } // add our last two triangles using existing verts poly.a = model.verts.size() - 2; poly.b = model.verts.size() - 1; poly.c = endGon; model.polys.reserve(vcount); model.polys.push_back(poly); faceCount = model.polys.size()-1; calculateFaceNormal(faceCount); // add our last two triangles using existing verts poly.a = model.verts.size() - 1; poly.b = endGon + 1; poly.c = endGon; model.polys.reserve(vcount + 1); model.polys.push_back(poly); faceCount = model.polys.size()-1; calculateFaceNormal(faceCount); normalizeVerts(); makeShader(); makeBuffer(); }
void atInitialize_02_cube(void** ppAppData, const char* const args) { GLuint texture = 0; GLenum target; GLenum glerror; GLboolean isMipmapped; GLuint gnDecalFs, gnVs; GLsizeiptr offset; KTX_error_code ktxerror; CubeTextured* pData = (CubeTextured*)atMalloc(sizeof(CubeTextured), 0); atAssert(pData); atAssert(ppAppData); *ppAppData = pData; pData->bInitialized = GL_FALSE; pData->gnTexture = 0; ktxerror = ktxLoadTextureN(args, &texture, &target, NULL, &isMipmapped, &glerror, 0, NULL); if (KTX_SUCCESS == ktxerror) { if (target != GL_TEXTURE_2D) { /* Can only draw 2D textures */ glDeleteTextures(1, &texture); return; } if (isMipmapped) /* Enable bilinear mipmapping */ /* TO DO: application can consider inserting a key,value pair in the KTX * file that indicates what type of filtering to use. */ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); else glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); atAssert(GL_NO_ERROR == glGetError()); } else { char message[1024]; int maxchars = sizeof(message)/sizeof(char); int nchars; nchars = snprintf(message, maxchars, "Load of texture \"%s\" failed: %s.", args, ktxErrorString(ktxerror)); if (ktxerror == KTX_GL_ERROR) { maxchars -= nchars; nchars += snprintf(&message[nchars], maxchars, " GL error is %#x.", glerror); } atMessageBox(message, "Texture load failed", AT_MB_OK|AT_MB_ICONERROR); } /* By default dithering is enabled. Dithering does not provide visual improvement * in this sample so disable it to improve performance. */ glDisable(GL_DITHER); glEnable(GL_CULL_FACE); glClearColor(0.2f,0.3f,0.4f,1.0f); // Create a VAO and bind it. glGenVertexArrays(1, &pData->gnVao); glBindVertexArray(pData->gnVao); // Must have vertex data in buffer objects to use VAO's on ES3/GL Core glGenBuffers(1, &pData->gnVbo); glBindBuffer(GL_ARRAY_BUFFER, pData->gnVbo); // Must be done after the VAO is bound // Use the same buffer for vertex attributes and element indices. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pData->gnVbo); // Create the buffer data store. glBufferData(GL_ARRAY_BUFFER, sizeof(cube_face) + sizeof(cube_color) + sizeof(cube_texture) + sizeof(cube_normal) + sizeof(cube_index_buffer), NULL, GL_STATIC_DRAW); // Interleave data copying and attrib pointer setup so offset is only computed once. glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_face), cube_face); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_face); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_color), cube_color); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_color); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_texture), cube_texture); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_texture); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_normal), cube_normal); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)offset); offset += sizeof(cube_normal); pData->iIndicesOffset = offset; // Either of the following can be used to buffer the data. glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cube_index_buffer), cube_index_buffer); //glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, sizeof(cube_index_buffer), cube_index_buffer); if (makeShader(GL_VERTEX_SHADER, pszVs, &gnVs)) { if (makeShader(GL_FRAGMENT_SHADER, pszDecalFs, &gnDecalFs)) { if (makeProgram(gnVs, gnDecalFs, &pData->gnTexProg)) { pData->gulMvMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "mvmatrix"); pData->gulPMatrixLocTP = glGetUniformLocation(pData->gnTexProg, "pmatrix"); pData->gulSamplerLocTP = glGetUniformLocation(pData->gnTexProg, "sampler"); glUseProgram(pData->gnTexProg); // We're using the default texture unit 0 glUniform1i(pData->gulSamplerLocTP, 0); } } glDeleteShader(gnVs); glDeleteShader(gnDecalFs); } atAssert(GL_NO_ERROR == glGetError()); pData->bInitialized = GL_TRUE; }