Created
January 5, 2014 05:36
-
-
Save ishikawash/8264836 to your computer and use it in GitHub Desktop.
Instanced rendering demo using openFrameworks Part 2.
The shader program use vertex attributes instead of uniform variables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 120 | |
uniform vec3 light_direction; | |
varying vec3 vertex_normal; | |
varying vec3 vertex_color; | |
void main(void) { | |
vec3 N = normalize(vertex_normal); | |
vec3 L = normalize(light_direction); | |
float kd = clamp(dot(N, L), 0.0f, 1.0f); | |
vec3 color = kd * vertex_color; | |
gl_FragColor = vec4(color, 1.0f); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 120 | |
#extension GL_EXT_gpu_shader4 : require | |
uniform vec3 colors[2]; | |
varying vec3 vertex_normal; | |
varying vec3 vertex_color; | |
attribute mat4 model_matrix; | |
attribute mat3 normal_matrix; | |
void main(void) { | |
vertex_normal = normal_matrix * gl_Normal; | |
vertex_color = colors[gl_InstanceID % 2]; | |
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * model_matrix * gl_Vertex; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ofMain.h" | |
#include "testApp.h" | |
//======================================================================== | |
int main( ){ | |
ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context | |
// this kicks off the running of my app | |
// can be OF_WINDOW or OF_FULLSCREEN | |
// pass in width and height too: | |
ofRunApp(new testApp()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "testApp.h" | |
using namespace std; | |
using namespace glm; | |
const int GRID_LENGTH = 10; | |
const float GRID_OFFSET = 20.0f; | |
const float BOX_SIZE = 20.0f; | |
void printMatrix4fv(const float *m) { | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
printf("%8.2f\t", m[4*i + j]); | |
} | |
printf("\n"); | |
} | |
printf("\n"); | |
} | |
void testApp::uniformMatrix4fv(const char *name, const float *m) { | |
GLint location = glGetUniformLocation(shader.getProgram(), name); | |
if (location != -1) | |
glUniformMatrix4fv(location, 1, GL_FALSE, m); | |
} | |
void testApp::uniformMatrix3fv(const char *name, const float *m) { | |
GLint location = glGetUniformLocation(shader.getProgram(), name); | |
if (location != -1) | |
glUniformMatrix3fv(location, 1, GL_FALSE, m); | |
} | |
void testApp::bindBuffers() { | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.model_matrix); | |
for (int i = 0; i < 4; i++) { | |
GLint location = attribLocation.model_matrix + i; | |
int offset = sizeof(vec4)*i; | |
glEnableVertexAttribArray(location); | |
glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (GLvoid*)offset); | |
glVertexAttribDivisorARB(location, 1); | |
} | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.normal_matrix); | |
for (int i = 0; i < 3; i++) { | |
GLint location = attribLocation.normal_matrix + i; | |
int offset = sizeof(vec3)*i; | |
glEnableVertexAttribArray(location); | |
glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, sizeof(mat3), (GLvoid*)offset); | |
glVertexAttribDivisorARB(location, 1); | |
} | |
} | |
void testApp::unbindBuffers() { | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
} | |
//-------------------------------------------------------------- | |
void testApp::setup(){ | |
ofEnableDepthTest(); | |
bg_colors[0].set(255.0f); | |
bg_colors[1].set(96.0f); | |
box.set(BOX_SIZE); | |
vboMesh = box.getMesh(); | |
const ivec3 grid_size(GRID_LENGTH); | |
nodes.resize(grid_size.x*grid_size.y*grid_size.z); | |
const vec3 grid_box_size(box.getWidth() + GRID_OFFSET, box.getHeight() + GRID_OFFSET, box.getDepth() + GRID_OFFSET); | |
const vec3 grid_center = 0.5f*vec3(grid_size.x*box.getWidth() + (grid_size.x - 1)*GRID_OFFSET, | |
grid_size.y*box.getHeight() + (grid_size.y - 1)*GRID_OFFSET, | |
grid_size.z*box.getDepth() + (grid_size.z - 1)*GRID_OFFSET); | |
for (int k = 0; k < grid_size.z; k++) { | |
for (int j = 0; j < grid_size.y; j++) { | |
for (int i = 0; i < grid_size.x; i++) { | |
ofNode &node = nodes[grid_size.x*grid_size.y*k + grid_size.x*j + i]; | |
node.move(-grid_center.x, -grid_center.y, -grid_center.z); | |
node.move(grid_box_size.x*i, grid_box_size.y*j, grid_box_size.z*k); | |
node.setParent(parent); | |
} | |
} | |
} | |
camera.move(0.0f, 0.0f, 800.0f); | |
shader.load("box.vs", "box.fs"); | |
shader.begin(); | |
{ | |
vec3 light_direction(0.0f, 1.0f, 1.0f); | |
shader.setUniform3fv("light_direction", value_ptr(light_direction)); | |
vec3 box_colors[2]; | |
box_colors[0] = vec3(0.0f, 0.0f, 0.0f); | |
box_colors[1] = vec3(1.0f, 1.0f, 1.0f); | |
char name[64]; | |
for (int i = 0; i < 2; i++) { | |
snprintf(name, sizeof(name), "colors[%d]", i); | |
shader.setUniform3fv(name, value_ptr(box_colors[i])); | |
} | |
attribLocation.model_matrix = shader.getAttributeLocation("model_matrix"); | |
attribLocation.normal_matrix = shader.getAttributeLocation("normal_matrix"); | |
} | |
shader.end(); | |
modelMatrices.resize(nodes.size()); | |
glGenBuffers(1, &bufferHandle.model_matrix); | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.model_matrix); | |
glBufferData(GL_ARRAY_BUFFER, nodes.size() * sizeof(mat4), value_ptr(modelMatrices[0]), GL_DYNAMIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
normalMatrices.resize(nodes.size()); | |
glGenBuffers(1, &bufferHandle.normal_matrix); | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.normal_matrix); | |
glBufferData(GL_ARRAY_BUFFER, nodes.size() * sizeof(mat3), value_ptr(normalMatrices[0]), GL_DYNAMIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
} | |
//-------------------------------------------------------------- | |
void testApp::update(){ | |
float t = ofGetElapsedTimef(); | |
float theta = 180.0f*ofGetLastFrameTime(); | |
parent.rotate(theta, cosf(t), sinf(t), 0.0f); | |
shader.begin(); | |
{ | |
glGetFloatv(GL_MODELVIEW_MATRIX, buf); | |
mat4 view_matrix; | |
memcpy(&view_matrix[0][0], buf, sizeof(buf)); | |
for (int i = 0; i < nodes.size(); i++) { | |
ofNode &node = nodes[i]; | |
mat4 &model_matrix = modelMatrices[i]; | |
memcpy(&model_matrix[0][0], node.getGlobalTransformMatrix().getPtr(), sizeof(mat4)); | |
mat4 model_view_matrix = view_matrix*model_matrix; | |
normalMatrices[i] = mat3(transpose(inverse(model_view_matrix))); | |
} | |
} | |
shader.end(); | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.model_matrix); | |
glBufferSubData(GL_ARRAY_BUFFER, 0, nodes.size()*sizeof(mat4), value_ptr(modelMatrices[0])); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ARRAY_BUFFER, bufferHandle.normal_matrix); | |
glBufferSubData(GL_ARRAY_BUFFER, 0, nodes.size()*sizeof(mat3), value_ptr(normalMatrices[0])); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
} | |
//-------------------------------------------------------------- | |
void testApp::draw(){ | |
ofBackgroundGradient(bg_colors[0], bg_colors[1], OF_GRADIENT_BAR); | |
camera.begin(); | |
{ | |
shader.begin(); | |
{ | |
bindBuffers(); | |
{ | |
vboMesh.drawInstanced(OF_MESH_FILL, nodes.size()); | |
} | |
unbindBuffers(); | |
} | |
shader.end(); | |
} | |
camera.end(); | |
} | |
//-------------------------------------------------------------- | |
void testApp::keyPressed(int key){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::keyReleased(int key){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::mouseMoved(int x, int y ){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::mouseDragged(int x, int y, int button){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::mousePressed(int x, int y, int button){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::mouseReleased(int x, int y, int button){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::windowResized(int w, int h){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::gotMessage(ofMessage msg){ | |
} | |
//-------------------------------------------------------------- | |
void testApp::dragEvent(ofDragInfo dragInfo){ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <glm/glm.hpp> | |
#include <glm/gtc/type_ptr.hpp> | |
#include "ofMain.h" | |
struct VertexBufferHandle { | |
GLuint model_matrix; | |
GLuint normal_matrix; | |
}; | |
struct VertexAttribLocation { | |
GLint model_matrix; | |
GLint normal_matrix; | |
}; | |
class testApp : public ofBaseApp{ | |
public: | |
void setup(); | |
void update(); | |
void draw(); | |
void keyPressed(int key); | |
void keyReleased(int key); | |
void mouseMoved(int x, int y ); | |
void mouseDragged(int x, int y, int button); | |
void mousePressed(int x, int y, int button); | |
void mouseReleased(int x, int y, int button); | |
void windowResized(int w, int h); | |
void dragEvent(ofDragInfo dragInfo); | |
void gotMessage(ofMessage msg); | |
ofCamera camera; | |
ofNode parent; | |
std::vector<ofNode> nodes; | |
ofBoxPrimitive box; | |
ofShader shader; | |
ofVboMesh vboMesh; | |
VertexBufferHandle bufferHandle; | |
VertexAttribLocation attribLocation; | |
std::vector<glm::mat4> modelMatrices; | |
std::vector<glm::mat3> normalMatrices; | |
ofColor bg_colors[2]; | |
float buf[16]; | |
private: | |
void uniformMatrix3fv(const char *name, const float *m); | |
void uniformMatrix4fv(const char *name, const float *m); | |
void bindBuffers(); | |
void unbindBuffers(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment