void test_quad_textured(int shadow, int cfunc) { GLint width, height; GLuint textures[2], texture_handle; GLfloat vVertices[] = { // front -0.45, -0.75, 0.0, 0.45, -0.75, 0.0, -0.45, 0.75, 0.0, 0.45, 0.75, 0.0 }; GLfloat vTexCoords[] = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, }; EGLSurface surface; RD_START("quad-textured", "shadow=%d, cfunc=%x", shadow, cfunc); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 255, 255); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); printf("EGL Version %s\n", eglQueryString(display, EGL_VERSION)); printf("EGL Vendor %s\n", eglQueryString(display, EGL_VENDOR)); printf("EGL Extensions %s\n", eglQueryString(display, EGL_EXTENSIONS)); printf("GL Version %s\n", glGetString(GL_VERSION)); printf("GL extensions: %s\n", glGetString(GL_EXTENSIONS)); program = get_program(vertex_shader_source, shadow ? fragment_shader_source_shadow : fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "in_position")); GCHK(glBindAttribLocation(program, 1, "in_TexCoord")); link_program(program); GCHK(glViewport(0, 0, width, height)); /* clear the color buffer */ GCHK(glClearColor(0.5, 0.5, 0.5, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords)); GCHK(glEnableVertexAttribArray(1)); GCHK(glGenTextures(2, &textures)); GCHK(glActiveTexture(GL_TEXTURE0)); GCHK(glBindTexture(GL_TEXTURE_2D, textures[0])); if (shadow) { GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cube_texture.width/2, cube_texture.height/2, 0, GL_DEPTH_COMPONENT, GL_FLOAT, cube_texture.pixel_data)); } else { GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, cube_texture.width, cube_texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, cube_texture.pixel_data)); } GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)); if (shadow) { #define GL_TEXTURE_COMPARE_MODE 0x884C #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_COMPARE_REF_TO_TEXTURE 0x884E GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, cfunc)); } else { float minlod = cfunc, maxlod = cfunc; GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, minlod)); GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, maxlod)); switch (cfunc) { case 0: GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); break; case 1: GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); break; case 2: GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); break; case 3: GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR)); break; case 4: GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); break; #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif case 5: GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4)); break; case 6: GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8)); break; case 7: GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16)); break; case 8: GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 32)); break; case 9: GCHK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 320)); break; } } GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */ GCHK(glActiveTexture(GL_TEXTURE1)); GCHK(glBindTexture(GL_TEXTURE_2D, textures[1])); GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cube_texture.width/3, cube_texture.height-1, 0, GL_RGBA, GL_UNSIGNED_BYTE, cube_texture.pixel_data+1)); /* Note: cube turned black until these were defined. */ GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)); GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glUniform1i(texture_handle, 1)); /* '1' refers to texture unit 1. */ GCHK(glEnable(GL_CULL_FACE)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); sleep(1); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
int main(void) { // set error callback glfwSetErrorCallback(error_callback); // init environment glfwInit(); // check GLFW and GLES version // glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); // create window context GLFWwindow *window = glfwCreateWindow(640, 480, "untitled_1", NULL, NULL); glfwSetFramebufferSizeCallback(window, reshape_callback); glfwMakeContextCurrent(window); glfwSwapInterval(1); // load dynamic gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); // show current OpenGL variables printf("GL_VERSION : %s\n", glGetString(GL_VERSION)); printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); // shader GLuint vertex_shader = create_shader(GL_VERTEX_SHADER, vertex_shader_text); GLuint fragment_shader = create_shader(GL_FRAGMENT_SHADER, fragment_shader_text); GLuint program = link_program(vertex_shader, fragment_shader); // load data from application to gpu GLuint vertex_buffer; glGenBuffers(1, &vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); GLint mvp_location = glGetUniformLocation(program, "MVP"); GLint vpos_location = glGetAttribLocation(program, "vPosition"); GLint vcol_location = glGetAttribLocation(program, "vColor"); glEnableVertexAttribArray((GLuint) vpos_location); glVertexAttribPointer((GLuint) vpos_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void *) 0); glEnableVertexAttribArray((GLuint) vcol_location); glVertexAttribPointer((GLuint) vcol_location, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void *) (sizeof(float) * 2)); // uint32_t counter = 0; float angle = 0; // main loop, keep running while (!glfwWindowShouldClose(window)) { int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT); float ratio = (float) width / height; // mat4x4 m, p, mvp; mat4x4_identity(m); mat4x4_rotate_Z(m, m, angle); // 构建旋转矩阵 counter += 1; if (counter < 100) { angle += 0.01; } else if ((counter < 200)) { angle -= 0.02; } else { counter = 0; } // mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); // 处理缩放 mat4x4_mul(mvp, p, m); // 组合旋转+缩放 // apply shader glUseProgram(program); // Specify the value of a uniform variable for the current program object glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat *) mvp); // draw glDrawArrays(GL_TRIANGLES, 0, 3); // window has two buffers, one for display, another for render // after render, we need to swap them to display glfwSwapBuffers(window); // process events glfwPollEvents(); } // destroy glfwDestroyWindow(window); glfwTerminate(); return 0; }
/* Run through multiple variants to detect clear color, quad color (frag * shader param), and vertices */ void test_tex(int nvtex, int nftex, int bcolor) { GLint width, height; EGLint pbuffer_attribute_list[] = { EGL_WIDTH, 256, EGL_HEIGHT, 256, EGL_LARGEST_PBUFFER, EGL_TRUE, EGL_NONE }; GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0}; GLfloat vertices[] = { -0.45, -0.75, 0.0, 0.45, -0.75, 0.0, -0.45, 0.75, 0.0, 0.45, 0.75, 0.0 }; GLfloat bcolors[][4] = { { 0.25, 0.50, 0.75, 1.0 }, { 1.00, 0.00, 0.00, 1.0 }, { 0.00, 1.00, 0.00, 1.0 }, { 0.00, 0.00, 1.00, 1.0 }, }; EGLSurface surface; int n; RD_START("tex", "%d vtex, %d ftex, bcolor=%d", nvtex, nftex, bcolor); ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list)); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("PBuffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source[nvtex], fragment_shader_source[nftex]); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glViewport(0, 0, width, height)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glEnableVertexAttribArray(0)); /* now set up our uniforms/textures. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glUniform4fv(uniform_location, 1, quad_color)); for (n = 0; n < max(nvtex, nftex); n++) { GLuint texturename = 0, texture_handle; static char name[8]; GCHK(glActiveTexture(tex_enums[n])); GCHK(glGenTextures(1, &texturename)); GCHK(glBindTexture(GL_TEXTURE_2D, texturename)); GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, cube_texture.width, cube_texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, cube_texture.pixel_data)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); if (bcolor) { GCHK(glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR_EXT, bcolors[n])); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_EXT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_EXT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, GL_CLAMP_TO_BORDER_EXT)); } else { GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, GL_REPEAT)); } sprintf(name, "uTex%d", n+1); GCHK(texture_handle = glGetUniformLocation(program, name)); GCHK(glUniform1i(texture_handle, n)); } GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GCHK(glFlush()); ECHK(eglSwapBuffers(display, surface)); ECHK(eglDestroySurface(display, surface)); GCHK(glFlush()); RD_END(); }
void test_triangle_quad(void) { EGLDisplay display; EGLConfig config; EGLint num_config; EGLContext context; EGLSurface surface; GLuint program; GLint width, height; int uniform_location; const char *vertex_shader_source = "precision mediump float; \n" "attribute vec4 aPosition; \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" "} \n"; const char *fragment_shader_source = "precision mediump float; \n" "uniform vec4 uColor; \n" " \n" "void main() \n" "{ \n" " gl_FragColor = uColor; \n" "} \n"; GLfloat vertices[] = { /* triangle */ -0.8, 0.50, 0.0, -0.2, 0.50, 0.0, -0.5, -0.50, 0.0, /* quad */ 0.2, -0.50, 0.0, 0.8, -0.50, 0.0, 0.2, 0.50, 0.0, 0.8, 0.50, 0.0 }; GLfloat triangle_color[] = {0.0, 1.0, 0.0, 1.0 }; GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0 }; DEBUG_MSG("----------------------------------------------------------------"); RD_START("triangle-quad", ""); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list)); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("PBuffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); GCHK(glFlush()); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glViewport(0, 0, width, height)); GCHK(glFlush()); /* clear the color buffer */ GCHK(glClearColor(0.3125, 0.3125, 0.3125, 1.0)); GCHK(glFlush()); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glFlush()); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glFlush()); GCHK(glEnableVertexAttribArray(0)); GCHK(glFlush()); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glUniform4fv(uniform_location, 1, triangle_color)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLES, 0, 3)); GCHK(glFlush()); GCHK(glUniform4fv(uniform_location, 1, quad_color)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 3, 4)); GCHK(glFlush()); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); usleep(1000000); RD_END(); }
bool load_shaders(ResourceManager* resources, const char* baseFilename, Program* programStruct) { Log("Loading shader: %s", baseFilename); check_gl_error(); // Create shader program. GLuint program = glCreateProgram(); programStruct->program = program; // Load vertex shader. circa::Value vertShaderPathname; circa_set_string(&vertShaderPathname, baseFilename); circa_string_append(&vertShaderPathname, ".vsh"); circa::Value vertShader; resources->loadAsText(circa_string(&vertShaderPathname), &vertShader); if (circa_is_error(&vertShader) || !circa_is_string(&vertShader)) { Log("Failed to load vertex shader: %v", &vertShaderPathname); return false; } // Compile vertex shader circa::Value vertShaderIndex; compile_shader(GL_VERTEX_SHADER, &vertShader, &vertShaderIndex); if (circa_is_error(&vertShaderIndex)) { Log("Failed to compile vertex shader:", &vertShaderPathname); return false; } // Load fragment shader circa::Value fragShaderPathname; circa_set_string(&fragShaderPathname, baseFilename); circa_string_append(&fragShaderPathname, ".fsh"); circa::Value fragShader; resources->loadAsText(circa_string(&fragShaderPathname), &fragShader); if (circa_is_error(&fragShader) || !circa_is_string(&fragShader)) { Log("Failed to load fragment shader:", &fragShaderPathname); return false; } // Compile fragment shader circa::Value fragShaderIndex; compile_shader(GL_FRAGMENT_SHADER, &fragShader, &fragShaderIndex); check_gl_error(); if (circa_is_error(&fragShaderIndex)) { Log("Failed to compile frag shader: %v", &fragShaderPathname); return false; } int vertShaderHandle = circa_int(&vertShaderIndex); int fragShaderHandle = circa_int(&fragShaderIndex); // Attach vertex shader to program. glAttachShader(program, vertShaderHandle); check_gl_error(); // Attach fragment shader to program. glAttachShader(program, fragShaderHandle); check_gl_error(); // Link program. if (!link_program(program)) { Log("Failed to link shaders: %s", baseFilename); glDeleteShader(vertShaderHandle); glDeleteShader(fragShaderHandle); if (program) { glDeleteProgram(program); program = 0; } check_gl_error(); return false; } check_gl_error(); // Get attribute locations programStruct->attributes.vertex = glGetAttribLocation(program, "vertex"); programStruct->attributes.tex_coord = glGetAttribLocation(program, "tex_coord"); check_gl_error(); // Get uniform locations. programStruct->uniforms.modelViewProjectionMatrix = glGetUniformLocation(program, "modelViewProjectionMatrix"); programStruct->uniforms.normalMatrix = glGetUniformLocation(program, "normalMatrix"); programStruct->uniforms.sampler = glGetUniformLocation(program, "sampler"); programStruct->uniforms.sampler2 = glGetUniformLocation(program, "sampler2"); programStruct->uniforms.color = glGetUniformLocation(program, "color"); programStruct->uniforms.blend = glGetUniformLocation(program, "blend"); check_gl_error(); return true; }
/* Run through multiple variants to detect mrt settings */ static void test(unsigned w, unsigned h, unsigned cpp, GLenum ifmt, GLenum fmt, GLenum type, int mipmap) { GLint width, height; GLuint fbo, fbotex; GLenum mrt_bufs[] = {GL_COLOR_ATTACHMENT0}; GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0}; GLfloat vertices[] = { -0.45, -0.75, 0.1, 0.45, -0.75, 0.1, -0.45, 0.75, 0.1, 0.45, 0.75, 0.1 }; EGLSurface surface; //////////////////////////////////////////// // calculate ubwc layout, see: // https://android.googlesource.com/platform/hardware/qcom/display/+/master/msm8996/libgralloc/alloc_controller.cpp#1057 unsigned block_width, block_height; switch (cpp) { case 2: case 4: block_width = 16; block_height = 4; break; case 8: block_width = 8; block_height = 4; break; case 16: block_width = 4; block_height = 4; break; default: DEBUG_MSG("invalid cpp: %u", cpp); return; } // div_round_up(): unsigned aligned_height = (h + block_height - 1) / block_height; unsigned aligned_width = (w + block_width - 1) / block_width; // Align meta buffer height to 16 blocks unsigned meta_height = ALIGN(aligned_height, 16); // Align meta buffer width to 64 blocks unsigned meta_width = ALIGN(aligned_width, 64); // Align meta buffer size to 4K unsigned meta_size = ALIGN((meta_width * meta_height), 4096); //////////////////////////////////////////// RD_START(mipmap ? "ubwc-layout-mipmap" : "ubwc-layout", "%dx%d, ifmt=%s, fmt=%s, type=%s, meta=%ux%u@0x%x (%ux%u)", w, h, formatname(fmt), formatname(ifmt), typename(type), meta_width, meta_height, meta_size, aligned_width, aligned_height); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, w, h); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glGenFramebuffers(1, &fbo)); GCHK(glGenTextures(1, &fbotex)); GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo)); GCHK(glBindTexture(GL_TEXTURE_2D, fbotex)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GCHK(glTexImage2D(GL_TEXTURE_2D, 0, ifmt, width, height, 0, fmt, type, 0)); GCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbotex, 0)); DEBUG_MSG("status=%04x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo)); GCHK(glViewport(0, 0, width, height)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glEnableVertexAttribArray(0)); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glDrawBuffers(1, mrt_bufs)); // glClearColor(0.25, 0.5, 0.75, 1.0); // GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glUniform4fv(uniform_location, 1, quad_color)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); /* clear any errors, in case it wasn't a renderable format: */ while (glGetError() != GL_NO_ERROR) {} GCHK(glFlush()); /* switch back to back buffer: */ GCHK(glBindFramebuffer(GL_FRAMEBUFFER, 0)); program = get_program(vertex_shader_source_sam, fragment_shader_source_sam); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glActiveTexture(GL_TEXTURE0)); GCHK(glBindTexture(GL_TEXTURE_2D, fbotex)); if (mipmap) { GCHK(glGenerateMipmap(GL_TEXTURE_2D)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)); } else { GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); } GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT)); GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */ GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
void test_triangle_quad(int samples, int depth, int stencil) { EGLDisplay display; EGLConfig config; EGLint num_config; EGLContext context; EGLSurface surface; GLuint program; GLint width, height; int uniform_location; const char *vertex_shader_source = "precision mediump float; \n" "attribute vec4 aPosition; \n" " \n" "void main() \n" "{ \n" " gl_Position = aPosition; \n" "} \n"; const char *fragment_shader_source = "precision mediump float; \n" "uniform vec4 uColor; \n" " \n" "void main() \n" "{ \n" " gl_FragColor = uColor; \n" "} \n"; EGLint const config_attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_STENCIL_SIZE, stencil, EGL_DEPTH_SIZE, depth, EGL_SAMPLES, samples, EGL_NONE }; GLfloat vertices[] = { /* triangle */ -0.8, 0.50, 0.0, -0.2, 0.50, 0.0, -0.5, -0.50, 0.0, /* quad */ 0.2, -0.50, 0.0, 0.8, -0.50, 0.0, 0.2, 0.50, 0.0, 0.8, 0.50, 0.0 }; GLfloat triangle_color[] = {0.0, 1.0, 0.0, 1.0 }; GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0 }; RD_START("triangle-quad", "samples=%d, depth=%d, stencil=%d", samples, depth, stencil); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 400, 240); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); ECHK(eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples)); ECHK(eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth)); ECHK(eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencil)); DEBUG_MSG("Buffer: %dx%d (samples=%d, depth=%d, stencil=%d)", width, height, samples, depth, stencil); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glViewport(0, 0, width, height)); /* clear the color buffer */ GCHK(glClearColor(0.3125, 0.3125, 0.3125, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glEnableVertexAttribArray(0)); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glUniform4fv(uniform_location, 1, triangle_color)); GCHK(glDrawArrays(GL_TRIANGLES, 0, 3)); GCHK(glUniform4fv(uniform_location, 1, quad_color)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 3, 4)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); usleep(1000000); RD_END(); }
void ShaderProgram::create_program(){ link_program(_shaders); check_program_link(); _shaders.clear(); }
void test_cube_textured(GLint mag_filter, GLint min_filter, GLint wrap_s, GLint wrap_t) { GLint width, height; GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle; GLuint texturename = 0, texture_handle; EGLint pbuffer_attribute_list[] = { EGL_WIDTH, 256, EGL_HEIGHT, 256, EGL_LARGEST_PBUFFER, EGL_TRUE, EGL_NONE }; GLfloat vVertices[] = { // front -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f, // point magenta -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white // back +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, -1.0f, // point black +1.0f, +1.0f, -1.0f, // point yellow -1.0f, +1.0f, -1.0f, // point green // right +1.0f, -1.0f, +1.0f, // point magenta +1.0f, -1.0f, -1.0f, // point red +1.0f, +1.0f, +1.0f, // point white +1.0f, +1.0f, -1.0f, // point yellow // left -1.0f, -1.0f, -1.0f, // point black -1.0f, -1.0f, +1.0f, // point blue -1.0f, +1.0f, -1.0f, // point green -1.0f, +1.0f, +1.0f, // point cyan // top -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white -1.0f, +1.0f, -1.0f, // point green +1.0f, +1.0f, -1.0f, // point yellow // bottom -1.0f, -1.0f, -1.0f, // point black +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f // point magenta }; GLfloat vTexCoords[] = { //front 1.0f, 1.0f, //point blue 0.0f, 1.0f, //point magenta 1.0f, 0.0f, //point cyan 0.0f, 0.0f, //point white //back 1.0f, 1.0f, //point red 0.0f, 1.0f, //point black 1.0f, 0.0f, //point yellow 0.0f, 0.0f, //point green //right 1.0f, 1.0f, //point magenta 0.0f, 1.0f, //point red 1.0f, 0.0f, //point white 0.0f, 0.0f, //point yellow //left 1.0f, 1.0f, //point black 0.0f, 1.0f, //point blue 1.0f, 0.0f, //point green 0.0f, 0.0f, //point cyan //top 1.0f, 1.0f, //point cyan 0.0f, 1.0f, //point white 1.0f, 0.0f, //point green 0.0f, 0.0f, //point yellow //bottom 1.0f, 0.0f, //point black 0.0f, 0.0f, //point red 1.0f, 1.0f, //point blue 0.0f, 1.0f, //point magenta }; GLfloat vNormals[] = { // front +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward // back +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left // top +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up // bottom +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f // down }; EGLSurface surface; DEBUG_MSG("----------------------------------------------------------------"); RD_START("cube-textured", "mag_filter=%04x, min_filter=%04x, wrap_s=%04x, wrap_t=%04x", mag_filter, min_filter, wrap_s, wrap_t); ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list)); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("PBuffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); GCHK(glFlush()); if (!program) { program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "in_position")); GCHK(glBindAttribLocation(program, 1, "in_normal")); GCHK(glBindAttribLocation(program, 2, "in_TexCoord")); link_program(program); GCHK(glFlush()); } GCHK(glViewport(0, 0, width, height)); GCHK(glFlush()); /* clear the color buffer */ GCHK(glClearColor(0.5, 0.5, 0.5, 1.0)); GCHK(glFlush()); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glFlush()); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glFlush()); GCHK(glEnableVertexAttribArray(0)); GCHK(glFlush()); GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals)); GCHK(glFlush()); GCHK(glEnableVertexAttribArray(1)); GCHK(glFlush()); GCHK(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords)); GCHK(glEnableVertexAttribArray(2)); ESMatrix modelview; esMatrixLoadIdentity(&modelview); esTranslate(&modelview, 0.0f, 0.0f, -8.0f); esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f); esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f); esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f); GLfloat aspect = (GLfloat)(height) / (GLfloat)(width); ESMatrix projection; esMatrixLoadIdentity(&projection); esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f); ESMatrix modelviewprojection; esMatrixLoadIdentity(&modelviewprojection); esMatrixMultiply(&modelviewprojection, &modelview, &projection); float normal[9]; normal[0] = modelview.m[0][0]; normal[1] = modelview.m[0][1]; normal[2] = modelview.m[0][2]; normal[3] = modelview.m[1][0]; normal[4] = modelview.m[1][1]; normal[5] = modelview.m[1][2]; normal[6] = modelview.m[2][0]; normal[7] = modelview.m[2][1]; normal[8] = modelview.m[2][2]; GCHK(glActiveTexture(GL_TEXTURE0)); GCHK(glFlush()); GCHK(glGenTextures(1, &texturename)); GCHK(glFlush()); GCHK(glBindTexture(GL_TEXTURE_2D, texturename)); GCHK(glFlush()); GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, cube_texture.width, cube_texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, cube_texture.pixel_data)); GCHK(glFlush()); /* Note: cube turned black until these were defined. */ GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter)); GCHK(glFlush()); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter)); GCHK(glFlush()); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s)); GCHK(glFlush()); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t)); GCHK(glFlush()); GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix")); GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix")); GCHK(normalmatrix_handle = glGetUniformLocation(program, "normalMatrix")); GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glFlush()); GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0])); GCHK(glFlush()); GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0])); GCHK(glFlush()); GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal)); GCHK(glFlush()); GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */ GCHK(glFlush()); GCHK(glEnable(GL_CULL_FACE)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 8, 4)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 12, 4)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 16, 4)); GCHK(glFlush()); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 20, 4)); GCHK(glFlush()); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); GCHK(glFlush()); RD_END(); }
static GLuint compile_program(glsl_shader_data_t *glsl, const char *vertex, const char *fragment, unsigned i) { GLuint vert = 0, frag = 0, prog = glCreateProgram(); if (!prog) return 0; if (vertex) { RARCH_LOG("Found GLSL vertex shader.\n"); vert = glCreateShader(GL_VERTEX_SHADER); if (!compile_shader( glsl, vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex)) { RARCH_ERR("Failed to compile vertex shader #%u\n", i); return 0; } glAttachShader(prog, vert); } if (fragment) { RARCH_LOG("Found GLSL fragment shader.\n"); frag = glCreateShader(GL_FRAGMENT_SHADER); if (!compile_shader(glsl, frag, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment)) { RARCH_ERR("Failed to compile fragment shader #%u\n", i); return 0; } glAttachShader(prog, frag); } if (vertex || fragment) { RARCH_LOG("Linking GLSL program.\n"); if (!link_program(prog)) { RARCH_ERR("Failed to link program #%u.\n", i); return 0; } /* Clean up dead memory. We're not going to relink the program. * Detaching first seems to kill some mobile drivers * (according to the intertubes anyways). */ if (vert) glDeleteShader(vert); if (frag) glDeleteShader(frag); glUseProgram(prog); glUniform1i(get_uniform(glsl, prog, "Texture"), 0); glUseProgram(0); } return prog; }
int main() { init_glfw(); GLFWwindow* window = create_window(800, 600, "OpenGL"); init_glew(); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); GLuint vertexShader = compile_shader(GL_VERTEX_SHADER, vertexSource); GLuint fragmentShader = compile_shader(GL_FRAGMENT_SHADER, fragSource); GLuint program = link_program(vertexShader, fragmentShader); glUseProgram(program); GLint posAttrib = glGetAttribLocation(program, "position"); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), 0); glEnableVertexAttribArray(posAttrib); GLint colorAttrib = glGetAttribLocation(program, "color"); glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(colorAttrib); GLint texAttrib = glGetAttribLocation(program, "texcoord"); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(5 * sizeof(float))); glEnableVertexAttribArray(texAttrib); GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); int width, height; unsigned char* image = SOIL_load_image("../sample.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); while(!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); glfwPollEvents(); if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, GL_TRUE); } // Clear the screen to black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUniform1f(glGetUniformLocation(program, "time"), glfwGetTime()); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glDeleteTextures(1, &tex); glDeleteProgram(program); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteVertexArrays(1, &vao); glfwTerminate(); }
Program::Program(const std::string& vs, const std::string& fs, const std::string& debug_name) : _debug_name(debug_name) { VLOG_SCOPE_F(1, "Compiling GLSL %s", debug_name.c_str()); CHECK_FOR_GL_ERROR; GLuint vs_id = load_shader(GL_VERTEX_SHADER, vs.c_str(), debug_name.c_str()); GLuint fs_id = load_shader(GL_FRAGMENT_SHADER, fs.c_str(), debug_name.c_str()); _program = glCreateProgram(); #if TARGET_OS_IPHONE // For debugger: glLabelObjectEXT(GL_PROGRAM_OBJECT_EXT, _program, 0, debug_name.c_str()); #endif glAttachShader(_program, vs_id); glAttachShader(_program, fs_id); //GLuint color_number = 0; //glBindFragDataLocation(_program, color_number, "out_frag_color"); link_program(_program, debug_name.c_str()); /* too early to validate: uniforms haven't been bound yet. Using two samplers of different type (sampler2D and sampler_cube) will break the validation. */ //validate(); CHECK_FOR_GL_ERROR; //debug_print(); #if 0 LOG_F(INFO, "Shader: %s", debug_name.c_str()); LOG_F(INFO, "-------------------------------------"); LOG_F(INFO, "%s", vs.c_str()); LOG_F(INFO, "-------------------------------------"); LOG_F(INFO, "%s", fs.c_str()); LOG_F(INFO, "-------------------------------------"); #endif GLint num_attribs; glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &num_attribs); for (int i=0; i<num_attribs; ++i) { GLint size; GLenum type; GLchar name[1024]; glGetActiveAttrib(_program, i, sizeof(name), NULL, &size, &type, name); int location = glGetAttribLocation(_program, name); CHECK_NE_F(location, -1, "Attribute '%s' not found in shader '%s'", name, _debug_name.c_str()); VLOG_F(1, "Attribute %d: %10s, %d x %s, location: %d", i, name, size, type_to_string(type), location); _attributes.emplace_back(Attribute{name, size, type, location}); } GLint num_uniforms; glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &num_uniforms); for (int i=0; i<num_uniforms; ++i) { GLint size; GLenum type; GLchar name[1024]; glGetActiveUniform(_program, i, sizeof(name), NULL, &size, &type, name); int location = glGetUniformLocation(_program, name); CHECK_NE_F(location, -1, "Uniform '%s' not found in shader '%s'", name, _debug_name.c_str()); VLOG_F(1, "Uniform %d: %10s, %d x %s, location: %d", i, name, size, type_to_string(type), location); _uniforms.emplace_back(Uniform{name, size, type, location}); } }
int main (int argc, char *argv[]) { char *frag_code = NULL; glutInit (&argc, argv); static struct option long_options[] = { { "texture", required_argument, NULL, 't' }, { "geometry", required_argument, NULL, 'g' }, { "help", no_argument, NULL, 'h' }, { 0, 0, NULL, 0 } }; glutInitWindowSize (800, 600); glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow ("Shadertoy"); init_glew (); /* option parsing */ while (1) { int c, slot, i; char nearest, repeat; c = getopt_long (argc, argv, ":t:g:?", long_options, NULL); if (c == -1) break; switch (c) { case 'g': for (i = 0; i < 4; i++) { char *token = strsep (&optarg, "x+"); if (!token) break; geometry[i] = atof (token); } fprintf (stderr, "geometry: %.0fx%.0f+%.0f+%.0f\n", geometry[0], geometry[1], geometry[2], geometry[3]); break; case 't': if (optarg[0] < '0' || optarg[0] > '3' || strchr (optarg, ':') == NULL) { fprintf (stderr, "Argument for texture file needs a slot from 0 to 3\n"); exit (1); } slot = optarg[0] - '0'; repeat = 1; nearest = 0; for (c = 1; optarg[c] != ':' && optarg[c] != '\0'; c++) { switch (optarg[c]) { case 'r': repeat = 1; break; case 'o': repeat = 0; break; case 'i': nearest = 0; break; case 'n': nearest = 1; break; default: break; } } if (optarg[c] != ':' || !load_texture (optarg + c + 1, GL_TEXTURE_2D, &tex[slot], nearest, repeat)) { fprintf (stderr, "Failed to load texture. Aborting.\n"); exit (1); } break; case 'h': case ':': default: fprintf (stderr, "Usage:\n %s [options] <shaderfile>\n", argv[0]); fprintf (stderr, "Options: --help\n"); fprintf (stderr, " --texture [0-3]:<textureimage>\n"); exit (c == ':' ? 1 : 0); break; } } if (optind != argc - 1) { fprintf (stderr, "No shaderfile specified. Aborting.\n"); exit (-1); } frag_code = load_file (argv[optind]); if (!frag_code) { fprintf (stderr, "Failed to load Shaderfile. Aborting.\n"); exit (-1); } prog = link_program (frag_code); if (prog < 0) { fprintf (stderr, "Failed to link shader program. Aborting\n"); exit (-1); } ipc_socket_open (IPC_PORT); glutDisplayFunc (display); glutMouseFunc (mouse_press_handler); glutMotionFunc (mouse_move_handler); glutKeyboardFunc (keyboard_handler); redisplay (1000/60); glutMainLoop (); return 0; }
void test_strip_smoothed(int fbo) { GLint width, height; GLfloat vVertices[] = { -0.7, 0.7, -0.7, -0.7, 0.2, -0.4, 0.0, 0.3, -0.5, -0.2, -0.3, 0.3, 0.5, -0.2, 0.4, 0.7, -0.7, 0.7 }; GLfloat vColors[] = { 0.1, 0.1, 0.1, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.9, 0.9, 0.9, 1.0}; EGLSurface surface; RD_START("strip-smoothed", "fbo=%d", fbo); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 256, 256); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); GCHK(glBindAttribLocation(program, 1, "aColor")); link_program(program); GCHK(glViewport(0, 0, width, height)); if (fbo) GCHK(setup_fbo(width, height)); /* clear the color buffer */ GCHK(glClearColor(0.3125, 0.3125, 0.3125, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, vColors)); GCHK(glEnableVertexAttribArray(1)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 6)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); if (fbo) GCHK(cleanup_fbo()); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
void simple_font_renderer::incremental_load(const application_folder & in_application_folder) { switch(internal_status) { case simple_font_renderer_status::ready: case simple_font_renderer_status::failed: break; case simple_font_renderer_status::waiting_to_load: { internal_vertex_shader_file.load(in_application_folder, "SimpleFont.vsh"); internal_fragment_shader_file.load(in_application_folder, "SimpleFont.fsh"); internal_status = simple_font_renderer_status::loading; break; } case simple_font_renderer_status::loading: { auto l_vsh_status = internal_vertex_shader_file.status(); auto l_fsh_status = internal_fragment_shader_file.status(); if((l_vsh_status != file_data_status::loading && l_vsh_status != file_data_status::ready) || (l_fsh_status != file_data_status::loading && l_fsh_status != file_data_status::ready)) { internal_status = simple_font_renderer_status::failed; } else if(l_vsh_status == file_data_status::ready && l_fsh_status == file_data_status::ready) { GLuint l_vertex_shader = 0, l_fragment_shader = 0; if(!compile_shader(internal_vertex_shader_file.data(), &l_vertex_shader, GL_VERTEX_SHADER) || !compile_shader(internal_fragment_shader_file.data(), &l_fragment_shader, GL_FRAGMENT_SHADER)) { atl_debug_log("Shader failed to compile"); internal_status = simple_font_renderer_status::failed; } else { // Index data: { unsigned short l_vertIdx = 0; for(unsigned int idx = 0; idx < pcsm_maxIndicesPerPass; idx += pcsm_indicesPerCharacter) { pm_indexData[idx + 0] = l_vertIdx + 0; pm_indexData[idx + 1] = l_vertIdx + 1; pm_indexData[idx + 2] = l_vertIdx + 2; pm_indexData[idx + 3] = l_vertIdx + 1; pm_indexData[idx + 4] = l_vertIdx + 2; pm_indexData[idx + 5] = l_vertIdx + 3; l_vertIdx += 4; } } // Do GL stuff to set up the vertex buffer: for(int i = 0; i < pcsm_numBuffers; i++) { pm_glVertexArray[i].alloc(); pm_glVertexBuffer[i].alloc(); } pm_glIndexBuffer.alloc(); for(int idx_buffer = 0; idx_buffer < pcsm_numBuffers; idx_buffer++) { pm_glVertexArray[idx_buffer].bind(); internal_configure_vertex_array(idx_buffer); glBufferData(GL_ARRAY_BUFFER, atl::c_array_byte_length(pm_vertexData), NULL, GL_DYNAMIC_DRAW); check_gl_errors(); glBufferData(GL_ELEMENT_ARRAY_BUFFER, atl::c_array_byte_length(pm_indexData), &pm_indexData[0], GL_STATIC_DRAW); check_gl_errors(); } atl::c_array_last_by_ref(pm_glVertexArray).unbind(); // Create shader program. pm_glProgram.alloc(); // Attach vertex shader to program. glAttachShader(pm_glProgram, l_vertex_shader); // Attach fragment shader to program. glAttachShader(pm_glProgram, l_fragment_shader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(pm_glProgram, ATTRIBUTE_VERT_POSITION, "v_position"); glBindAttribLocation(pm_glProgram, ATTRIBUTE_VERT_TEX_COORD, "v_texCoord"); glBindAttribLocation(pm_glProgram, ATTRIBUTE_VERT_COLOR, "v_color"); glBindAttribLocation(pm_glProgram, ATTRIBUTE_VERT_EDGE, "v_edge"); glBindAttribLocation(pm_glProgram, ATTRIBUTE_VERT_RADIUS, "v_radius"); // Link program. if(link_program(pm_glProgram)) { // Get uniform locations. pm_shaderUniforms[UNIFORM_SCREEN_DIM] = glGetUniformLocation(pm_glProgram, "u_screenBounds"); pm_shaderUniforms[UNIFORM_TRANSLATION] = glGetUniformLocation(pm_glProgram, "u_translation"); pm_shaderUniforms[UNIFORM_SAMPLER_DISTANCE_FIELD] = glGetUniformLocation(pm_glProgram, "s_distanceField"); internal_status = simple_font_renderer_status::ready; } else { atl_debug_log("Shader failed to link"); pm_glProgram.free(); internal_status = simple_font_renderer_status::failed; } } internal_vertex_shader_file.free(); internal_fragment_shader_file.free(); // Release vertex and fragment shaders. if(l_vertex_shader != 0) { glDetachShader(pm_glProgram, l_vertex_shader); glDeleteShader(l_vertex_shader); } if(l_fragment_shader != 0) { glDetachShader(pm_glProgram, l_fragment_shader); glDeleteShader(l_fragment_shader); } } break; } } }
int main(int argc, char **argv) { /* Options */ bool fullscreen = false; const char *title = "OpenGL 3.3 Demo"; int opt; while ((opt = getopt(argc, argv, "f")) != -1) { switch (opt) { case 'f': fullscreen = true; break; default: exit(EXIT_FAILURE); } } /* Create window and OpenGL context */ struct graphics_context context; if (!glfwInit()) { fprintf(stderr, "GLFW3: failed to initialize\n"); exit(EXIT_FAILURE); } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if (fullscreen) { GLFWmonitor *monitor = glfwGetPrimaryMonitor(); const GLFWvidmode *m = glfwGetVideoMode(monitor); context.window = glfwCreateWindow(m->width, m->height, title, monitor, NULL); } else { context.window = glfwCreateWindow(640, 640, title, NULL, NULL); } glfwMakeContextCurrent(context.window); glfwSwapInterval(1); /* Initialize gl3w */ if (gl3wInit()) { fprintf(stderr, "gl3w: failed to initialize\n"); exit(EXIT_FAILURE); } /* Shader sources */ const GLchar *vert_shader = "#version 330\n" "layout(location = 0) in vec2 point;\n" "uniform float angle;\n" "void main() {\n" " mat2 rotate = mat2(cos(angle), -sin(angle),\n" " sin(angle), cos(angle));\n" " gl_Position = vec4(0.75 * rotate * point, 0.0, 1.0);\n" "}\n"; const GLchar *frag_shader = "#version 330\n" "out vec4 color;\n" "void main() {\n" " color = vec4(1, 0.15, 0.15, 0);\n" "}\n"; /* Compile and link OpenGL program */ GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_shader); GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_shader); context.program = link_program(vert, frag); context.uniform_angle = glGetUniformLocation(context.program, "angle"); glDeleteShader(frag); glDeleteShader(vert); /* Prepare vertex buffer object (VBO) */ glGenBuffers(1, &context.vbo_point); glBindBuffer(GL_ARRAY_BUFFER, context.vbo_point); glBufferData(GL_ARRAY_BUFFER, sizeof(SQUARE), SQUARE, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); /* Prepare vertrex array object (VAO) */ glGenVertexArrays(1, &context.vao_point); glBindVertexArray(context.vao_point); glBindBuffer(GL_ARRAY_BUFFER, context.vbo_point); glVertexAttribPointer(ATTRIB_POINT, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(ATTRIB_POINT); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); /* Start main loop */ glfwSetKeyCallback(context.window, key_callback); context.lastframe = glfwGetTime(); context.framecount = 0; while (!glfwWindowShouldClose(context.window)) { render(&context); glfwPollEvents(); } fprintf(stderr, "Exiting ...\n"); /* Cleanup and exit */ glDeleteVertexArrays(1, &context.vao_point); glDeleteBuffers(1, &context.vbo_point); glDeleteProgram(context.program); glfwTerminate(); return 0; }
void test_cat(void) { GLint width, height; GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle; GLuint position_vbo, normal_vbo; EGLSurface surface; float scale = 1.3; DEBUG_MSG("----------------------------------------------------------------"); RD_START("cat", ""); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 400, 240); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "normal")); GCHK(glBindAttribLocation(program, 1, "position")); /* upload the attribute vbo's, only done once: */ GCHK(glGenBuffers(1, &normal_vbo)); GCHK(glBindBuffer(GL_ARRAY_BUFFER, normal_vbo)); GCHK(glBufferData(GL_ARRAY_BUFFER, sizeof(cat_normal), cat_normal, GL_STATIC_DRAW)); GCHK(glGenBuffers(1, &position_vbo)); GCHK(glBindBuffer(GL_ARRAY_BUFFER, position_vbo)); GCHK(glBufferData(GL_ARRAY_BUFFER, sizeof(cat_position), cat_position, GL_STATIC_DRAW)); link_program(program); GCHK(glViewport(0, 0, width, height)); /* clear the color buffer */ GCHK(glClearColor(0.5, 0.5, 0.5, 1.0)); GCHK(glEnable(GL_DEPTH_TEST)); GCHK(glDepthFunc(GL_LEQUAL)); GCHK(glEnable(GL_CULL_FACE)); GCHK(glCullFace(GL_BACK)); GCHK(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); GCHK(glEnableVertexAttribArray(0)); GCHK(glBindBuffer(GL_ARRAY_BUFFER, normal_vbo)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL)); GCHK(glEnableVertexAttribArray(1)); GCHK(glBindBuffer(GL_ARRAY_BUFFER, position_vbo)); GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL)); ESMatrix modelview; esMatrixLoadIdentity(&modelview); esTranslate(&modelview, 0.0f, 0.0f, -8.0f); esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f); GLfloat aspect = (GLfloat)(height) / (GLfloat)(width); ESMatrix projection; esMatrixLoadIdentity(&projection); esFrustum(&projection, -scale, +scale, -scale * aspect, +scale * aspect, 5.5f, 10.0f); ESMatrix modelviewprojection; esMatrixLoadIdentity(&modelviewprojection); esMatrixMultiply(&modelviewprojection, &modelview, &projection); float normal[9]; normal[0] = modelview.m[0][0]; normal[1] = modelview.m[0][1]; normal[2] = modelview.m[0][2]; normal[3] = modelview.m[1][0]; normal[4] = modelview.m[1][1]; normal[5] = modelview.m[1][2]; normal[6] = modelview.m[2][0]; normal[7] = modelview.m[2][1]; normal[8] = modelview.m[2][2]; GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "ModelViewMatrix")); GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "ModelViewProjectionMatrix")); GCHK(normalmatrix_handle = glGetUniformLocation(program, "NormalMatrix")); GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0])); GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0])); GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal)); GCHK(glDrawArrays(GL_TRIANGLES, 0, cat_vertices)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
void flat_textured_renderer::incremental_load(const application_folder & in_application_folder) { switch(internal_status) { case flat_textured_renderer_status::ready: case flat_textured_renderer_status::failed: break; case flat_textured_renderer_status::waiting_to_load: { internal_vertex_shader_file.load(in_application_folder, "flat_textured.vsh"); internal_fragment_shader_file.load(in_application_folder, "flat_textured.fsh"); internal_status = flat_textured_renderer_status::loading; break; } case flat_textured_renderer_status::loading: { auto l_vsh_status = internal_vertex_shader_file.status(); auto l_fsh_status = internal_fragment_shader_file.status(); if((l_vsh_status != file_data_status::loading && l_vsh_status != file_data_status::ready) || (l_fsh_status != file_data_status::loading && l_fsh_status != file_data_status::ready)) { internal_status = flat_textured_renderer_status::failed; } else if(l_vsh_status == file_data_status::ready && l_fsh_status == file_data_status::ready) { GLuint l_vertex_shader = 0, l_fragment_shader = 0; if(!compile_shader(internal_vertex_shader_file.data(), &l_vertex_shader, GL_VERTEX_SHADER) || !compile_shader(internal_fragment_shader_file.data(), &l_fragment_shader, GL_FRAGMENT_SHADER)) { atl_debug_log("Shader failed to compile"); internal_status = flat_textured_renderer_status::failed; } else { // Create shader program. internal_program.alloc(); // Attach vertex shader to program. glAttachShader(internal_program, l_vertex_shader); // Attach fragment shader to program. glAttachShader(internal_program, l_fragment_shader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(internal_program, ATTRIBUTE_POSITION, "v_position"); check_gl_errors(); glBindAttribLocation(internal_program, ATTRIBUTE_TEXTURE_COORDINATES, "v_texture_coordinates"); check_gl_errors(); glBindAttribLocation(internal_program, ATTRIBUTE_COLOR_MULTIPLY, "v_color_multiply"); check_gl_errors(); glBindAttribLocation(internal_program, ATTRIBUTE_COLOR_LERP, "v_color_lerp"); check_gl_errors(); // Link program. if(link_program(internal_program)) { // Get uniform locations. internal_shader_uniforms[UNIFORM_SCREEN_DIM] = glGetUniformLocation(internal_program, "u_stage_bounds"); check_gl_errors(); internal_status = flat_textured_renderer_status::ready; } else { atl_debug_log("Shader failed to link"); internal_program.free(); internal_status = flat_textured_renderer_status::failed; } } internal_vertex_shader_file.free(); internal_fragment_shader_file.free(); // Release vertex and fragment shaders. if(l_vertex_shader != 0) { glDetachShader(internal_program, l_vertex_shader); glDeleteShader(l_vertex_shader); } if(l_fragment_shader != 0) { glDetachShader(internal_program, l_fragment_shader); glDeleteShader(l_fragment_shader); } } break; } } }
/** * edges using geometry shader. */ int build_triangle_edges(lulog *log, GLuint *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "flat_model_g.vert", &shaders)); try(compile_shader_from_file(log, GL_GEOMETRY_SHADER, "edge_lines.geom", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_colour.frag", &shaders)); try(link_program(log, shaders, program)); finally: status = free_shaders(log, &shaders, status); return status; } /** * copy a frame by rendering a texture directly (needs a quad to select the area). */ int build_direct_texture(lulog *log, direct_texture *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_texture.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); finally: status = free_shaders(log, &shaders, status); return status; } /** * merge two frames via textures. */ int build_merge_frames(lulog *log, merge_frames *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "merge_frames.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame1", &program->frame1, 0)); try(set_uniform(log, program->name, "frame2", &program->frame2, 1)); finally: status = free_shaders(log, &shaders, status); return status; } /** * blur a frame (roughly uniform over 5 pixels radius). */ int build_blur(lulog *log, blur *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "blur.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); try(set_uniform(log, program->name, "horizontal", &program->horizontal, 1)); finally: status = free_shaders(log, &shaders, status); return status; } int draw_triangle_edges(lulog *log, model *model, programs *programs) { int status = LU_OK; gl_try(glBindVertexArray(model->vao)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); gl_try(glUseProgram(programs->triangle_edges)); gl_try(glMultiDrawArrays(GL_TRIANGLE_STRIP, model->offsets->i, model->counts->i, model->counts->mem.used)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); finally: GL_CLEAN(glBindVertexArray(0)) GL_CLEAN(glUseProgram(0)) return status; }
static void test_vector(const char *glsl_type, const char * suffix, void (GLAPIENTRY *uniform)(GLint, GLsizei, const GLfloat*)) { char buffer[2*sizeof(vs_vector_template)]; GLuint vs, fs; GLuint program; GLint loc_a, loc_b, loc_c; GLint loc_b2; snprintf(buffer, sizeof(buffer), vs_vector_template, glsl_type, glsl_type, glsl_type, glsl_type); vs = compile_shader(GL_VERTEX_SHADER_ARB, buffer); snprintf(buffer, sizeof(buffer), fs_vector_template, glsl_type, suffix); fs = compile_shader(GL_FRAGMENT_SHADER_ARB, buffer); program = link_program(vs, fs); glUseProgramObjectARB(program); loc_a = glGetUniformLocationARB(program, "a"); loc_b = glGetUniformLocationARB(program, "b"); loc_c = glGetUniformLocationARB(program, "c"); loc_b2 = glGetUniformLocationARB(program, "b[2]"); printf("locations: a: %i b: %i c: %i b[2]: %i\n", loc_a, loc_b, loc_c, loc_b); expect_error(GL_NO_ERROR, "Type %s: Sanity check", glsl_type); uniform(loc_a, 0, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to a", glsl_type); uniform(loc_a, 1, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to a", glsl_type); uniform(loc_a, 2, lots_of_zeros); expect_error(GL_INVALID_OPERATION, "Type %s: Write count = 2 to a", glsl_type); uniform(loc_a, 1024, lots_of_zeros); expect_error(GL_INVALID_OPERATION, "Type %s: Write count = 1024 to a", glsl_type); uniform(loc_b, 0, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to b", glsl_type); uniform(loc_b, 1, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to b", glsl_type); uniform(loc_b, 4, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 4 to b", glsl_type); /* Note: The following are out of bound for the array, * but the spec situation is a bit unclear as to whether errors * should be generated. * * Issue #32 of the ARB_shader_objects spec suggests errors * should be generated when writing out-of-bounds on arrays, * but this is not reflected in the OpenGL spec. * * The main point of these tests is to make sure the driver * does not introduce memory errors by accessing internal arrays * out of bounds. */ uniform(loc_b, 5, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ uniform(loc_c, 0, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to c", glsl_type); uniform(loc_c, 1, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to c", glsl_type); uniform(loc_c, 4, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 4 to c", glsl_type); /* Out of bounds; see comment above */ uniform(loc_c, 5, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ uniform(loc_b2, 0, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to b[2]", glsl_type); uniform(loc_b2, 2, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 2 to b[2]", glsl_type); /* Out of bounds; see comment above */ uniform(loc_b2, 1024, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ glDeleteObjectARB(fs); glDeleteObjectARB(vs); glDeleteObjectARB(program); }
void test_stencil(void) { GLint numStencilBits; GLuint stencilValues[NumTests] = { 0x7, // Result of test 0 0x0, // Result of test 1 0x2, // Result of test 2 0xff // Result of test 3. We need to fill this value in a run-time }; int i; DEBUG_MSG("----------------------------------------------------------------"); RD_START("stencil", ""); ECHK(surface = eglCreatePbufferSurface(display, config, pbuffer_attribute_list)); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("PBuffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); GCHK(glFlush()); if (!program) { program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); } GCHK(glClearColor(0.0, 0.0, 0.0, 0.0)); GCHK(glClearStencil(0x1)); GCHK(glClearDepthf(0.75)); GCHK(glEnable(GL_DEPTH_TEST)); GCHK(glEnable(GL_STENCIL_TEST)); // Set the viewport GCHK(glViewport(0, 0, width, height)); // Clear the color, depth, and stencil buffers. At this // point, the stencil buffer will be 0x1 for all pixels GCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); // Use the program object GCHK(glUseProgram(program)); // Load the vertex position GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); // Test 0: // // Initialize upper-left region. In this case, the // stencil-buffer values will be replaced because the // stencil test for the rendered pixels will fail the // stencil test, which is // // ref mask stencil mask // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 ) // // The value in the stencil buffer for these pixels will // be 0x7. // GCHK(glStencilFunc(GL_LESS, 0x7, 0x3)); GCHK(glStencilOp(GL_REPLACE, GL_DECR, GL_DECR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0])); // Test 1: // // Initialize the upper-right region. Here, we'll decrement // the stencil-buffer values where the stencil test passes // but the depth test fails. The stencil test is // // ref mask stencil mask // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 ) // // but where the geometry fails the depth test. The // stencil values for these pixels will be 0x0. // GCHK(glStencilFunc(GL_GREATER, 0x3, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_DECR, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1])); // Test 2: // // Initialize the lower-left region. Here we'll increment // (with saturation) the stencil value where both the // stencil and depth tests pass. The stencil test for // these pixels will be // // ref mask stencil mask // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 ) // // The stencil values for these pixels will be 0x2. // GCHK(glStencilFunc(GL_EQUAL, 0x1, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_INCR, GL_INCR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2])); // Test 3: // // Finally, initialize the lower-right region. We'll invert // the stencil value where the stencil tests fails. The // stencil test for these pixels will be // // ref mask stencil mask // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 ) // // The stencil value here will be set to ~((2^s-1) & 0x1), // (with the 0x1 being from the stencil clear value), // where 's' is the number of bits in the stencil buffer // GCHK(glStencilFunc(GL_EQUAL, 0x2, 0x1)); GCHK(glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3])); // Since we don't know at compile time how many stencil bits are present, // we'll query, and update the value correct value in the // stencilValues arrays for the fourth tests. We'll use this value // later in rendering. GCHK(glGetIntegerv(GL_STENCIL_BITS, &numStencilBits)); stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff; // Use the stencil buffer for controlling where rendering will // occur. We disable writing to the stencil buffer so we // can test against them without modifying the values we // generated. GCHK(glStencilMask(0x0)); for (i = 0; i < NumTests; i++) { GCHK(glStencilFunc(GL_EQUAL, stencilValues[i], 0xff)); GCHK(glUniform4fv(uniform_location, 1, colors[i])); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4])); } ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); GCHK(glFlush()); usleep(1000000); dump_bmp(display, surface, "stencil.bmp"); RD_END(); }
static void test_matrix(void) { GLuint vs, fs; GLuint program; GLint loc_a, loc_b, loc_c; GLint loc_b2; const char * glsl_type = "mat4"; vs = compile_shader(GL_VERTEX_SHADER_ARB, vs_matrix_template); fs = compile_shader(GL_FRAGMENT_SHADER_ARB, fs_matrix_template); program = link_program(vs, fs); glUseProgramObjectARB(program); loc_a = glGetUniformLocationARB(program, "a"); loc_b = glGetUniformLocationARB(program, "b"); loc_c = glGetUniformLocationARB(program, "c"); loc_b2 = glGetUniformLocationARB(program, "b[2]"); printf("locations: a: %i b: %i c: %i b[2]: %i\n", loc_a, loc_b, loc_c, loc_b); expect_error(GL_NO_ERROR, "Type %s: Sanity check", glsl_type); glUniformMatrix4fvARB(loc_b, 0, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to b", glsl_type); glUniformMatrix4fvARB(loc_b, 1, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to b", glsl_type); glUniformMatrix4fvARB(loc_b, 4, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 4 to b", glsl_type); /* Out of bounds; see comment above */ glUniformMatrix4fvARB(loc_b, 5, GL_FALSE, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ glUniformMatrix4fvARB(loc_c, 0, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to c", glsl_type); glUniformMatrix4fvARB(loc_c, 1, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to c", glsl_type); glUniformMatrix4fvARB(loc_c, 4, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 4 to c", glsl_type); /* Out of bounds; see comment above */ glUniformMatrix4fvARB(loc_c, 5, GL_FALSE, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ glUniformMatrix4fvARB(loc_b2, 0, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to b[2]", glsl_type); glUniformMatrix4fvARB(loc_b2, 2, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 2 to b[2]", glsl_type); /* Out of bounds; see comment above */ glUniformMatrix4fvARB(loc_b2, INT_MAX, GL_FALSE, lots_of_zeros); (void) glGetError(); /* Eat generated error, if any */ glUniformMatrix4fvARB(loc_a, 0, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 0 to a", glsl_type); glUniformMatrix4fvARB(loc_a, 1, GL_FALSE, lots_of_zeros); expect_error(GL_NO_ERROR, "Type %s: Write count = 1 to a", glsl_type); glUniformMatrix4fvARB(loc_a, 2, GL_FALSE, lots_of_zeros); expect_error(GL_INVALID_OPERATION, "Type %s: Write count = 2 to a", glsl_type); glUniformMatrix4fvARB(loc_a, INT_MAX, GL_FALSE, lots_of_zeros); expect_error(GL_INVALID_OPERATION, "Type %s: Write count = INT_MAX to a", glsl_type); glDeleteObjectARB(fs); glDeleteObjectARB(vs); glDeleteObjectARB(program); }
void GLAPIENTRY _mesa_LinkProgramARB(GLhandleARB programObj) { GET_CURRENT_CONTEXT(ctx); link_program(ctx, programObj); }
/* Run through multiple variants to detect clear color, quad color (frag * shader param), and vertices */ void test_query(int querytype, int w, int h) { static const GLfloat clear_color[] = {0.0, 0.0, 0.0, 0.0}; static const GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0}; static const GLfloat quad2_color[] = {0.0, 1.0, 0.0, 1.0}; static const GLfloat vertices[] = { -0.45, -0.75, 0.0, 0.45, -0.75, 0.0, -0.45, 0.75, 0.0, 0.45, 0.75, 0.0, }; static const GLfloat vertices2[] = { -0.15, -0.23, 1.0, 0.25, -0.33, 1.0, -0.35, 0.43, 1.0, 0.45, 0.53, 1.0, }; static const char *queryname[] = { "none", "samples-passed", "time-elapsed", }; RD_START("query", "query=%s", queryname[querytype]); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, w, h); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glGenQueries(1, &query)); GCHK(glDepthMask(GL_TRUE)); GCHK(glEnable(GL_DEPTH_TEST)); GCHK(glViewport(0, 0, width, height)); if (clear_color) { /* clear the color buffer */ GCHK(glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3])); GCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); } GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices)); GCHK(glEnableVertexAttribArray(0)); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glUniform4fv(uniform_location, 1, quad_color)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); switch (querytype) { case 1: GCHK(glBeginQuery(GL_ANY_SAMPLES_PASSED, query)); break; case 2: GCHK(glBeginQuery(GL_TIME_ELAPSED_EXT, query)); break; } /* Quad 2 render */ GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices2)); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glUniform4fv(uniform_location, 1, quad2_color)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); switch (querytype) { case 1: GCHK(glEndQuery(GL_ANY_SAMPLES_PASSED)); break; case 2: GCHK(glEndQuery(GL_TIME_ELAPSED_EXT)); break; } if (querytype > 0) { GLuint result; do { GCHK(glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result)); } while (!result); GCHK(glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result)); DEBUG_MSG("Query ended with %d", result); } ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); usleep(1000000); GCHK(glDeleteQueries(1, &query)); eglTerminate(display); RD_END(); }
void GameView::initializeGL() { glClearColor(0,0,0,0); #ifdef USE_VAO glGenVertexArrays(1, &_vao); #endif glGenBuffers(1, &_vertex_buffer_identifier); _program_identifier = glCreateProgram(); QImage img; if (!img.load(":/8x8tiles.png")) { std::cout << "image not found!" << std::endl; } QImage GL_formatted_image; GL_formatted_image = QGLWidget::convertToGLFormat(img); glGenTextures(1, &_texture_identifier); glBindTexture(GL_TEXTURE_2D, _texture_identifier); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, GL_formatted_image.width(), GL_formatted_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_formatted_image.bits() ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); update_vertex_buffer(); #ifdef USE_GLSL_150 // Use GLSL 1.5 std::string vertex_shader; vertex_shader += "#version 150\n"; vertex_shader += "in vec4 vertex;\n"; vertex_shader += "in vec2 texcoord;\n"; vertex_shader += "in vec4 symbol_color;\n"; vertex_shader += "in vec4 background_color;\n"; vertex_shader += "uniform mat4 mvp;\n"; vertex_shader += "out vec2 v_texcoord;\n"; vertex_shader += "out vec4 v_symbol_color;\n"; vertex_shader += "out vec4 v_background_color;\n"; vertex_shader += "void main() {\n"; vertex_shader += " gl_Position = mvp * vertex;\n"; vertex_shader += " v_texcoord = texcoord;\n"; vertex_shader += " v_symbol_color = symbol_color;\n"; vertex_shader += " v_background_color = background_color;\n"; vertex_shader += "}\n"; std::string fragment_shader; fragment_shader += "#version 150\n"; fragment_shader += "in vec2 v_texcoord;\n"; fragment_shader += "in vec4 v_symbol_color;\n"; fragment_shader += "in vec4 v_background_color;\n"; fragment_shader += "uniform sampler2D texture0;\n"; fragment_shader += "out vec4 frag_color;\n"; fragment_shader += "void main() {\n"; fragment_shader += " float r = texture(texture0, v_texcoord).r;\n"; fragment_shader += " frag_color = v_symbol_color * r + v_background_color * (1.0 - r);\n"; fragment_shader += "}\n"; #else // Use GLSL 1.2 std::string vertex_shader; vertex_shader += "#version 120\n"; vertex_shader += "attribute vec4 vertex;\n"; vertex_shader += "attribute vec2 texcoord;\n"; vertex_shader += "attribute vec4 symbol_color;\n"; vertex_shader += "attribute vec4 background_color;\n"; vertex_shader += "uniform mat4 mvp;\n"; vertex_shader += "varying vec2 v_texcoord;\n"; vertex_shader += "varying vec4 v_symbol_color;\n"; vertex_shader += "varying vec4 v_background_color;\n"; vertex_shader += "void main() {\n"; vertex_shader += " gl_Position = mvp * vertex;\n"; vertex_shader += " v_texcoord = texcoord;\n"; vertex_shader += " v_symbol_color = symbol_color;\n"; vertex_shader += " v_background_color = background_color;\n"; vertex_shader += "}\n"; std::string fragment_shader; fragment_shader += "#version 120\n"; fragment_shader += "varying vec2 v_texcoord;\n"; fragment_shader += "varying vec4 v_symbol_color;\n"; fragment_shader += "varying vec4 v_background_color;\n"; fragment_shader += "uniform sampler2D texture0;\n"; fragment_shader += "void main() {\n"; fragment_shader += " float r = texture2D(texture0, v_texcoord).r;\n"; fragment_shader += " gl_FragColor = v_symbol_color * r + v_background_color * (1.0 - r);\n"; fragment_shader += "}\n"; #endif GLuint vertex_shader_identifier = glCreateShader(GL_VERTEX_SHADER); GLuint fragment_shader_identifier = glCreateShader(GL_FRAGMENT_SHADER); compile_shader(vertex_shader_identifier, vertex_shader); compile_shader(fragment_shader_identifier, fragment_shader); glAttachShader(_program_identifier, vertex_shader_identifier); glAttachShader(_program_identifier, fragment_shader_identifier); glBindAttribLocation(_program_identifier, 0, "vertex"); glBindAttribLocation(_program_identifier, 1, "texcoord"); glBindAttribLocation(_program_identifier, 2, "symbol_color"); glBindAttribLocation(_program_identifier, 3, "background_color"); link_program(); glDetachShader(_program_identifier, vertex_shader_identifier); glDetachShader(_program_identifier, fragment_shader_identifier); glDeleteShader(fragment_shader_identifier); glDeleteShader(vertex_shader_identifier); GLenum error = glGetError(); if (error != GL_NO_ERROR) { std::cout << "Error: " << error << std::endl; } gettimeofday(&_lastTime, 0); }
void test_quad_instanced(int instances, int div0, int div1) { GLint width, height; GLuint texturename = 0, texture_handle; GLfloat vVertices[] = { // front -0.45, -0.75, 0.0, 0.45, -0.75, 0.0, -0.45, 0.75, 0.0, 0.45, 0.75, 0.0 }; GLfloat vTexCoords[] = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, }; EGLSurface surface; RD_START("instanced", "instances=%d, div0=%d, div1=%d", instances, div0, div1); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 255, 255); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); printf("EGL Version %s\n", eglQueryString(display, EGL_VERSION)); printf("EGL Vendor %s\n", eglQueryString(display, EGL_VENDOR)); printf("EGL Extensions %s\n", eglQueryString(display, EGL_EXTENSIONS)); printf("GL Version %s\n", glGetString(GL_VERSION)); printf("GL extensions: %s\n", glGetString(GL_EXTENSIONS)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "in_position")); GCHK(glBindAttribLocation(program, 1, "in_TexCoord")); link_program(program); GCHK(glViewport(0, 0, width, height)); /* clear the color buffer */ GCHK(glClearColor(0.5, 0.5, 0.5, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords)); GCHK(glEnableVertexAttribArray(1)); GCHK(glActiveTexture(GL_TEXTURE0)); GCHK(glGenTextures(1, &texturename)); GCHK(glBindTexture(GL_TEXTURE_2D, texturename)); GCHK(glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, cube_texture.width, cube_texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, cube_texture.pixel_data)); /* Note: cube turned black until these were defined. */ GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)); GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */ GCHK(glEnable(GL_CULL_FACE)); if (instances > 0) { GCHK(glVertexAttribDivisor(0, div0)); GCHK(glVertexAttribDivisor(1, div1)); GCHK(glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, instances)); } else { GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); sleep(1); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
static void test_transform_feedback(int n, int separate) { GLint width, height, ret, i; GLuint texturename = 0, texture_handle, tf; GLfloat vVertices[] = { // front -0.45, -0.75, 0.0, 0.45, -0.75, 0.0, -0.45, 0.75, 0.0, 0.45, 0.75, 0.0 }; const char *varyings[] = { "pos", "pos2", "pos3", "pos4", "pos5", "pos6", "pos7", //"posen[0]", //"posen[1]", //"posen[2]", //"posen[8]", //"posen[5]", }; GLuint tf_bufs[ARRAY_SIZE(varyings)] = { 0 }; EGLSurface surface; RD_START("transform-feedback", "n=%d, separate=%d", n, separate); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 255, 255); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); printf("EGL Version %s\n", eglQueryString(display, EGL_VERSION)); printf("EGL Vendor %s\n", eglQueryString(display, EGL_VENDOR)); printf("EGL Extensions %s\n", eglQueryString(display, EGL_EXTENSIONS)); printf("GL Version %s\n", glGetString(GL_VERSION)); printf("GL extensions: %s\n", glGetString(GL_EXTENSIONS)); program = get_program(vertex_shader_source, fragment_shader_source); if (n > 0) GCHK(glEnable(GL_RASTERIZER_DISCARD)); GCHK(glBindAttribLocation(program, 0, "in_position")); if (n > 0) { GCHK(glTransformFeedbackVaryings(program, n, varyings, separate ? GL_SEPARATE_ATTRIBS : GL_INTERLEAVED_ATTRIBS)); } link_program(program); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); if (n > 0) { GCHK(glGenBuffers(n, tf_bufs)); for (i = 0; i < (separate ? n : 1); i++) { GCHK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tf_bufs[i])); GCHK(glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STREAM_DRAW)); GCHK(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, tf_bufs[i], 32 * i, 1024)); } } //GCHK(glGenTransformFeedbacks(1, &tf)); //GCHK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf)); if (n > 0) GCHK(glBeginTransformFeedback(GL_POINTS)); GCHK(glDrawArrays(GL_POINTS, 0, 4)); if (n > 0) GCHK(glEndTransformFeedback()); //ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); sleep(1); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
void test_cube_textured(GLint mag_filter, GLint min_filter, GLint wrap_s, GLint wrap_t, GLint wrap_r, GLenum format, GLenum type) { GLint width, height; GLint modelviewmatrix_handle, modelviewprojectionmatrix_handle, normalmatrix_handle; GLuint texturename = 0, texture_handle; GLfloat vVertices[] = { // front -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f, // point magenta -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white // back +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, -1.0f, // point black +1.0f, +1.0f, -1.0f, // point yellow -1.0f, +1.0f, -1.0f, // point green // right +1.0f, -1.0f, +1.0f, // point magenta +1.0f, -1.0f, -1.0f, // point red +1.0f, +1.0f, +1.0f, // point white +1.0f, +1.0f, -1.0f, // point yellow // left -1.0f, -1.0f, -1.0f, // point black -1.0f, -1.0f, +1.0f, // point blue -1.0f, +1.0f, -1.0f, // point green -1.0f, +1.0f, +1.0f, // point cyan // top -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white -1.0f, +1.0f, -1.0f, // point green +1.0f, +1.0f, -1.0f, // point yellow // bottom -1.0f, -1.0f, -1.0f, // point black +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f // point magenta }; GLfloat vTexCoords[] = { //front 1.0f, 1.0f, //point blue 0.0f, 1.0f, //point magenta 1.0f, 0.0f, //point cyan 0.0f, 0.0f, //point white //back 1.0f, 1.0f, //point red 0.0f, 1.0f, //point black 1.0f, 0.0f, //point yellow 0.0f, 0.0f, //point green //right 1.0f, 1.0f, //point magenta 0.0f, 1.0f, //point red 1.0f, 0.0f, //point white 0.0f, 0.0f, //point yellow //left 1.0f, 1.0f, //point black 0.0f, 1.0f, //point blue 1.0f, 0.0f, //point green 0.0f, 0.0f, //point cyan //top 1.0f, 1.0f, //point cyan 0.0f, 1.0f, //point white 1.0f, 0.0f, //point green 0.0f, 0.0f, //point yellow //bottom 1.0f, 0.0f, //point black 0.0f, 0.0f, //point red 1.0f, 1.0f, //point blue 0.0f, 1.0f, //point magenta }; GLfloat vNormals[] = { // front +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward // back +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left // top +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up // bottom +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f // down }; EGLSurface surface; const int texwidth = 333; const int texheight = 222; static uint8_t *buf = NULL; if (!buf) { int i; buf = malloc(texwidth * texheight * 16); for (i = 0; i < (texwidth * texheight * 16); i++) buf[i] = i; } RD_START("cube-textured", "mag_filter=%04x, min_filter=%04x, " "wrap_s=%04x, wrap_t=%04x, wrap_r=%04x, format=%s, type=%s", mag_filter, min_filter, wrap_s, wrap_t, wrap_r, formatname(format), typename(type)); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 256, 256); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "in_position")); GCHK(glBindAttribLocation(program, 1, "in_normal")); GCHK(glBindAttribLocation(program, 2, "in_TexCoord")); link_program(program); GCHK(glViewport(0, 0, width, height)); /* clear the color buffer */ GCHK(glClearColor(0.5, 0.5, 0.5, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vNormals)); GCHK(glEnableVertexAttribArray(1)); GCHK(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, vTexCoords)); GCHK(glEnableVertexAttribArray(2)); ESMatrix modelview; esMatrixLoadIdentity(&modelview); esTranslate(&modelview, 0.0f, 0.0f, -8.0f); esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f); esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f); esRotate(&modelview, 10.0f, 0.0f, 0.0f, 1.0f); GLfloat aspect = (GLfloat)(height) / (GLfloat)(width); ESMatrix projection; esMatrixLoadIdentity(&projection); esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f); ESMatrix modelviewprojection; esMatrixLoadIdentity(&modelviewprojection); esMatrixMultiply(&modelviewprojection, &modelview, &projection); float normal[9]; normal[0] = modelview.m[0][0]; normal[1] = modelview.m[0][1]; normal[2] = modelview.m[0][2]; normal[3] = modelview.m[1][0]; normal[4] = modelview.m[1][1]; normal[5] = modelview.m[1][2]; normal[6] = modelview.m[2][0]; normal[7] = modelview.m[2][1]; normal[8] = modelview.m[2][2]; GCHK(glActiveTexture(GL_TEXTURE0)); GCHK(glGenTextures(1, &texturename)); GCHK(glBindTexture(GL_TEXTURE_2D, texturename)); GCHK(glTexImage2D(GL_TEXTURE_2D, 0, format, texwidth, texheight, 0, format, type, buf)); /* Note: cube turned black until these were defined. */ GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, wrap_r)); GCHK(modelviewmatrix_handle = glGetUniformLocation(program, "modelviewMatrix")); GCHK(modelviewprojectionmatrix_handle = glGetUniformLocation(program, "modelviewprojectionMatrix")); GCHK(normalmatrix_handle = glGetUniformLocation(program, "normalMatrix")); GCHK(texture_handle = glGetUniformLocation(program, "uTexture")); GCHK(glUniformMatrix4fv(modelviewmatrix_handle, 1, GL_FALSE, &modelview.m[0][0])); GCHK(glUniformMatrix4fv(modelviewprojectionmatrix_handle, 1, GL_FALSE, &modelviewprojection.m[0][0])); GCHK(glUniformMatrix3fv(normalmatrix_handle, 1, GL_FALSE, normal)); GCHK(glUniform1i(texture_handle, 0)); /* '0' refers to texture unit 0. */ GCHK(glEnable(GL_CULL_FACE)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 8, 4)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 12, 4)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 16, 4)); GCHK(glDrawArrays(GL_TRIANGLE_STRIP, 20, 4)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
void opengl::ShaderProgram::linkProgram() { link_program(_program_id); // We don't need the shaders anymore freeCompiledShaders(); }
/* Run through multiple variants to detect mrt settings */ void test_srgb_fbo(GLint ifmt, GLenum fmt, GLenum type) { GLint width, height; GLuint fbo, fbotex; GLenum mrt_bufs[16]; GLfloat quad_color[] = {1.0, 0.0, 0.0, 1.0}; GLfloat vertices[] = { -0.45, -0.75, 0.1, 0.45, -0.75, 0.1, -0.45, 0.75, 0.1, 0.45, 0.75, 0.1 }; EGLSurface surface; RD_START("srgb-fbo", "fmt=%s (%x), ifmt=%s (%x), type=%s (%x)", formatname(fmt), fmt, formatname(ifmt), ifmt, typename(type), type); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 64, 64); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); GCHK(glGenFramebuffers(1, &fbo)); GCHK(glGenTextures(1, &fbotex)); GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo)); GCHK(glBindTexture(GL_TEXTURE_2D, fbotex)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GCHK(glTexImage2D(GL_TEXTURE_2D, 0, ifmt, width, height, 0, fmt, type, 0)); GCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbotex, 0)); DEBUG_MSG("status=%04x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); GCHK(glBindFramebuffer(GL_FRAMEBUFFER, fbo)); GCHK(glDrawBuffers(1, (const GLenum[]){GL_COLOR_ATTACHMENT0}));