#include #include #include #define GL_GLEXT_PROTOTYPES 1 #include #include #include #include float gTestVertexBuffer[8] = { 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, }; const uint testVBLength = 4; const uint vbStride = 8; short gTestIndexBuffer[6] = {0,1,2,2,3,0}; const uint testIBLength = 6; const uint ibStride = 2; bool gFramebufferSRGBEnabled = false; const unsigned char testPixelData[4] = {127, 127, 127, 255}; enum Encoding { eLinear, eSRGB }; void checkGLError() { GLenum error = glGetError(); while (error) { const char* errStr; switch (error) { case GL_INVALID_ENUM: errStr = "GL_INVALID_ENUM"; break; case GL_INVALID_VALUE: errStr = "GL_INVALID_VALUE"; break; case GL_INVALID_OPERATION: errStr = "GL_INVALID_OPERATION"; break; default: errStr = "Unknown error"; break; } std::cout << errStr << std::endl; throw; } } GLuint LoadShader(const GLchar *const data, GLenum shaderType) { GLuint shaderId = glCreateShader(shaderType); glShaderSource(shaderId, 1, &data, NULL); checkGLError(); glCompileShader(shaderId); checkGLError(); GLint status; glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status); checkGLError(); if (status != GL_TRUE) { GLchar logMessage[2048]; glGetShaderInfoLog(shaderId, 2048, NULL, logMessage); std::cout << logMessage << std::endl; throw; } return shaderId; } GLuint LoadBufferData(const GLbyte* data, GLuint length, GLenum bufferType) { GLuint bufferId; glGenBuffers(1, &bufferId); checkGLError(); glBindBuffer(bufferType, bufferId); checkGLError(); glBufferData(bufferType, length, data, GL_DYNAMIC_DRAW); checkGLError(); return bufferId; } void printPixelValue() { GLbyte pixel[4]; glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,pixel); checkGLError(); std::cout << "R:" << (uint)(unsigned char)pixel[0] << ", G:" << (uint)(unsigned char)pixel[1] << ", B:" << (uint)(unsigned char)pixel[2] << ", A:" << (uint)(unsigned char)pixel[3] << std::endl; } int main() { // Initilaise SDL SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("TestApplication", 0, 0, 200, 200, SDL_WINDOW_OPENGL); if (!window) std::cout << SDL_GetError() << std::endl; SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); SDL_GLContext context = SDL_GL_CreateContext(window); if (!context) std::cout << SDL_GetError() << std::endl; int encoding; glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding); checkGLError(); std::cout << "SDL has returned a " << (encoding == GL_LINEAR ? "linear" : "non-linear") << " backbuffer." << std::endl; // Disable sRGB conversions until we need them glDisable(GL_FRAMEBUFFER_SRGB); checkGLError(); // Create texture and associated framebuffers glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Creating textures and framebuffers"); std::cout << "Creating textures and framebuffers" << std::endl; GLuint srcTexId[4]; GLuint dstTexId[4]; glGenTextures(4, srcTexId); checkGLError(); glGenTextures(4, dstTexId); checkGLError(); GLuint srcFramebufferId[4]; GLuint dstFramebufferId[4]; glGenFramebuffers(4, srcFramebufferId); checkGLError(); glGenFramebuffers(4, dstFramebufferId); checkGLError(); // GL_RGBA8, GL_SRGB8_ALPHA8 // GL_RGBA8 view of GL_SRGB8_ALPHA8 // GL_SRGB8_ALPHA8 view of GL_RGBA8 for(int i=0; i<4; i++) { Encoding enc = (Encoding)(i%2); GLenum texSizedFormat = enc == eLinear ? GL_RGBA8 : GL_SRGB8_ALPHA8; GLenum texViewSizedFormat = enc == eLinear ? GL_SRGB8_ALPHA8 : GL_RGBA8; GLenum texType = GL_UNSIGNED_BYTE; const char* expected = enc == eLinear ? "GL_LINEAR" : "GL_SRGB"; const char* prefix = ""; if( i >= 2 ) { prefix = "(Texture View of opposite) "; expected = enc == eLinear ? "GL_SRGB" : "GL_LINEAR"; } // Sources glActiveTexture(GL_TEXTURE0 + i); checkGLError(); glBindTexture(GL_TEXTURE_2D, srcTexId[i]); checkGLError(); if( i < 2 ) { glTexStorage2D(GL_TEXTURE_2D, 1, texSizedFormat, 1, 1); checkGLError(); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, testPixelData); checkGLError(); glTextureView(srcTexId[i+2], GL_TEXTURE_2D, srcTexId[i], texViewSizedFormat, 0, 1, 0, 1 ); checkGLError(); } glBindFramebuffer(GL_FRAMEBUFFER, srcFramebufferId[i]); checkGLError(); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, srcTexId[i], 0); checkGLError(); // Check framebuffer has expected SRGBness GLint colorEncoding; glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &colorEncoding); std::cout << prefix << "Expected framebuffer encoding (source): " << expected << ", got: "; if (colorEncoding == GL_LINEAR) std::cout << "GL_LINEAR"; else if (colorEncoding == GL_SRGB) std::cout << "GL_SRGB"; std::cout << std::endl; // Destinations glActiveTexture(GL_TEXTURE0 + i + 2); checkGLError(); glBindTexture(GL_TEXTURE_2D, dstTexId[i]); checkGLError(); if( i < 2 ) { glTexStorage2D(GL_TEXTURE_2D, 1, texSizedFormat, 1, 1); checkGLError(); glTextureView(dstTexId[i+2], GL_TEXTURE_2D, dstTexId[i], texViewSizedFormat, 0, 1, 0, 1 ); checkGLError(); } glBindFramebuffer(GL_FRAMEBUFFER, dstFramebufferId[i]); checkGLError(); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTexId[i], 0); checkGLError(); // Check framebuffer has expected SRGBness glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &colorEncoding); std::cout << prefix << "Expected framebuffer encoding (destination): " << expected << ", got: "; if (colorEncoding == GL_LINEAR) std::cout << "GL_LINEAR"; else if (colorEncoding == GL_SRGB) std::cout << "GL_SRGB"; std::cout << std::endl; } }