mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-13 09:43:15 +08:00
Support macOS + OpenGL 3.3+ GPU
This commit is contained in:
parent
d6b0b0b990
commit
b864ea7349
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
* glew
|
||||||
* glfw3
|
* glfw3
|
||||||
* premake5(linux)
|
* premake5(linux)
|
||||||
|
* OpenGL 3.3+ GPU
|
||||||
|
|
||||||
## Build on Linux
|
## Build on Linux and macOS
|
||||||
|
|
||||||
```
|
```
|
||||||
$ premake5 gmake
|
$ premake5 gmake
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include <iostream>
|
#include <fstream>
|
||||||
#include <fstream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
#include "window.h"
|
|
||||||
#include "shaders.h"
|
#include "shaders.h"
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#define TINYGLTF_IMPLEMENTATION
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||||
|
|
||||||
|
bool loadModel(tinygltf::Model &model, const char *filename) {
|
||||||
bool loadModel(tinygltf::Model &model, const char* filename)
|
|
||||||
{
|
|
||||||
tinygltf::TinyGLTF loader;
|
tinygltf::TinyGLTF loader;
|
||||||
std::string err;
|
std::string err;
|
||||||
std::string warn;
|
std::string warn;
|
||||||
@ -35,24 +33,25 @@ bool loadModel(tinygltf::Model &model, const char* filename)
|
|||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
std::cout << "Failed to load glTF: " << filename << std::endl;
|
std::cout << "Failed to load glTF: " << filename << std::endl;
|
||||||
else std::cout << "Loaded glTF: " << filename << std::endl;
|
else
|
||||||
|
std::cout << "Loaded glTF: " << filename << std::endl;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos,
|
||||||
std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos, tinygltf::Model &model, tinygltf::Mesh &mesh)
|
tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||||
{
|
|
||||||
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
|
for (size_t i = 0; i < model.bufferViews.size(); ++i) {
|
||||||
const tinygltf::BufferView &bufferView = model.bufferViews[i];
|
const tinygltf::BufferView &bufferView = model.bufferViews[i];
|
||||||
if (bufferView.target == 0) { // TODO impl drawarrays
|
if (bufferView.target == 0) { // TODO impl drawarrays
|
||||||
std::cout << "WARN: bufferView.target is zero" << std::endl;
|
std::cout << "WARN: bufferView.target is zero" << std::endl;
|
||||||
continue; // Unsupported bufferView.
|
continue; // Unsupported bufferView.
|
||||||
/*
|
/*
|
||||||
From spec2.0 readme: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
|
From spec2.0 readme:
|
||||||
... drawArrays function should be used with a count equal to the count
|
https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
|
||||||
property of any of the accessors referenced by the attributes property
|
... drawArrays function should be used with a count equal to
|
||||||
(they are all equal for a given primitive).
|
the count property of any of the accessors referenced by the attributes
|
||||||
|
property (they are all equal for a given primitive).
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,22 +63,22 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos, tinygltf::Model &mode
|
|||||||
vbos[i] = vbo;
|
vbos[i] = vbo;
|
||||||
glBindBuffer(bufferView.target, vbo);
|
glBindBuffer(bufferView.target, vbo);
|
||||||
|
|
||||||
std::cout << "buffer.data.size = " << buffer.data.size() << ", bufferview.byteOffset = "
|
std::cout << "buffer.data.size = " << buffer.data.size()
|
||||||
<< bufferView.byteOffset << std::endl;
|
<< ", bufferview.byteOffset = " << bufferView.byteOffset
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
glBufferData(bufferView.target, bufferView.byteLength,
|
glBufferData(bufferView.target, bufferView.byteLength,
|
||||||
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
|
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); ++i)
|
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
||||||
{
|
|
||||||
tinygltf::Primitive primitive = mesh.primitives[i];
|
tinygltf::Primitive primitive = mesh.primitives[i];
|
||||||
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
||||||
|
|
||||||
for (auto& attrib : primitive.attributes)
|
for (auto &attrib : primitive.attributes) {
|
||||||
{
|
|
||||||
tinygltf::Accessor accessor = model.accessors[attrib.second];
|
tinygltf::Accessor accessor = model.accessors[attrib.second];
|
||||||
int byteStride = accessor.ByteStride(model.bufferViews[accessor.bufferView]);
|
int byteStride =
|
||||||
|
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
|
glBindBuffer(GL_ARRAY_BUFFER, vbos[accessor.bufferView]);
|
||||||
|
|
||||||
int size = 1;
|
int size = 1;
|
||||||
@ -91,19 +90,13 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos, tinygltf::Model &mode
|
|||||||
if (attrib.first.compare("POSITION") == 0) vaa = 0;
|
if (attrib.first.compare("POSITION") == 0) vaa = 0;
|
||||||
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
|
if (attrib.first.compare("NORMAL") == 0) vaa = 1;
|
||||||
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
|
if (attrib.first.compare("TEXCOORD_0") == 0) vaa = 2;
|
||||||
if (vaa > -1)
|
if (vaa > -1) {
|
||||||
{
|
|
||||||
glEnableVertexAttribArray(vaa);
|
glEnableVertexAttribArray(vaa);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(vaa, size, accessor.componentType,
|
||||||
vaa,
|
|
||||||
size,
|
|
||||||
accessor.componentType,
|
|
||||||
accessor.normalized ? GL_TRUE : GL_FALSE,
|
accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||||
byteStride,
|
byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
||||||
BUFFER_OFFSET(accessor.byteOffset)
|
} else
|
||||||
);
|
std::cout << "vaa missing: " << attrib.first << std::endl;
|
||||||
}
|
|
||||||
else std::cout << "vaa missing: " << attrib.first << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint texid;
|
GLuint texid;
|
||||||
@ -119,17 +112,16 @@ std::map<int, GLuint> bindMesh(std::map<int, GLuint> vbos, tinygltf::Model &mode
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0,
|
||||||
image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
GL_RGBA, GL_UNSIGNED_BYTE, &image.image.at(0));
|
||||||
&image.image.at(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vbos;
|
return vbos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind models
|
// bind models
|
||||||
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model, tinygltf::Node &node)
|
void bindModelNodes(std::map<int, GLuint> vbos, tinygltf::Model &model,
|
||||||
{
|
tinygltf::Node &node) {
|
||||||
bindMesh(vbos, model, model.meshes[node.mesh]);
|
bindMesh(vbos, model, model.meshes[node.mesh]);
|
||||||
for (size_t i = 0; i < node.children.size(); i++) {
|
for (size_t i = 0; i < node.children.size(); i++) {
|
||||||
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
|
bindModelNodes(vbos, model, model.nodes[node.children[i]]);
|
||||||
@ -148,38 +140,32 @@ GLuint bindModel(tinygltf::Model &model) {
|
|||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
// cleanup vbos
|
// cleanup vbos
|
||||||
for (size_t i = 0; i < vbos.size(); ++i)
|
for (size_t i = 0; i < vbos.size(); ++i) {
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &vbos[i]);
|
glDeleteBuffers(1, &vbos[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vao;
|
return vao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh) {
|
||||||
|
for (size_t i = 0; i < mesh.primitives.size(); ++i) {
|
||||||
void drawMesh(tinygltf::Model &model, tinygltf::Mesh &mesh)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); ++i)
|
|
||||||
{
|
|
||||||
tinygltf::Primitive primitive = mesh.primitives[i];
|
tinygltf::Primitive primitive = mesh.primitives[i];
|
||||||
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
tinygltf::Accessor indexAccessor = model.accessors[primitive.indices];
|
||||||
|
|
||||||
glDrawElements(primitive.mode, indexAccessor.count, indexAccessor.componentType,
|
glDrawElements(primitive.mode, indexAccessor.count,
|
||||||
|
indexAccessor.componentType,
|
||||||
BUFFER_OFFSET(indexAccessor.byteOffset));
|
BUFFER_OFFSET(indexAccessor.byteOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursively draw node and children nodes of model
|
// recursively draw node and children nodes of model
|
||||||
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node)
|
void drawModelNodes(tinygltf::Model &model, tinygltf::Node &node) {
|
||||||
{
|
|
||||||
drawMesh(model, model.meshes[node.mesh]);
|
drawMesh(model, model.meshes[node.mesh]);
|
||||||
for (size_t i = 0; i < node.children.size(); i++) {
|
for (size_t i = 0; i < node.children.size(); i++) {
|
||||||
drawModelNodes(model, model.nodes[node.children[i]]);
|
drawModelNodes(model, model.nodes[node.children[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drawModel(GLuint vao, tinygltf::Model &model)
|
void drawModel(GLuint vao, tinygltf::Model &model) {
|
||||||
{
|
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
const tinygltf::Scene &scene = model.scenes[model.defaultScene];
|
||||||
@ -190,48 +176,40 @@ void drawModel(GLuint vao, tinygltf::Model &model)
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dbgModel(tinygltf::Model &model) {
|
||||||
|
for (auto &mesh : model.meshes) {
|
||||||
|
|
||||||
void dbgModel(tinygltf::Model &model)
|
|
||||||
{
|
|
||||||
for (auto &mesh : model.meshes)
|
|
||||||
{
|
|
||||||
std::cout << "mesh : " << mesh.name << std::endl;
|
std::cout << "mesh : " << mesh.name << std::endl;
|
||||||
for (auto &primitive : mesh.primitives)
|
for (auto &primitive : mesh.primitives) {
|
||||||
{
|
const tinygltf::Accessor &indexAccessor =
|
||||||
const tinygltf::Accessor &indexAccessor = model.accessors[primitive.indices];
|
model.accessors[primitive.indices];
|
||||||
|
|
||||||
std::cout << "indexaccessor: count " << indexAccessor.count << ", type " <<
|
std::cout << "indexaccessor: count " << indexAccessor.count << ", type "
|
||||||
indexAccessor.componentType << std::endl;
|
<< indexAccessor.componentType << std::endl;
|
||||||
|
|
||||||
tinygltf::Material &mat = model.materials[primitive.material];
|
tinygltf::Material &mat = model.materials[primitive.material];
|
||||||
for (auto &mats : mat.values)
|
for (auto &mats : mat.values) {
|
||||||
{
|
|
||||||
std::cout << "mat : " << mats.first.c_str() << std::endl;
|
std::cout << "mat : " << mats.first.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &image : model.images)
|
for (auto &image : model.images) {
|
||||||
{
|
|
||||||
std::cout << "image name : " << image.uri << std::endl;
|
std::cout << "image name : " << image.uri << std::endl;
|
||||||
std::cout << " size : " << image.image.size() << std::endl;
|
std::cout << " size : " << image.image.size() << std::endl;
|
||||||
std::cout << " w/h : " << image.width << "/" << image.height << std::endl;
|
std::cout << " w/h : " << image.width << "/" << image.height
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "indices : " << primitive.indices << std::endl;
|
std::cout << "indices : " << primitive.indices << std::endl;
|
||||||
std::cout << "mode : " << "(" << primitive.mode << ")" << std::endl;
|
std::cout << "mode : "
|
||||||
|
<< "(" << primitive.mode << ")" << std::endl;
|
||||||
|
|
||||||
for (auto &attrib : primitive.attributes)
|
for (auto &attrib : primitive.attributes) {
|
||||||
{
|
|
||||||
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
|
std::cout << "attribute : " << attrib.first.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat) {
|
||||||
glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat)
|
|
||||||
{
|
|
||||||
// Camera matrix
|
// Camera matrix
|
||||||
glm::mat4 view = glm::lookAt(
|
glm::mat4 view = glm::lookAt(
|
||||||
pos, // Camera in World Space
|
pos, // Camera in World Space
|
||||||
@ -242,21 +220,21 @@ glm::mat4 genView(glm::vec3 pos, glm::vec3 lookat)
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w, int h)
|
glm::mat4 genMVP(glm::mat4 view_mat, glm::mat4 model_mat, float fov, int w,
|
||||||
{
|
int h) {
|
||||||
glm::mat4 Projection = glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
|
glm::mat4 Projection =
|
||||||
|
glm::perspective(glm::radians(fov), (float)w / (float)h, 0.01f, 1000.0f);
|
||||||
|
|
||||||
// Or, for an ortho camera :
|
// Or, for an ortho camera :
|
||||||
//glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f); // In world coordinates
|
// glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f);
|
||||||
|
// // In world coordinates
|
||||||
|
|
||||||
glm::mat4 mvp = Projection * view_mat * model_mat;
|
glm::mat4 mvp = Projection * view_mat * model_mat;
|
||||||
|
|
||||||
return mvp;
|
return mvp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayLoop(Window& window, const std::string &filename)
|
void displayLoop(Window &window, const std::string &filename) {
|
||||||
{
|
|
||||||
Shaders shader = Shaders();
|
Shaders shader = Shaders();
|
||||||
glUseProgram(shader.pid);
|
glUseProgram(shader.pid);
|
||||||
|
|
||||||
@ -282,16 +260,16 @@ void displayLoop(Window& window, const std::string &filename)
|
|||||||
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
|
glm::vec3 sun_position = glm::vec3(3.0, 10.0, -5.0);
|
||||||
glm::vec3 sun_color = glm::vec3(1.0);
|
glm::vec3 sun_color = glm::vec3(1.0);
|
||||||
|
|
||||||
while (!window.Close())
|
while (!window.Close()) {
|
||||||
{
|
|
||||||
window.Resize();
|
window.Resize();
|
||||||
|
|
||||||
glClearColor(0.2, 0.2, 0.2, 1.0);
|
glClearColor(0.2, 0.2, 0.2, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glm::mat4 trans =
|
||||||
glm::mat4 trans = glm::translate(glm::mat4(1.0f), model_pos); // reposition model
|
glm::translate(glm::mat4(1.0f), model_pos); // reposition model
|
||||||
model_rot = glm::rotate(model_rot, glm::radians(0.8f), glm::vec3(0,1,0)); // rotate model on y axis
|
model_rot = glm::rotate(model_rot, glm::radians(0.8f),
|
||||||
|
glm::vec3(0, 1, 0)); // rotate model on y axis
|
||||||
model_mat = trans * model_rot;
|
model_mat = trans * model_rot;
|
||||||
|
|
||||||
// build a model-view-projection
|
// build a model-view-projection
|
||||||
@ -309,9 +287,7 @@ void displayLoop(Window& window, const std::string &filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
std::string filename = "../../models/Cube/Cube.gltf";
|
std::string filename = "../../models/Cube/Cube.gltf";
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@ -319,11 +295,31 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!glfwInit()) return -1;
|
if (!glfwInit()) return -1;
|
||||||
|
|
||||||
|
// Force create 3.3 profile.
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
Window window = Window(800, 600, "TinyGLTF basic example");
|
Window window = Window(800, 600, "TinyGLTF basic example");
|
||||||
glfwMakeContextCurrent(window.window);
|
glfwMakeContextCurrent(window.window);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// https://stackoverflow.com/questions/50192625/openggl-segmentation-fault
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
glewInit();
|
glewInit();
|
||||||
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION) << std::endl;
|
std::cout << glGetString(GL_RENDERER) << ", " << glGetString(GL_VERSION)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (!GLEW_VERSION_3_3) {
|
||||||
|
std::cerr << "OpenGL 3.3 is required to execute this app." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
@ -30,7 +30,7 @@ solution "basic_viewer"
|
|||||||
includedirs { "/usr/local/include" }
|
includedirs { "/usr/local/include" }
|
||||||
buildoptions { "-Wno-deprecated-declarations" }
|
buildoptions { "-Wno-deprecated-declarations" }
|
||||||
libdirs { "/usr/local/lib" }
|
libdirs { "/usr/local/lib" }
|
||||||
links { "glfw3", "GLEW" }
|
links { "glfw", "GLEW" }
|
||||||
linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" }
|
linkoptions { "-framework OpenGL", "-framework Cocoa", "-framework IOKit", "-framework CoreVideo" }
|
||||||
|
|
||||||
configuration "Debug"
|
configuration "Debug"
|
||||||
|
@ -19,7 +19,7 @@ uniform vec3 sun_color; \n\
|
|||||||
out vec4 color;\n\
|
out vec4 color;\n\
|
||||||
void main() {\n\
|
void main() {\n\
|
||||||
float lum = max(dot(normal, normalize(sun_position)), 0.0);\n\
|
float lum = max(dot(normal, normalize(sun_position)), 0.0);\n\
|
||||||
color = texture2D(tex, texcoord) * vec4((0.3 + 0.7 * lum) * sun_color, 1.0);\n\
|
color = texture(tex, texcoord) * vec4((0.3 + 0.7 * lum) * sun_color, 1.0);\n\
|
||||||
}\n\
|
}\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user