Adding a programmable image shader to gl_hud

- add a framebuffer to gl_hud with programmable image shader
- add optional SSAO image shader to the new framebuffer
- add screenshot to png functionality
- implement in glViewer

note: ptexViewer and some others still need refactoring to use the new hud capabilities
This commit is contained in:
manuelk 2014-05-15 13:53:43 -07:00
parent 5ff9edf4f9
commit 9913e349df
22 changed files with 1040 additions and 50 deletions

View File

@ -22,8 +22,18 @@
# language governing permissions and limitations under the Apache License.
#
if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
# optional dependency - enables screenshots in some examples
find_package(PNG)
if (PNG_FOUND)
include_directories("${PNG_INCLUDE_DIRS}")
list(APPEND PLATFORM_LIBRARIES "${PNG_LIBRARIES}")
add_definitions(-DOPENSUBDIV_HAS_PNG)
endif()
add_subdirectory(common)
add_subdirectory(glViewer)

View File

@ -22,6 +22,11 @@
# language governing permissions and limitations under the Apache License.
#
set(EXAMPLES_COMMON_SHADER_FILES
framebuffer.glsl
ssao.glsl
)
set(EXAMPLES_COMMON_SOURCE_FILES
font_image.cpp
hdr_reader.cpp
@ -43,10 +48,14 @@ set(EXAMPLES_COMMON_HEADER_FILES
if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
gl_common.cpp
gl_framebuffer.cpp
gl_hud.cpp
)
list(APPEND EXAMPLES_COMMON_HEADER_FILES
gl_common.h
gl_framebuffer.h
gl_hud.h
)
@ -81,10 +90,20 @@ endif()
include_directories(
"${PROJECT_SOURCE_DIR}/opensubdiv"
"${CMAKE_CURRENT_BINARY_DIR}"
)
set(INC_FILES )
_stringify("${EXAMPLES_COMMON_SHADER_FILES}" INC_FILES)
source_group("Shaders" FILES ${EXAMPLES_COMMON_SHADER_FILES})
source_group("Inc" FILES ${INC_FILES})
add_library(examples_common_obj
OBJECT
${EXAMPLES_COMMON_SOURCE_FILES}
${EXAMPLES_COMMON_HEADER_FILES}
${INC_FILES}
)

View File

@ -0,0 +1,66 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#version 410
//--------------------------------------------------------------
// image vertex shader
//--------------------------------------------------------------
#ifdef IMAGE_VERTEX_SHADER
layout (location=0) in vec2 position;
out vec2 outUV;
void
main()
{
outUV = vec2(position.xy*0.5) + vec2(0.5);
gl_Position = vec4(position.x, position.y, 0, 1);
}
#endif
//--------------------------------------------------------------
#ifdef IMAGE_FRAGMENT_SHADER
uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D depthMap;
in vec2 outUV;
out vec4 outColor;
void main()
{
vec4 colorSample = texture(colorMap, outUV);
//background color as a vertical grey ramp
vec4 bgColor = vec4(mix(0.05, 0.25, outUV.y));
outColor = mix(bgColor, colorSample, colorSample.a);
}
#endif

View File

@ -0,0 +1,57 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "gl_common.h"
void
checkGLErrors(std::string const & where) {
GLuint err;
while ((err = glGetError()) != GL_NO_ERROR) {
std::cerr << "GL error: "
<< (where.empty() ? "" : where + " ")
<< err << "\n";
}
}
GLuint
compileShader(GLenum shaderType, const char *source) {
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLchar emsg[40960];
glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error compiling GLSL shader: %s\n", emsg);
return 0;
}
return shader;
}

View File

@ -0,0 +1,38 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef GL_COMMON_H
#define GL_COMMON_H
#include <osd/opengl.h>
#include <cstdio>
#include <string>
#include <iostream>
void checkGLErrors(std::string const & where = "");
GLuint compileShader(GLenum shaderType, const char *source);
#endif // GL_FRAMEBUFFER_H

View File

@ -0,0 +1,476 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "gl_framebuffer.h"
#include "gl_common.h"
#include "gl_hud.h"
#include <cstdlib>
#include <cassert>
#include <iostream>
#ifdef OPENSUBDIV_HAS_PNG
#include <zlib.h>
#include <png.h>
#endif
GLFrameBuffer::GLFrameBuffer() :
_width(0), _height(0),
_frameBuffer(0),
_frameBufferColor(0),
_frameBufferNormal(0),
_frameBufferDepthTexture(0),
_program(0),
_vao(0),
_vbo(0) {
}
GLFrameBuffer::~GLFrameBuffer() {
glDeleteFramebuffers(1, &_frameBuffer);
glDeleteTextures(1, &_frameBufferColor);
glDeleteTextures(1, &_frameBufferNormal);
glDeleteTextures(1, &_frameBufferDepthTexture);
glDeleteProgram(_program);
glDeleteVertexArrays(1, &_vao);
glDeleteBuffers(1, &_vbo);
}
static const char *g_framebufferShaderSource =
#include "framebuffer.gen.h"
;
void
GLFrameBuffer::Init(int width, int height) {
_width = width;
_height = height;
if (not _program)
_program = compileProgram(g_framebufferShaderSource);
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
float pos[] = { -1, -1, 1, -1, -1, 1, 1, 1 };
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(pos), pos, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenFramebuffers(1, &_frameBuffer);
glGenTextures(1, &_frameBufferColor);
glGenTextures(1, &_frameBufferNormal);
glGenTextures(1, &_frameBufferDepthTexture);
glBindTexture(GL_TEXTURE_2D, _frameBufferColor);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, _frameBufferNormal);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, _frameBufferDepthTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
checkGLErrors("FrameBuffer::Init");
}
void
GLFrameBuffer::Bind() const {
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
GLenum buffers[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, buffers);
}
GLuint
GLFrameBuffer::compileProgram(char const * src) {
GLuint program = glCreateProgram();
std::string vertexSrc = std::string("#define IMAGE_VERTEX_SHADER\n") + src;
GLuint vs = compileShader(GL_VERTEX_SHADER, vertexSrc.c_str());
std::string fragmentSrc = std::string("#define IMAGE_FRAGMENT_SHADER\n") + src;
GLuint fs = compileShader(GL_FRAGMENT_SHADER, fragmentSrc.c_str());
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
char *infoLog = new char[infoLogLength];
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
printf("%s\n", infoLog);
delete[] infoLog;
}
#if defined(GL_ARB_separate_shader_objects) or defined(GL_VERSION_4_1)
GLint colorMap = glGetUniformLocation(program, "colorMap");
if (colorMap != -1)
glProgramUniform1i(program, colorMap, 0); // GL_TEXTURE0
GLint normalMap = glGetUniformLocation(program, "normalMap");
if (normalMap != -1)
glProgramUniform1i(program, normalMap, 1); // GL_TEXTURE1
GLint depthMap = glGetUniformLocation(program, "depthMap");
if (depthMap != -1)
glProgramUniform1i(program, depthMap, 2); // GL_TEXTURE2
#else
glUseProgram(program);
GLint colorMap = glGetUniformLocation(program, "colorMap");
if (colorMap != -1)
glUniform1i(colorMap, 0); // GL_TEXTURE0
GLint colorMap = glGetUniformLocation(program, "normalMap");
if (normalMap != -1)
glUniform1i(normalMap, 1); // GL_TEXTURE1
GLint depthMap = glGetUniformLocation(program, "depthMap");
if (depthMap != -1)
glUniform1i(depthMap, 2); // GL_TEXTURE2
#endif
return program;
}
void
GLFrameBuffer::ApplyImageShader() {
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, GetWidth(), GetHeight());
glUseProgram(_program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _frameBufferColor);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _frameBufferNormal);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, _frameBufferDepthTexture);
glBindVertexArray(_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glUseProgram(0);
}
void
GLFrameBuffer::Reshape(int width, int height) {
// resize framebuffers
glBindTexture(GL_TEXTURE_2D, _frameBufferColor);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, _frameBufferNormal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_RGB, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, _frameBufferDepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, _frameBufferColor, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D, _frameBufferNormal, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, _frameBufferDepthTexture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
assert(false);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
_width=width;
_height=height;
}
void
GLFrameBuffer::BuildUI(GLhud * /* hud */, int /* x */, int /* y */) {
}
void
GLFrameBuffer::Screenshot() const {
#ifdef OPENSUBDIV_HAS_PNG
int width = GetWidth(),
height = GetHeight();
void * buf = malloc(GetWidth() * GetHeight() * 4 /*RGBA*/);
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
GLint restoreBinding, restoreActiveTexture;
glGetIntegerv( GL_TEXTURE_BINDING_2D, &restoreBinding );
glGetIntegerv( GL_ACTIVE_TEXTURE, & restoreActiveTexture);
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, _frameBufferColor );
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
glActiveTexture( restoreActiveTexture );
glBindTexture( GL_TEXTURE_2D, restoreBinding );
glPopClientAttrib();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static int counter=0;
char fname[64];
snprintf(fname, 64, "screenshot.%d.png", counter++);
if (FILE * f = fopen( fname, "w" )) {
png_structp png_ptr =
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert(png_ptr);
png_infop info_ptr =
png_create_info_struct(png_ptr);
assert(info_ptr);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT );
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
png_bytep rows_ptr[ height ];
for(int i = 0; i<height; ++i ) {
rows_ptr[height-i-1] = ((png_byte *)buf) + i*width*4;
}
png_set_rows(png_ptr, info_ptr, rows_ptr);
png_init_io(png_ptr, f);
png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0 );
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(f);
fprintf(stdout, "Saved %s\n", fname);
} else {
fprintf(stderr, "Error creating: %s\n", fname);
}
free(buf);
#endif
}
SSAOGLFrameBuffer::SSAOGLFrameBuffer() :
_active(1),
_radius(0),
_scale(0),
_gamma(0),
_contrast(0) {
}
static const char *g_ssaoShaderSource =
#include "ssao.gen.h"
;
void
SSAOGLFrameBuffer::Init(int width, int height) {
setProgram( compileProgram(g_ssaoShaderSource) );
GLFrameBuffer::Init(width, height);
GLuint program = getProgram();
glUseProgram(program);
_radius = glGetUniformLocation(program, "radius");
_scale = glGetUniformLocation(program, "scale");
_gamma = glGetUniformLocation(program, "gamma");
_contrast = glGetUniformLocation(program, "contrast");
SetRadius(0.01f);
SetScale(300.0f);
SetContrast(1.0f);
SetGamma(1.0f);
checkGLErrors("SSAOGLFrameBuffer::Init");
}
void
SSAOGLFrameBuffer::ApplyImageShader() {
GLFrameBuffer::ApplyImageShader();
}
// nasty hack until callbacks carry pointers
static SSAOGLFrameBuffer * g_ssaofb=0;
static void
callbackCheckbox(bool value, int /* data */) {
g_ssaofb->SetActive(value);
}
static void
callbackSlider(float value, int data) {
switch (data) {
case 0: g_ssaofb->SetRadius(value); break;
case 1: g_ssaofb->SetScale(value); break;
case 2: g_ssaofb->SetGamma(value); break;
case 3: g_ssaofb->SetContrast(value); break;
default:
assert(0);
}
}
void
SSAOGLFrameBuffer::BuildUI(GLhud * hud, int x, int y) {
g_ssaofb = this;
hud->AddCheckBox("SSAO", _active, x, y, callbackCheckbox);
hud->AddSlider("Radius", 0.0f, 0.1f, 0.01f, x+20, y+20, 20, false, callbackSlider, 0);
hud->AddSlider("Scale", 1.0f, 1000.0f, 300.0f, x+20, y+60, 20, false, callbackSlider, 1);
//hud->AddSlider("Gamma", 0.0f, 1.0f, 1.0f, x+20, y+100, 20, false, callbackSlider, 2);
//hud->AddSlider("Contrast", 0.0f, 1.0f, 1.0f, x+20, y+140, 20, false, callbackSlider, 3);
}
void
SSAOGLFrameBuffer::SetActive(bool value) {
if ( (_active = value) ) {
SSAOGLFrameBuffer::Init(GetWidth(), GetHeight());
} else {
setProgram( compileProgram(g_framebufferShaderSource) );
}
}
void
SSAOGLFrameBuffer::SetRadius(float value) {
GLuint program = getProgram();
if (_radius!=-1 and program>0) {
#if defined(GL_ARB_separate_shader_objects) or defined(GL_VERSION_4_1)
glProgramUniform1f(program, _radius, value);
#else
glUseProgram(program);
glUniform1f(_radius, value);
#endif
}
}
void
SSAOGLFrameBuffer::SetScale(float value) {
GLuint program = getProgram();
if (_scale!=-1 and program>0) {
#if defined(GL_ARB_separate_shader_objects) or defined(GL_VERSION_4_1)
glProgramUniform1f(program, _scale, value);
#else
glUseProgram(program);
glUniform1f(_scale, value);
#endif
}
}
void
SSAOGLFrameBuffer::SetGamma(float value) {
GLuint program = getProgram();
if (_gamma!=-1 and program>0) {
#if defined(GL_ARB_separate_shader_objects) or defined(GL_VERSION_4_1)
glProgramUniform1f(program, _gamma, value);
#else
glUseProgram(program);
glUniform1f(_gamma, value);
#endif
}
}
void
SSAOGLFrameBuffer::SetContrast(float value) {
GLuint program = getProgram();
if (_contrast!=-1 and program>0) {
#if defined(GL_ARB_separate_shader_objects) or defined(GL_VERSION_4_1)
glProgramUniform1f(program, _contrast, value);
#else
glUseProgram(program);
glUniform1f(_contrast, value);
#endif
}
}

View File

@ -0,0 +1,128 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef GL_FRAMEBUFFER_H
#define GL_FRAMEBUFFER_H
#include <osd/opengl.h>
class GLhud;
//------------------------------------------------------
class GLFrameBuffer {
public:
int GetWidth() const {
return _width;
}
int GetHeight() const {
return _height;
}
virtual void Init(int width, int height);
virtual void Reshape(int width, int height);
virtual void ApplyImageShader();
virtual void Bind() const;
virtual void BuildUI(GLhud * hud, int x, int y);
void Screenshot() const;
protected:
friend class GLhud;
GLFrameBuffer();
virtual ~GLFrameBuffer();
GLuint getFrameBuffer() {
return _frameBuffer;
}
GLuint getProgram() {
return _program;
}
void setProgram(GLuint program) {
if (_program) {
glDeleteProgram(_program);
}
_program = program;
}
GLuint compileProgram(char const * src);
private:
int _width, _height;
GLuint _frameBuffer;
GLuint _frameBufferColor;
GLuint _frameBufferNormal;
GLuint _frameBufferDepthTexture;
GLuint _program;
GLuint _vao;
GLuint _vbo;
};
//------------------------------------------------------
class SSAOGLFrameBuffer : public GLFrameBuffer {
public:
SSAOGLFrameBuffer();
virtual void Init(int width, int height);
virtual void ApplyImageShader();
virtual void BuildUI(GLhud * hud, int x, int y);
void SetActive(bool value);
void SetRadius(float value);
void SetScale(float value);
void SetGamma(float value);
void SetContrast(float value);
private:
bool _active;
GLint _radius,
_scale,
_gamma,
_contrast;
};
#endif // GL_FRAMEBUFFER_H

View File

@ -23,12 +23,16 @@
//
#include "gl_hud.h"
#include "gl_common.h"
#include "font_image.h"
#include "simple_math.h"
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cassert>
#include <iostream>
static const char *s_VS =
#if defined(GL_VERSION_3_1)
@ -84,7 +88,7 @@ static const char *s_FS =
"}\n";
#endif
GLhud::GLhud() : _fontTexture(0), _vbo(0), _staticVbo(0),
GLhud::GLhud() : _frameBuffer(0), _fontTexture(0), _vbo(0), _staticVbo(0),
_vao(0), _staticVao(0), _program(0),
_aPosition(0), _aColor(0), _aUV(0)
{
@ -92,6 +96,8 @@ GLhud::GLhud() : _fontTexture(0), _vbo(0), _staticVbo(0),
GLhud::~GLhud()
{
if (_frameBuffer)
delete _frameBuffer;
if (_program)
glDeleteProgram(_program);
if (_fontTexture)
@ -106,15 +112,6 @@ GLhud::~GLhud()
glDeleteVertexArrays(1, &_staticVao);
}
static GLuint compileShader(GLenum shaderType, const char *source)
{
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
return shader;
}
void
GLhud::Init(int width, int height)
{
@ -193,6 +190,14 @@ GLhud::Init(int width, int height)
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
checkGLErrors("GLhud::Init");
_frameBuffer = new SSAOGLFrameBuffer;
_frameBuffer->Init(width, height);
_frameBuffer->BuildUI(this, 10, 600);
}
void
@ -208,6 +213,8 @@ GLhud::Rebuild(int width, int height)
glBufferData(GL_ARRAY_BUFFER, _staticVboSize * sizeof(float),
&getStaticVboSource()[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GetFrameBuffer()->Reshape(width, height);
}
bool
@ -222,12 +229,11 @@ GLhud::Flush()
glBufferData(GL_ARRAY_BUFFER, getVboSource().size() * sizeof(float),
&getVboSource()[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* (x, y, r, g, b, u, v) = 7*/
// (x, y, r, g, b, u, v) = 7
int numVertices = (int)getVboSource().size()/7;
// reserved space of the vector remains for the next frame.
getVboSource().clear();
glUseProgram(_program);
float proj[16];
ortho(proj, 0, 0, float(GetWidth()), float(GetHeight()));
@ -248,3 +254,4 @@ GLhud::Flush()
return true;
}

View File

@ -29,8 +29,10 @@
#include <osd/opengl.h>
class GLhud : public Hud
{
#include "gl_framebuffer.h"
class GLhud : public Hud {
public:
GLhud();
~GLhud();
@ -41,7 +43,15 @@ public:
virtual bool Flush();
GLFrameBuffer * GetFrameBuffer() {
return _frameBuffer;
}
private:
GLFrameBuffer * _frameBuffer;
GLuint _fontTexture;
GLuint _vbo, _staticVbo;
GLuint _vao, _staticVao;

View File

@ -208,7 +208,7 @@ Hud::MouseClick(int x, int y)
}
void
Hud::MouseMotion(int x, int y)
Hud::MouseMotion(int x, int /* y */)
{
if (_capturedSlider != -1) {
std::vector<Slider>::iterator it = _sliders.begin() + _capturedSlider;

168
examples/common/ssao.glsl Normal file
View File

@ -0,0 +1,168 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#version 410
//--------------------------------------------------------------
// image vertex shader
//--------------------------------------------------------------
#ifdef IMAGE_VERTEX_SHADER
layout (location=0) in vec2 position;
out vec2 outUV;
void
main()
{
outUV = vec2(position.xy*0.5) + vec2(0.5);
gl_Position = vec4(position.x, position.y, 0, 1);
}
#endif
//--------------------------------------------------------------
#ifdef IMAGE_FRAGMENT_SHADER
uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D depthMap;
in vec2 outUV;
out vec4 outColor;
const vec2 oflut[49] = vec2[](
vec2(-0.864,-0.930),
vec2(-0.952,-0.608),
vec2(-0.820,-0.318),
vec2(-0.960,-0.076),
vec2(-0.939,0.244),
vec2(-0.827,0.421),
vec2(-0.871,0.561),
vec2(-0.668,-0.810),
vec2(-0.749,-0.557),
vec2(-0.734,-0.422),
vec2(-0.681,-0.043),
vec2(-0.598,0.132),
vec2(-0.720,0.323),
vec2(-0.513,0.723),
vec2(-0.371,-0.829),
vec2(-0.366,-0.735),
vec2(-0.259,-0.318),
vec2(-0.344,-0.079),
vec2(-0.386,0.196),
vec2(-0.405,0.425),
vec2(-0.310,0.518),
vec2(-0.154,-0.931),
vec2(-0.171,-0.572),
vec2(-0.241,-0.420),
vec2(-0.130,-0.225),
vec2(-0.092,0.189),
vec2(-0.018,0.310),
vec2(-0.179,0.512),
vec2(0.133,-0.942),
vec2(0.235,-0.738),
vec2(0.229,-0.380),
vec2(0.027,-0.030),
vec2(0.052,0.183),
vec2(0.141,0.415),
vec2(0.129,0.736),
vec2(0.340,-0.931),
vec2(0.254,-0.564),
vec2(0.388,-0.417),
vec2(0.363,-0.104),
vec2(0.413,0.234),
vec2(0.421,0.321),
vec2(0.423,0.653),
vec2(0.631,-0.756),
vec2(0.665,-0.736),
vec2(0.551,-0.350),
vec2(0.526,-0.220),
vec2(0.519,0.053),
vec2(0.750,0.321),
vec2(0.736,0.641) );
float ZBuffer2Linear( float z ,float znear, float zfar)
{
float z_n = 2.0 * z - 1.0;
float z_e = 2.0 * znear * zfar / (zfar+znear-z_n*(zfar-znear));
return z_e / 10.0;
}
uniform float radius;
uniform float scale;
uniform float gamma;
uniform float contrast;
void main()
{
vec4 colorSample = texture(colorMap, outUV);
float zbuffer = texture(depthMap, outUV).r;
float rz = ZBuffer2Linear( zbuffer, 1.0, 500.0 );
float an = fract(fract(outUV.x*0.36257507)*0.38746515+outUV.y*0.32126721);
float k1=cos(6.2831*an);
float k2=sin(6.2831*an);
// calculate occlusion factor
float ao = 0.0;
for( int i=0; i<49; i++ )
{
vec2 of = vec2( oflut[i].x*k1 - oflut[i].y*k2,
oflut[i].x*k2 + oflut[i].y*k1 );
//sampling point
vec2 sa = outUV.xy + radius * of;
//difference in zbuffer
float zd = rz - ZBuffer2Linear( texture(depthMap, sa).r, 1.0, 500.0);
//adjust based on scale.
zd = zd * scale;
//accumulate zdiffs transfer func
ao += clamp( zd, 0.0, 1.0 ) - clamp((zd-5.0)*.02,0.0,1.0);
}
//add in occlusion to color.
ao = 1.0 - ao/49.0;
//scale occlusion toward white.
ao = clamp(ao, 0.0, 1.0);
//add in contrast/gamma to colorsample.
outColor = contrast*pow(colorSample*ao,vec4(gamma));
//background color as a vertical grey ramp
vec4 bgColor = vec4(mix(0.05, 0.25, outUV.y));
outColor = mix(bgColor, outColor, colorSample.a);
}
#endif

View File

@ -28,7 +28,7 @@ set(SHADER_FILES
shader.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"

View File

@ -29,7 +29,7 @@ set(SHADER_FILES
shader_gl3.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"

View File

@ -24,7 +24,7 @@
# *** glStencilViewer ***
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${GLFW_LIBRARIES}"
)

View File

@ -29,18 +29,18 @@ set(SHADER_FILES
shader_gl3.glsl
)
set(PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"
)
include_directories(
"${PROJECT_SOURCE_DIR}/opensubdiv"
"${PROJECT_SOURCE_DIR}/regression"
"${GLFW_INCLUDE_DIR}"
)
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"
)
if ( GLEW_FOUND )
include_directories("${GLEW_INCLUDE_DIR}")
list(APPEND PLATFORM_LIBRARIES "${GLEW_LIBRARY}")

View File

@ -300,6 +300,7 @@ in block {
} inpt;
out vec4 outColor;
out vec3 outNormal;
#define NUM_LIGHTS 2
@ -392,6 +393,7 @@ main()
#endif
outColor = Cf;
outNormal = N;
}
#endif

View File

@ -264,11 +264,9 @@ checkGLErrors(std::string const & where = "")
{
GLuint err;
while ((err = glGetError()) != GL_NO_ERROR) {
/*
std::cerr << "GL error: "
<< (where.empty() ? "" : where + " ")
<< err << "\n";
*/
}
}
@ -636,7 +634,6 @@ getKernelName(int kernel) {
static void
createOsdMesh( const std::string &shape, int level, int kernel, Scheme scheme=kCatmark ) {
checkGLErrors("create osd enter");
// generate Hbr representation from "obj" description
OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape.c_str(), scheme, g_orgPositions,
g_displayStyle == kFaceVaryingColor);
@ -1258,6 +1255,8 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
static void
display() {
g_hud.GetFrameBuffer()->Bind();
Stopwatch s;
s.Start();
@ -1275,7 +1274,7 @@ display() {
translate(g_transformData.ModelViewMatrix,
-g_center[0], -g_center[1], -g_center[2]);
perspective(g_transformData.ProjectionMatrix,
45.0f, (float)aspect, 0.01f, 500.0f);
45.0f, (float)aspect, 1.0f, 500.0f);
multMatrix(g_transformData.ModelViewProjectionMatrix,
g_transformData.ModelViewMatrix,
g_transformData.ProjectionMatrix);
@ -1286,6 +1285,8 @@ display() {
if (g_displayStyle == kVaryingColor)
g_mesh->BindVaryingBuffer();
glEnable(GL_DEPTH_TEST);
glBindVertexArray(g_vao);
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
@ -1389,6 +1390,8 @@ display() {
if (g_drawCageVertices)
drawCageVertices();
g_hud.GetFrameBuffer()->ApplyImageShader();
GLuint numPrimsGenerated = 0;
GLuint timeElapsed = 0;
glGetQueryObjectuiv(g_queries[0], GL_QUERY_RESULT, &numPrimsGenerated);
@ -1450,7 +1453,7 @@ display() {
glFinish();
checkGLErrors("display leave");
//checkGLErrors("display leave");
}
//------------------------------------------------------------------------------
@ -1461,8 +1464,10 @@ motion(GLFWwindow *, double dx, double dy) {
#else
motion(int x, int y) {
#endif
if (g_mbutton[0] && !g_mbutton[1] && !g_mbutton[2]) {
if (g_hud.MouseCapture()) {
// check gui
g_hud.MouseMotion(x, y);
} else if (g_mbutton[0] && !g_mbutton[1] && !g_mbutton[2]) {
// orbit
g_rotate[0] += x - g_prev_x;
g_rotate[1] += y - g_prev_y;
@ -1484,11 +1489,14 @@ motion(int x, int y) {
//------------------------------------------------------------------------------
static void
#if GLFW_VERSION_MAJOR>=3
mouse(GLFWwindow *, int button, int state, int mods) {
mouse(GLFWwindow *, int button, int state, int /* mods */) {
#else
mouse(int button, int state) {
#endif
if (state == GLFW_RELEASE)
g_hud.MouseRelease();
if (button == 0 && state == GLFW_PRESS && g_hud.MouseClick(g_prev_x, g_prev_y))
return;
@ -1585,7 +1593,7 @@ toggleFullScreen() {
//------------------------------------------------------------------------------
static void
#if GLFW_VERSION_MAJOR>=3
keyboard(GLFWwindow *, int key, int scancode, int event, int mods) {
keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */) {
#else
#define GLFW_KEY_ESCAPE GLFW_KEY_ESC
keyboard(int key, int event) {
@ -1602,6 +1610,7 @@ keyboard(int key, int event) {
case '=': g_tessLevel++; break;
case '-': g_tessLevel = std::max(g_tessLevelMin, g_tessLevel-1); break;
case GLFW_KEY_ESCAPE: g_hud.SetVisible(!g_hud.IsVisible()); break;
case 'X': g_hud.GetFrameBuffer()->Screenshot(); break;
}
}
@ -1670,7 +1679,7 @@ callbackModel(int m)
}
static void
callbackAdaptive(bool checked, int a)
callbackAdaptive(bool checked, int /* a */)
{
if (OpenSubdiv::OsdGLDrawContext::SupportsAdaptiveTessellation()) {
g_adaptive = checked;
@ -1789,7 +1798,7 @@ initHUD()
static void
initGL()
{
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glCullFace(GL_BACK);

View File

@ -24,7 +24,7 @@
# *** glViewer ***
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${GLFW_LIBRARIES}"
)

View File

@ -29,7 +29,7 @@ set(SHADER_FILES
paintShader.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLEW_LIBRARY}"

View File

@ -31,7 +31,7 @@ set(SHADER_FILES
imageshader.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"

View File

@ -28,7 +28,7 @@ set(SHADER_FILES
shader.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"

View File

@ -28,7 +28,7 @@ set(SHADER_FILES
shader.glsl
)
set(PLATFORM_LIBRARIES
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LIBRARY}"
"${GLFW_LIBRARIES}"