v0.8.1.0 Release

v0.8.1.0 Release
This commit is contained in:
jdsouza90
2022-09-20 09:59:34 -07:00
parent 3bd2be62a4
commit cf68600c4f
691 changed files with 181019 additions and 22147 deletions

View File

@@ -0,0 +1,632 @@
/*###############################################################################
#
# Copyright 2016-2021 NVIDIA Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
###############################################################################*/
#ifdef _MSC_VER
#include "glad/glad.h"
#else
#include <GLES3/gl3.h>
#endif // _MSC_VER
#include <string>
#include <stdint.h>
#include "GLShaders.h"
enum {
myErrNone = 0,
myErrShader = -1,
myErrProgram = -2,
myErrTexture = -3,
};
#define BAIL_IF_ERR(err) do { if ((err)) { goto bail; } } while(0)
#define _STRINGIFY_(token) #token
#define STRINGIFY(token) _STRINGIFY_(token)
#define MAYBE_UNUSED(token) if (token){}
/****************************************************************************//**
* Print Shader Log.
* \param[in] id the ID of the shader.
* \param[in] type either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
* \param[in] shader the shader source code.
********************************************************************************/
static void PrintShaderLog(GLuint id, GLenum type, const char *shader) {
GLsizei msgLength;
std::string errMsg;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &msgLength);
errMsg.resize(msgLength);
glGetShaderInfoLog(id, msgLength, &msgLength, &errMsg[0]);
fprintf(stderr, "\nShader Log:\n%sfor %s Shader:\n%s\n", errMsg.c_str(),
((type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment"), shader);
}
/****************************************************************************//**
* Print Program Log.
* \param[in] id the id of the program.
********************************************************************************/
static void PrintProgramLog(GLuint id) {
GLsizei msgLength;
std::string errMsg;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &msgLength);
errMsg.resize(msgLength);
glGetProgramInfoLog(id, msgLength, &msgLength, &errMsg[0]);
fprintf(stderr, "\nProgram Log:\n%s\n", errMsg.c_str());
}
/****************************************************************************//**
* NewShader
********************************************************************************/
static int NewShader(const char *shaderStr, GLenum type, GLuint *shaderID) {
GLuint id;
GLint result;
*shaderID = 0;
id = glCreateShader(type);
glShaderSource(id, 1, &shaderStr, NULL);
glCompileShader(id);
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result) {
*shaderID = id;
return myErrNone;
}
else {
PrintShaderLog(id, type, shaderStr);
glDeleteShader(id);
return myErrShader;
}
}
/****************************************************************************//**
* NewProgram
********************************************************************************/
static int NewProgram(GLuint vertexShader, GLuint fragmentShader, GLuint *progID) {
GLint result;
GLuint id;
*progID = 0;
id = glCreateProgram();
glAttachShader(id, vertexShader);
glAttachShader(id, fragmentShader);
glLinkProgram(id);
glGetProgramiv(id, GL_LINK_STATUS, &result);
if (result) {
*progID = id;
return myErrNone;
}
else {
PrintProgramLog(id);
glDeleteProgram(id);
return myErrProgram;
}
}
/****************************************************************************//**
* IndexTypeFromSize
********************************************************************************/
static GLenum IndexTypeFromSize(unsigned indexSize) {
return (indexSize < 2) ? GL_UNSIGNED_BYTE
: (indexSize == 2) ? GL_UNSIGNED_SHORT
: GL_UNSIGNED_INT;
}
/********************************************************************************
********************************************************************************
***** SMOOTH RENDERER *****
********************************************************************************
********************************************************************************/
/********************************************************************************
* Shaders
********************************************************************************/
const char SmoothRenderer::_vertexShader[] =
"uniform mat4 MVP;\n"
"attribute vec3 vCol;\n"
"attribute vec3 vPos;\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(vPos, 1.0);\n"
" color = vCol;\n"
"}\n";
const char SmoothRenderer::_fragmentShader[] =
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(color, 1.0);\n"
"}\n";
/********************************************************************************
* startup
********************************************************************************/
int SmoothRenderer::startup() {
int err = myErrNone;
GLuint vertexShader = 0, fragmentShader = 0;
_programID = 0;
BAIL_IF_ERR(err = NewShader(_vertexShader, GL_VERTEX_SHADER, &vertexShader));
BAIL_IF_ERR(err = NewShader(_fragmentShader, GL_FRAGMENT_SHADER, &fragmentShader));
BAIL_IF_ERR(err = NewProgram(vertexShader, fragmentShader, &_programID));
_maxtrixID = glGetUniformLocation(_programID, "MVP");
_vtxPosID = glGetAttribLocation(_programID, "vPos");
_vtxColID = glGetAttribLocation(_programID, "vCol");
err = (-1 == _maxtrixID || -1 == _vtxPosID || -1 == _vtxColID) ? myErrShader : myErrNone;
bail:
if (myErrNone != err) shutdown();
if (fragmentShader) glDeleteShader(fragmentShader);
if (vertexShader) glDeleteShader(vertexShader);
return err;
}
/********************************************************************************
* use
********************************************************************************/
int SmoothRenderer::use() {
if (0 == _programID)
return myErrProgram;
glUseProgram(_programID);
return myErrNone;
}
/********************************************************************************
* drawElements, from user memory
********************************************************************************/
void SmoothRenderer::drawElements(GLsizei numVertices, const GLfloat *positions, const GLfloat *colors,
GLenum graphicsMode, GLsizei indexCount, GLenum indexType, const GLvoid *indices, const GLfloat *M
) {
MAYBE_UNUSED(numVertices);
glUseProgram(_programID);
if (M)
glUniformMatrix4fv(_maxtrixID, 1, GL_FALSE, M);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (colors) { /* Separate array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(*positions), positions);
glEnableVertexAttribArray(_vtxColID);
glVertexAttribPointer(_vtxColID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(*colors), colors);
}
else { /* One contiguous array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(*positions), positions);
glEnableVertexAttribArray(_vtxColID);
glVertexAttribPointer(_vtxColID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(*positions), positions + 3);
}
glDrawElements(graphicsMode, indexCount, indexType, indices);
}
/********************************************************************************
* drawElements, from buffer objects
********************************************************************************/
void SmoothRenderer::drawElements(GLuint vtxBuf, unsigned posOff, unsigned colOff,
GLenum graphicsMode, GLsizei numIndices, unsigned indexSize, GLuint topoBuf, const GLfloat *M
) {
GLenum err;
glUseProgram(_programID);
if (M)
glUniformMatrix4fv(_maxtrixID, 1, GL_FALSE, M);
glBindBuffer(GL_ARRAY_BUFFER, vtxBuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, topoBuf);
if (!(colOff == 12 || colOff == 0)) { /* Separate array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(intptr_t)posOff);
glEnableVertexAttribArray(_vtxColID);
glVertexAttribPointer(_vtxColID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(intptr_t)colOff);
}
else { /* One contiguous array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(intptr_t)(posOff + 0 * sizeof(float)));
glEnableVertexAttribArray(_vtxColID);
glVertexAttribPointer(_vtxColID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(intptr_t)(posOff + 3 * sizeof(float)));
err = glGetError(); if (err) printf("glVertexAttribPointer returns %d\n", err);
}
glDrawElements(graphicsMode, numIndices, IndexTypeFromSize(indexSize), (void*)0);
}
/********************************************************************************
********************************************************************************
***** TEXTURE RENDERER *****
********************************************************************************
********************************************************************************/
/********************************************************************************
* shaders
********************************************************************************/
const char TextureRenderer::_vertexShader[] =
"uniform mat4 MVP;\n" // Model, view, projection matrices, concatenated.
"attribute vec3 vPos;\n" // Vertex position
"attribute vec2 vTex;\n" // Vertex texture coordinate
"varying vec2 texCoord;\n" // Interpolated texture coordinate
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(vPos, 1.0);\n"
" texCoord = vTex;\n"
"}\n";
const char TextureRenderer::_fragmentShader[] =
"uniform sampler2D tex;\n"
"varying vec2 texCoord;\n" // Interpolated texture coordinate
"void main()\n"
"{\n"
" gl_FragColor = texture2D(tex, texCoord);\n"
"}\n";
/********************************************************************************
* startup
********************************************************************************/
int TextureRenderer::startup() {
int err = myErrNone;
GLuint vertexShader = 0, fragmentShader = 0;
if (_programID)
return myErrNone;
_programID = 0;
BAIL_IF_ERR(err = NewShader(_vertexShader, GL_VERTEX_SHADER, &vertexShader));
BAIL_IF_ERR(err = NewShader(_fragmentShader, GL_FRAGMENT_SHADER, &fragmentShader));
BAIL_IF_ERR(err = NewProgram(vertexShader, fragmentShader, &_programID));
_maxtrixID = _vtxPosID = _vtxTexID = -1;
_maxtrixID = glGetUniformLocation(_programID, "MVP");
_vtxPosID = glGetAttribLocation(_programID, "vPos");
_vtxTexID = glGetAttribLocation(_programID, "vTex");
err = (-1 == _maxtrixID || -1 == _vtxPosID || -1 == _vtxTexID) ? myErrShader : myErrNone;
bail:
if (myErrNone != err) shutdown();
if (fragmentShader) glDeleteShader(fragmentShader);
if (vertexShader) glDeleteShader(vertexShader);
return err;
}
/********************************************************************************
* use
********************************************************************************/
int TextureRenderer::use() {
if (0 == _programID)
return myErrProgram;
glUseProgram(_programID);
return myErrNone;
}
/********************************************************************************
* drawElements, from user buffers
********************************************************************************/
void TextureRenderer::drawElements(GLsizei numVertices, const GLfloat *xyz, const GLfloat *uv,
GLenum graphicsMode, GLsizei indexCount, GLenum indexType, const GLvoid *indices, GLuint texID ,const GLfloat *M
) {
MAYBE_UNUSED(numVertices);
glUseProgram(_programID);
if (M)
glUniformMatrix4fv(_maxtrixID, 1, GL_FALSE, M);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texID);
if (uv) { /* Separate array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(*xyz), xyz);
glEnableVertexAttribArray(_vtxTexID);
glVertexAttribPointer(_vtxTexID, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(*uv), uv);
}
else { /* One contiguous array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(*xyz), xyz);
glEnableVertexAttribArray(_vtxTexID);
glVertexAttribPointer(_vtxTexID, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(*xyz), xyz + 3);
}
glDrawElements(graphicsMode, indexCount, indexType, indices);
}
/********************************************************************************
* drawElements, from buffer objects
********************************************************************************/
void TextureRenderer::drawElements(
GLuint vtxBuf, unsigned xyzOff, unsigned uvOff, GLenum graphicsMode,
GLsizei numIndices, GLenum indexSize, GLuint indexBuf, GLuint texID, const GLfloat *M
) {
GLenum err;
glUseProgram(_programID);
if (M)
glUniformMatrix4fv(_maxtrixID, 1, GL_FALSE, M);
glBindBuffer(GL_ARRAY_BUFFER, vtxBuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
glBindTexture(GL_TEXTURE_2D, texID);
if (!(uvOff == 12 || uvOff == 0)) { /* Separate array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(intptr_t)xyzOff);
glEnableVertexAttribArray(_vtxTexID);
glVertexAttribPointer(_vtxTexID, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)(intptr_t)uvOff);
}
else { /* One contiguous array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(intptr_t)(xyzOff + 0 * sizeof(float)));
glEnableVertexAttribArray(_vtxTexID);
glVertexAttribPointer(_vtxTexID, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(intptr_t)(xyzOff + 3 * sizeof(float)));
err = glGetError(); if (err) printf("glVertexAttribPointer returns %d\n", err);
}
glDrawElements(graphicsMode, numIndices, IndexTypeFromSize(indexSize), (void*)0);
}
/********************************************************************************
* drawQuad, from user buffers
********************************************************************************/
void TextureRenderer::drawQuad(const float xyz[4*3], const float uv[4*2], GLuint texID, const float *M) {
static const unsigned char indices[4] = { 0, 1, 2, 3 }; // These need to be static, because GL is asynchronous
drawElements(4, xyz, uv, GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, indices, texID, M);
}
/********************************************************************************
* Mesh shader
********************************************************************************/
class MeshShader {
static const char _vertexShader[], _fragmentShader[];
};
// The ambient and diffuse coefficients are rolled into the ambCol and litCol, respectively.
const char MeshShader::_vertexShader[] =
"uniform mat4 MVP;\n" // Model, view, projection matrices, concatenated.
"uniform mat3 N;\n" // Normal matrix.
"uniform vec3 litDir;\n" // Light direction
"uniform vec3 litCol;\n" // Light color multiplied by the diffuse coefficient
"uniform vec3 ambCol;\n" // Ambient color multiplied by the ambient coefficient
"attribute vec3 vtxPos;\n" // Vertex position
"attribute vec3 vtxNor;\n" // Vertex normal
"attribute vec2 vtxTex;\n" // Vertex texture coordinate
"varying vec2 texCoord;\n" // Interpolated texture coordinate
"varying vec3 illum;\n" // Interpolated illumination
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(vtxPos, 1.0);\n"
" texCoord = vtxTex;\n"
" illum = max(dot(N * vtxNor, litDir) * litCol + ambCol;\n"
"}\n";
/********************************************************************************
* UpdateTexture
********************************************************************************/
GLenum UpdateTexture(GLint texID, GLsizei width, GLsizei height, GLsizei rowBytes, GLenum glFormat, const GLvoid *pixels) {
glBindTexture(GL_TEXTURE_2D, texID);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowBytes / 4);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, glFormat, GL_UNSIGNED_BYTE, pixels);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // restore to default
return glGetError();
}
/********************************************************************************
********************************************************************************
***** LAMBERTIAN RENDERER *****
********************************************************************************
********************************************************************************/
/********************************************************************************
* Shaders
********************************************************************************/
const char LambertianRenderer::_vertexShader[] =
"#version 120\n"
"uniform mat4 M;\n"
"uniform mat4 VP;\n"
"uniform vec4 lightLoc[" STRINGIFY(LAMBERTIAN_NUM_LIGHTS) "];\n"
"uniform vec3 lightColor[" STRINGIFY(LAMBERTIAN_NUM_LIGHTS) "];\n"
"uniform vec3 Ka;\n"
"uniform vec3 Kd;\n"
"attribute vec3 vPos;\n"
"attribute vec3 vNrm;\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
" vec4 loc = M * vec4(vPos, 1.);\n" // Transform points into world space ...
" gl_Position = VP * loc;\n" // ... and screen space
" vec3 N = normalize(mat3(M) * vNrm);\n" // Transform normal into world space, assuming isotropic scaling
" color = Ka;\n" // Initialize color to ambient
" for (int i = 0; i < " STRINGIFY(LAMBERTIAN_NUM_LIGHTS) "; ++i)\n"
" {\n"
" vec3 L = normalize(lightLoc[i].xyz - lightLoc[i].w * loc.xyz);\n" // Compute vector to light: w must be either 1 or 0
" float d = dot(L, N);\n" // Lambertian lighting
" if (d > 0.)\n" // If the light hits the outside surface, ...
" color += d * lightColor[i] * Kd;\n" // ... accumulate color from the light source
" }\n"
"}\n";
const char LambertianRenderer::_fragmentShader[] =
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(color, 1.);\n" // Interpolate the color
"}\n";
/********************************************************************************
* startup
********************************************************************************/
int LambertianRenderer::startup() {
int err = myErrNone;
GLuint vertexShader = 0, fragmentShader = 0;
_programID = 0;
BAIL_IF_ERR(err = NewShader(_vertexShader, GL_VERTEX_SHADER, &vertexShader));
BAIL_IF_ERR(err = NewShader(_fragmentShader, GL_FRAGMENT_SHADER, &fragmentShader));
BAIL_IF_ERR(err = NewProgram(vertexShader, fragmentShader, &_programID));
_lightLoc = glGetUniformLocation(_programID, "lightLoc"); // light locations
_lightColor = glGetUniformLocation(_programID, "lightColor"); // light diffuse colors
_MmatrixID = glGetUniformLocation(_programID, "M"); // M matrix; require UL 3x3 to be orthogonal
_VPmatrixID = glGetUniformLocation(_programID, "VP"); // VP matrix
_ambientColorID = glGetUniformLocation(_programID, "Ka"); // ambient color
_diffuseColorID = glGetUniformLocation(_programID, "Kd"); // diffuse color
_vtxPosID = glGetAttribLocation(_programID, "vPos"); // vertex positions
_vtxNrmID = glGetAttribLocation(_programID, "vNrm"); // vertex normals
err = (-1 == _lightLoc || -1 == _lightColor || -1 == _MmatrixID || -1 == _VPmatrixID || -1 == _ambientColorID
|| -1 == _diffuseColorID || -1 == _vtxPosID || -1 == _vtxNrmID) ? myErrShader : myErrNone;
BAIL_IF_ERR(err);
bail:
if (myErrNone != err) shutdown();
if (fragmentShader) glDeleteShader(fragmentShader);
if (vertexShader) glDeleteShader(vertexShader);
return err;
}
/********************************************************************************
* use
********************************************************************************/
int LambertianRenderer::use() {
if (0 == _programID)
return myErrProgram;
glUseProgram(_programID);
return myErrNone;
}
/********************************************************************************
* set lights
********************************************************************************/
void LambertianRenderer::setLights(const float locXYZW[4*LAMBERTIAN_NUM_LIGHTS], const float colorRGB[3*LAMBERTIAN_NUM_LIGHTS]) {
glUseProgram(_programID);
glUniform4fv(_lightLoc, LAMBERTIAN_NUM_LIGHTS, locXYZW);
glUniform3fv(_lightColor, LAMBERTIAN_NUM_LIGHTS, colorRGB);
}
/********************************************************************************
* drawElements, from user memory
********************************************************************************/
void LambertianRenderer::drawElements(GLsizei numVertices, const GLfloat *positions, const GLfloat *normals,
GLenum graphicsMode, GLsizei indexCount, GLenum indexType, const GLvoid *indices,
const GLfloat M[4*4], const GLfloat VP[4*4], const float Ka[3], const float Kd[3]
) {
MAYBE_UNUSED(numVertices);
glUseProgram(_programID);
if (M) glUniformMatrix4fv(_MmatrixID, 1, GL_FALSE, M);
if (VP) glUniformMatrix4fv(_VPmatrixID, 1, GL_FALSE, VP);
if (Ka) glUniform3fv(_ambientColorID, 1, Ka);
if (Kd) glUniform3fv(_diffuseColorID, 1, Kd);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (normals) { /* Separate array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(*positions), positions);
glEnableVertexAttribArray(_vtxNrmID);
glVertexAttribPointer(_vtxNrmID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(*normals), normals);
}
else { /* One contiguous array for position and color */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(*positions), positions);
glEnableVertexAttribArray(_vtxNrmID);
glVertexAttribPointer(_vtxNrmID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(*normals), normals + 3);
}
glDrawElements(graphicsMode, indexCount, indexType, indices);
}
/********************************************************************************
* drawElements, from buffer objects
********************************************************************************/
void LambertianRenderer::drawElements(GLuint vtxBuf, unsigned posOff, unsigned nrmOff,
GLenum graphicsMode, GLsizei numIndices, unsigned indexSize, GLuint indexBuf,
const GLfloat M[4*4], const GLfloat VP[4*4], const float Ka[3], const float Kd[3]
) {
GLenum err;
glUseProgram(_programID);
if (M) glUniformMatrix4fv(_MmatrixID, 1, GL_FALSE, M);
if (VP) glUniformMatrix4fv(_VPmatrixID, 1, GL_FALSE, VP);
if (Ka) glUniform3fv(_ambientColorID, 1, Ka);
if (Kd) glUniform3fv(_diffuseColorID, 1, Kd);
glBindBuffer(GL_ARRAY_BUFFER, vtxBuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
if (!(nrmOff == 12 || nrmOff == 0)) { /* Separate array for position and normal */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(intptr_t)posOff);
glEnableVertexAttribArray(_vtxNrmID);
glVertexAttribPointer(_vtxNrmID, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(intptr_t)nrmOff);
}
else { /* One contiguous array for position and normal */
glEnableVertexAttribArray(_vtxPosID);
glVertexAttribPointer(_vtxPosID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(intptr_t)(posOff + 0 * sizeof(float)));
glEnableVertexAttribArray(_vtxNrmID);
glVertexAttribPointer(_vtxNrmID, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(intptr_t)(posOff + 3 * sizeof(float)));
err = glGetError(); if (err) printf("glVertexAttribPointer returns %d\n", err);
}
glDrawElements(graphicsMode, numIndices, IndexTypeFromSize(indexSize), (void*)0);
}