enum piglit_result piglit_display(void) { bool pass = true; GLfloat pos[2]; glGetMultisamplefv(GL_SAMPLE_POSITION, 0, pos); /* API gives us 0..1 sample position; get it into * -0.5..0.5 space. */ pos[0] -= 0.5f; pos[1] -= 0.5f; glViewport(0, 0, 64, 64); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ms_fbo); glUseProgram(draw_prog); glUniform2fv(sample_pos_loc, 1, pos); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo); glUseProgram(test_prog); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); pass = piglit_probe_rect_rgb(0, 0, 64, 64, green) && pass; piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
static enum piglit_result check_sample_positions(int expected_sample_count) { GLint samples; int i; glGetIntegerv(GL_SAMPLES, &samples); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; if (samples < expected_sample_count) { printf("Expected sample count at least %d, got %d\n", expected_sample_count, samples); return PIGLIT_FAIL; } for (i = 0; i < samples; i++) { float sample_pos[2]; glGetMultisamplefv(GL_SAMPLE_POSITION, i, sample_pos); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; printf("Sample %d position %2.2f %2.2f\n", i, sample_pos[0], sample_pos[1] ); if (sample_pos[0] < 0 || sample_pos[0] > 1 || sample_pos[1] < 0 || sample_pos[1] > 1) { printf("Sample %d out of range\n", i ); return PIGLIT_FAIL; } } return PIGLIT_PASS; }
/////////////////////////////////////////////////////////////////////////////// // OpenGL related startup code is safe to put here. Load textures, etc. void SetupRC(void) { GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } glEnable(GL_DEPTH_TEST); exposure = 1.0f; // Light Blue glClearColor(vSkyBlue[0], vSkyBlue[1], vSkyBlue[2], vSkyBlue[3]); // Load geometry GLfloat alpha = 0.25f; floorBatch.Begin(GL_TRIANGLE_FAN, 4, 1); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(-20.0f, -0.41f, 20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 1.00f, 0.0f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(20.0f, -0.41f, 20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 1.00f, 1.00f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(20.0f, -0.41f, -20.0f); floorBatch.Color4f(0.0f, 1.0f, 0.0f, alpha); floorBatch.MultiTexCoord2f(0, 0.0f, 1.00f); floorBatch.Normal3f(0.0, 1.0f, 0.0f); floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f); floorBatch.End(); windowBatch.Begin(GL_TRIANGLE_FAN, 4, 1); windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f); windowBatch.MultiTexCoord2f(0, 0.0f, 0.0f); windowBatch.Normal3f( 0.0f, 1.0f, 0.0f); windowBatch.Vertex3f(-1.0f, 0.0f, 0.0f); windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f); windowBatch.MultiTexCoord2f(0, 1.0f, 0.0f); windowBatch.Normal3f(0.0f, 1.0f, 0.0f); windowBatch.Vertex3f(1.0f, 0.0f, 0.0f); windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f); windowBatch.MultiTexCoord2f(0, 1.0f, 1.0f); windowBatch.Normal3f(0.0f, 1.0f, 0.0f); windowBatch.Vertex3f(1.0f, 2.0f, 0.0f); windowBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f); windowBatch.MultiTexCoord2f(0, 0.0f, 1.0f); windowBatch.Normal3f( 0.0f, 1.0f, 0.0f); windowBatch.Vertex3f(-1.0f, 2.0f, 0.0f); windowBatch.End(); const float width = 0.2f; windowBorderBatch.Begin(GL_TRIANGLE_STRIP, 13); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01f, width, 0.01f); windowBorderBatch.Normal3f(0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01f, 0.0f, 0.01f); windowBorderBatch.Normal3f(0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01f, width, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01f, 0.0f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01-width, 0.0f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01f, 2.0f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01-width, 2.0f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(1.01f, 2.0-width, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01f, 2.f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01f, 2.0-width, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01+width, 2.f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01f, 0.0f, 0.01f); windowBorderBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowBorderBatch.Vertex3f(-1.01+width, 0.0f, 0.01f); windowBorderBatch.End(); const float gridWidth = (float)0.01; const int gridLineCount = 24; windowGridBatch.Begin(GL_TRIANGLES, gridLineCount*2*6); // bottom horizontal for(int i=0; i<gridLineCount; i++) { float offset = 2*((float)(i+1)/(float)(gridLineCount+1)); windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(-1.0f, offset+gridWidth, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(-1.0f, offset-gridWidth, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(1.0f, offset-gridWidth, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(1.0f,offset-gridWidth, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(1.0f, offset+gridWidth, 0.01f); windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(-1.0f, offset+gridWidth, 0.01f); } // Verticals for(int i=0; i<gridLineCount; i++) { float offset = 2*((float)(i+1)/(float)(gridLineCount+1)) - 1.0; windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset+gridWidth, 0.0f, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset-gridWidth, 0.0f, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset-gridWidth, 2.0f, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset-gridWidth, 2.0f, 0.01f); windowGridBatch.Normal3f(0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset+gridWidth, 2.0, 0.01f); windowGridBatch.Normal3f( 0.0f, 0.0f, 1.0f); windowGridBatch.Vertex3f(offset+gridWidth, 0.0f, 0.01f); } windowGridBatch.End(); glGenTextures(1, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); LoadBMPTexture("marble.bmp", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT); // Setup HDR render texture glGenTextures(1, hdrTextures); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, hdrTextures[0]); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB16F, screenWidth, screenHeight, GL_FALSE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Attach HDR texture to fbo // Create and bind an FBO glGenFramebuffers(1,hdrFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, hdrFBO[0]); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hdrTextures[0], 0); // Create window texture glGenTextures(1, &windowTexture); glBindTexture(GL_TEXTURE_2D, windowTexture); GLuint texWidth = 0; GLuint texHeight = 0; // Load HDR image from EXR file LoadOpenEXRImage("window.exr", windowTexture, texWidth, texHeight); // Load flat color shader flatColorProg = gltLoadShaderPairWithAttributes("basic.vs", "color.fs", 3, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_NORMAL, "vNormal", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(flatColorProg, 0, "oColor"); glBindFragDataLocation(flatColorProg, 1, "oBright"); glLinkProgram(flatColorProg); // Load texture replace shader texReplaceProg = gltLoadShaderPairWithAttributes("basic.vs", "tex_replace.fs", 3, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_NORMAL, "vNormal", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(texReplaceProg, 0, "oColor"); glBindFragDataLocation(texReplaceProg, 1, "oBright"); glLinkProgram(texReplaceProg); // Load bloom shader hdrResolve = gltLoadShaderPairWithAttributes("basic.vs", "hdr_exposure.fs", 3, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_NORMAL, "vNormal", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(hdrResolve, 0, "oColor"); glLinkProgram(hdrResolve); // Uncomment the line below to get the correct behavior. floorBatch.Draw(); // Get the location of each multisample sample int sampleCount = 0; glGetIntegerv(GL_SAMPLES, &sampleCount); float positions[64]; // Enough for at least 32 samples for(int i =0; i < sampleCount; i++) { glGetMultisamplefv(GL_SAMPLE_POSITION, i, &positions[i*2]); } // Limit sample count to 8x //assert(sampleCount >= 8); sampleCount = 8; float invertedSampleDistances[8]; // The maxDist is used for doing the distance inversion // You could use the actual max dist a sample could be, but that // would mean that sample would receive a weighting of 0, use 1.0 instead. //float maxDist = sqrt(0.5*0.5*2); float maxDist = 1.0f; // calculate the distance of each sample from the center, // then invert it so that samples closer to the center recieve more weight for(int i=0; i<8; i++) { double xDist = positions[i*2 ]-0.5; double yDist = positions[i*2+1]-0.5; invertedSampleDistances[i] = maxDist - sqrt(xDist*xDist + yDist*yDist); } // zero out sample weights array for(int i=0; i<8; i++) { for(int j=0; j<8; j++) { sampleWeights[i][j] = 0.0f; } } // First array is easy, 1 sample so that samples weight is 1 sampleWeights[0][0] = 1.0f; // Add up the distances to get the total used for calculating weights for(int i=1; i<8; i++) { float totalWeight = 0.0f; for(int j=0; j<=i; j++) totalWeight += invertedSampleDistances[j]; // Invert to get the factor used for each sample, the sum of all sample weights is always 1.0 float perSampleFactor = 1 / totalWeight; for(int j=0; j<=i; j++) sampleWeights[i][j] = invertedSampleDistances[j] * perSampleFactor; } // Setup a texture buffer object for holding the sample weights glGenBuffers(1, &sampleWeightBuf); glBindBuffer(GL_TEXTURE_BUFFER_ARB, sampleWeightBuf); glBufferData(GL_TEXTURE_BUFFER_ARB, sizeof(float)*8, sampleWeights, GL_DYNAMIC_DRAW); glBindBuffer(GL_TEXTURE_BUFFER_ARB, 0); // Load the texBO into texture 1 glActiveTexture(GL_TEXTURE1); glGenTextures(1, &texBOTexture); glBindTexture(GL_TEXTURE_BUFFER_ARB, texBOTexture); glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_R32F, sampleWeightBuf); glActiveTexture(GL_TEXTURE0); // Reset framebuffer binding glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL32_nglGetMultisamplefv(JNIEnv *env, jclass clazz, jint pname, jint index, jlong val, jlong function_pointer) { GLfloat *val_address = (GLfloat *)(intptr_t)val; glGetMultisamplefvPROC glGetMultisamplefv = (glGetMultisamplefvPROC)((intptr_t)function_pointer); glGetMultisamplefv(pname, index, val_address); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBTextureMultisample_nglGetMultisamplefv__IIJ(JNIEnv *__env, jclass clazz, jint pname, jint index, jlong valAddress) { glGetMultisamplefvPROC glGetMultisamplefv = (glGetMultisamplefvPROC)tlsGetFunction(655); intptr_t val = (intptr_t)valAddress; UNUSED_PARAM(clazz) glGetMultisamplefv(pname, index, val); }