#include "Renderer3d.h" #include "Camera3d.h" #include "WebglContext.h" const char* vertexSrc = "attribute vec3 position;\n" "attribute vec3 normal;\n" "attribute vec4 color;\n" "uniform mat4 projection;\n" "uniform mat4 view;\n" "uniform mat4 model;\n" "varying lowp vec4 VertexColor;\n" "varying lowp vec3 VertexNormal;\n" "void main() { \n" " vec4 fragmentPosition = projection * view * model * vec4(position, 1);" " gl_Position = fragmentPosition;\n" " VertexColor = color;\n" " mat3 normalMatrix = mat3(model);\n" " VertexNormal = normalize(normalMatrix * normal);\n" "}\n"; const char* fragmentSrc = "precision mediump float;\n" "varying lowp vec4 VertexColor; \n" "varying lowp vec3 VertexNormal; \n" "vec4 ambientColor = vec4(0.2, 0.2, 0.2, 1.0);\n" "vec3 lightDirection = vec3(0.0, 1.0, 0.0);\n" "vec4 lightColor = vec4(0.7, 0.7, 0.7, 1.0);\n" "void main() { \n" " vec4 finalColor = VertexColor * ambientColor;\n" " float normalDotDir = max(0.0, dot(VertexNormal, lightDirection));\n" " if (normalDotDir <= 0.0001) {" " finalColor += vec4(0, 0, 0, 0);" " }\n" " else {\n" " float cosTheta = clamp(normalDotDir, 0.0, 1.0);\n" " vec4 diffuseFactor = VertexColor * cosTheta;\n" " finalColor += lightColor * diffuseFactor; \n" " }\n" " gl_FragColor = finalColor;\n" "}"; void Renderer3d::load(WebglContext* context) { printf("Compiling 3d shader...\n"); shader = loadShader(vertexSrc, fragmentSrc); useShader(shader); attributes.position = getShaderAttribute(shader, "position"); attributes.color = getShaderAttribute(shader, "color"); attributes.normal = getShaderAttribute(shader, "normal"); uniforms.projection = getShaderUniform(shader, "projection"); uniforms.view = getShaderUniform(shader, "view"); uniforms.model = getShaderUniform(shader, "model"); printf("3d shader compiled.\n"); } void Renderer3d::render(Camera3d* camera) { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_TRUE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); useShader(shader); setShaderMat4(uniforms.projection, camera->projection); setShaderMat4(uniforms.view, camera->view); } void Renderer3d::unload() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDeleteProgram(shader); } void Mesh3d::load(Vertex3d* inVertices, uint32 inNumVertices, uint32* inIndices, uint32 inNumIndices, Renderer3d* renderer) { numIndices = inNumIndices; useShader(renderer->shader); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glGenBuffers(1, &ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, inNumVertices * sizeof(Vertex3d), &inVertices[0], GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, inNumIndices * sizeof(uint32), &inIndices[0], GL_STATIC_DRAW); glEnableVertexAttribArray(renderer->attributes.position); glVertexAttribPointer(renderer->attributes.position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)0); glEnableVertexAttribArray(renderer->attributes.normal); glVertexAttribPointer(renderer->attributes.normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)offsetof(Vertex3d, normal)); glEnableVertexAttribArray(renderer->attributes.color); glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)offsetof(Vertex3d, color)); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } void Mesh3d::render(Renderer3d* renderer, GLenum drawType) { setShaderMat4(renderer->uniforms.model, model); glBindVertexArray(vao); glDrawElements(drawType, numIndices, GL_UNSIGNED_INT, 0); glBindVertexArray(0); } void Mesh3d::unload() { glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); }