glmdraw.c revision 32001f49
132001f49Smrg/* */ 232001f49Smrg 332001f49Smrg#define GL_GLEXT_PROTOTYPES 432001f49Smrg 532001f49Smrg#include <assert.h> 632001f49Smrg#include <stdio.h> 732001f49Smrg#include <stdlib.h> 832001f49Smrg#include <string.h> 932001f49Smrg#include <GL/glew.h> 1032001f49Smrg#include "glm.h" 1132001f49Smrg#include "readtex.h" 1232001f49Smrg#include "shaderutil.h" 1332001f49Smrg 1432001f49Smrg 1532001f49Smrg/* defines */ 1632001f49Smrg#define T(x) model->triangles[(x)] 1732001f49Smrg 1832001f49Smrg 1932001f49Smrg/* glmDraw: Renders the model to the current OpenGL context using the 2032001f49Smrg * mode specified. 2132001f49Smrg * 2232001f49Smrg * model - initialized GLMmodel structure 2332001f49Smrg * mode - a bitwise OR of values describing what is to be rendered. 2432001f49Smrg * GLM_NONE - render with only vertices 2532001f49Smrg * GLM_FLAT - render with facet normals 2632001f49Smrg * GLM_SMOOTH - render with vertex normals 2732001f49Smrg * GLM_TEXTURE - render with texture coords 2832001f49Smrg * GLM_COLOR - render with colors (color material) 2932001f49Smrg * GLM_MATERIAL - render with materials 3032001f49Smrg * GLM_COLOR and GLM_MATERIAL should not both be specified. 3132001f49Smrg * GLM_FLAT and GLM_SMOOTH should not both be specified. 3232001f49Smrg */ 3332001f49SmrgGLvoid 3432001f49SmrgglmDraw(GLMmodel* model, GLuint mode) 3532001f49Smrg{ 3632001f49Smrg GLuint i; 3732001f49Smrg GLMgroup* group; 3832001f49Smrg 3932001f49Smrg assert(model); 4032001f49Smrg assert(model->vertices); 4132001f49Smrg 4232001f49Smrg /* do a bit of warning */ 4332001f49Smrg if (mode & GLM_FLAT && !model->facetnorms) { 4432001f49Smrg printf("glmDraw() warning: flat render mode requested " 4532001f49Smrg "with no facet normals defined.\n"); 4632001f49Smrg mode &= ~GLM_FLAT; 4732001f49Smrg } 4832001f49Smrg if (mode & GLM_SMOOTH && !model->normals) { 4932001f49Smrg printf("glmDraw() warning: smooth render mode requested " 5032001f49Smrg "with no normals defined.\n"); 5132001f49Smrg mode &= ~GLM_SMOOTH; 5232001f49Smrg } 5332001f49Smrg if (mode & GLM_TEXTURE && !model->texcoords) { 5432001f49Smrg printf("glmDraw() warning: texture render mode requested " 5532001f49Smrg "with no texture coordinates defined.\n"); 5632001f49Smrg mode &= ~GLM_TEXTURE; 5732001f49Smrg } 5832001f49Smrg if (mode & GLM_FLAT && mode & GLM_SMOOTH) { 5932001f49Smrg printf("glmDraw() warning: flat render mode requested " 6032001f49Smrg "and smooth render mode requested (using smooth).\n"); 6132001f49Smrg mode &= ~GLM_FLAT; 6232001f49Smrg } 6332001f49Smrg if (mode & GLM_COLOR && !model->materials) { 6432001f49Smrg printf("glmDraw() warning: color render mode requested " 6532001f49Smrg "with no materials defined.\n"); 6632001f49Smrg mode &= ~GLM_COLOR; 6732001f49Smrg } 6832001f49Smrg if (mode & GLM_MATERIAL && !model->materials) { 6932001f49Smrg printf("glmDraw() warning: material render mode requested " 7032001f49Smrg "with no materials defined.\n"); 7132001f49Smrg mode &= ~GLM_MATERIAL; 7232001f49Smrg } 7332001f49Smrg if (mode & GLM_COLOR && mode & GLM_MATERIAL) { 7432001f49Smrg printf("glmDraw() warning: color and material render mode requested " 7532001f49Smrg "using only material mode\n"); 7632001f49Smrg mode &= ~GLM_COLOR; 7732001f49Smrg } 7832001f49Smrg if (mode & GLM_COLOR) 7932001f49Smrg glEnable(GL_COLOR_MATERIAL); 8032001f49Smrg if (mode & GLM_MATERIAL) 8132001f49Smrg glDisable(GL_COLOR_MATERIAL); 8232001f49Smrg 8332001f49Smrg glPushMatrix(); 8432001f49Smrg glTranslatef(model->position[0], model->position[1], model->position[2]); 8532001f49Smrg 8632001f49Smrg glBegin(GL_TRIANGLES); 8732001f49Smrg group = model->groups; 8832001f49Smrg while (group) { 8932001f49Smrg if (mode & GLM_MATERIAL) { 9032001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, 9132001f49Smrg model->materials[group->material].ambient); 9232001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 9332001f49Smrg model->materials[group->material].diffuse); 9432001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, 9532001f49Smrg model->materials[group->material].specular); 9632001f49Smrg glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9732001f49Smrg model->materials[group->material].shininess); 9832001f49Smrg } 9932001f49Smrg 10032001f49Smrg if (mode & GLM_COLOR) { 10132001f49Smrg glColor3fv(model->materials[group->material].diffuse); 10232001f49Smrg } 10332001f49Smrg 10432001f49Smrg for (i = 0; i < group->numtriangles; i++) { 10532001f49Smrg if (mode & GLM_FLAT) 10632001f49Smrg glNormal3fv(&model->facetnorms[3 * T(group->triangles[i]).findex]); 10732001f49Smrg 10832001f49Smrg if (mode & GLM_SMOOTH) 10932001f49Smrg glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[0]]); 11032001f49Smrg if (mode & GLM_TEXTURE) 11132001f49Smrg glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[0]]); 11232001f49Smrg glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[0]]); 11332001f49Smrg#if 0 11432001f49Smrg printf("%f %f %f\n", 11532001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[0] + X], 11632001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[0] + Y], 11732001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[0] + Z]); 11832001f49Smrg#endif 11932001f49Smrg 12032001f49Smrg if (mode & GLM_SMOOTH) 12132001f49Smrg glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[1]]); 12232001f49Smrg if (mode & GLM_TEXTURE) 12332001f49Smrg glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[1]]); 12432001f49Smrg glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[1]]); 12532001f49Smrg#if 0 12632001f49Smrg printf("%f %f %f\n", 12732001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[1] + X], 12832001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[1] + Y], 12932001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[1] + Z]); 13032001f49Smrg#endif 13132001f49Smrg 13232001f49Smrg if (mode & GLM_SMOOTH) 13332001f49Smrg glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[2]]); 13432001f49Smrg if (mode & GLM_TEXTURE) 13532001f49Smrg glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[2]]); 13632001f49Smrg glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[2]]); 13732001f49Smrg#if 0 13832001f49Smrg printf("%f %f %f\n", 13932001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[2] + X], 14032001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[2] + Y], 14132001f49Smrg model->vertices[3 * T(group->triangles[i]).vindices[2] + Z]); 14232001f49Smrg#endif 14332001f49Smrg 14432001f49Smrg } 14532001f49Smrg 14632001f49Smrg group = group->next; 14732001f49Smrg } 14832001f49Smrg glEnd(); 14932001f49Smrg 15032001f49Smrg glPopMatrix(); 15132001f49Smrg} 15232001f49Smrg 15332001f49Smrg 15432001f49Smrgvoid 15532001f49SmrgglmMakeVBOs(GLMmodel *model) 15632001f49Smrg{ 15732001f49Smrg uint bytes, vertexFloats, i; 15832001f49Smrg float *buffer; 15932001f49Smrg GLMgroup* group; 16032001f49Smrg unsigned totalIndexes; 16132001f49Smrg GLubyte *ibuffer, *ib; 16232001f49Smrg 16332001f49Smrg /* 16432001f49Smrg * Vertex data 16532001f49Smrg */ 16632001f49Smrg vertexFloats = 3; 16732001f49Smrg model->posOffset = 0; 16832001f49Smrg 16932001f49Smrg if (model->numnormals > 0) { 17032001f49Smrg assert(model->numnormals == model->numvertices); 17132001f49Smrg model->normOffset = vertexFloats * sizeof(GLfloat); 17232001f49Smrg vertexFloats += 3; 17332001f49Smrg } 17432001f49Smrg 17532001f49Smrg if (model->numtexcoords > 0) { 17632001f49Smrg assert(model->numtexcoords == model->numvertices); 17732001f49Smrg model->texOffset = vertexFloats * sizeof(GLfloat); 17832001f49Smrg vertexFloats += 2; 17932001f49Smrg } 18032001f49Smrg 18132001f49Smrg model->vertexSize = vertexFloats; 18232001f49Smrg 18332001f49Smrg bytes = (model->numvertices + 1) * vertexFloats * sizeof(float); 18432001f49Smrg 18532001f49Smrg buffer = (float *) malloc(bytes); 18632001f49Smrg for (i = 0; i < model->numvertices; i++) { 18732001f49Smrg /* copy vertex pos */ 18832001f49Smrg uint j = 0; 18932001f49Smrg buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 0]; 19032001f49Smrg buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 1]; 19132001f49Smrg buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 2]; 19232001f49Smrg if (model->numnormals > 0) { 19332001f49Smrg buffer[i * vertexFloats + j++] = model->normals[i * 3 + 0]; 19432001f49Smrg buffer[i * vertexFloats + j++] = model->normals[i * 3 + 1]; 19532001f49Smrg buffer[i * vertexFloats + j++] = model->normals[i * 3 + 2]; 19632001f49Smrg } 19732001f49Smrg if (model->numtexcoords > 0) { 19832001f49Smrg buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 0]; 19932001f49Smrg buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 1]; 20032001f49Smrg } 20132001f49Smrg } 20232001f49Smrg 20332001f49Smrg glGenBuffersARB(1, &model->vbo); 20432001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo); 20532001f49Smrg glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, buffer, GL_STATIC_DRAW_ARB); 20632001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 20732001f49Smrg 20832001f49Smrg free(buffer); 20932001f49Smrg 21032001f49Smrg /* 21132001f49Smrg * Index data 21232001f49Smrg */ 21332001f49Smrg totalIndexes = 0; 21432001f49Smrg for (group = model->groups; group; group = group->next) { 21532001f49Smrg if (group->numtriangles > 0) { 21632001f49Smrg totalIndexes += 3 * group->numtriangles; 21732001f49Smrg } 21832001f49Smrg } 21932001f49Smrg 22032001f49Smrg glGenBuffersARB(1, &model->index_vbo); 22132001f49Smrg glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, model->index_vbo); 22232001f49Smrg glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, totalIndexes * sizeof(GLuint), 22332001f49Smrg NULL, GL_STATIC_DRAW_ARB); 22432001f49Smrg ibuffer = (GLubyte *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 22532001f49Smrg GL_WRITE_ONLY); 22632001f49Smrg ib = ibuffer; 22732001f49Smrg 22832001f49Smrg for (group = model->groups; group; group = group->next) { 22932001f49Smrg if (group->numtriangles > 0) { 23032001f49Smrg int bytes = 3 * group->numtriangles * sizeof(uint); 23132001f49Smrg memcpy(ib, group->triIndexes, bytes); 23232001f49Smrg totalIndexes += 3 * group->numtriangles; 23332001f49Smrg group->indexVboOffset = ib - ibuffer; 23432001f49Smrg ib += bytes; 23532001f49Smrg } 23632001f49Smrg } 23732001f49Smrg 23832001f49Smrg glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); 23932001f49Smrg 24032001f49Smrg glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); 24132001f49Smrg} 24232001f49Smrg 24332001f49Smrg 24432001f49Smrgstatic void 24532001f49Smrg_glmLoadTexture(GLMmaterial *mat) 24632001f49Smrg{ 24732001f49Smrg if (mat->map_kd) { 24832001f49Smrg GLint imgWidth, imgHeight; 24932001f49Smrg GLenum imgFormat; 25032001f49Smrg GLubyte *image = NULL; 25132001f49Smrg 25232001f49Smrg glGenTextures(1, &mat->texture_kd); 25332001f49Smrg 25432001f49Smrg image = LoadRGBImage( mat->map_kd, &imgWidth, &imgHeight, &imgFormat ); 25532001f49Smrg if (!image) { 25632001f49Smrg /*fprintf(stderr, "Couldn't open texture %s\n", mat->map_kd);*/ 25732001f49Smrg free(mat->map_kd); 25832001f49Smrg mat->map_kd = NULL; 25932001f49Smrg mat->texture_kd = 0; 26032001f49Smrg return; 26132001f49Smrg } 26232001f49Smrg if (0) 26332001f49Smrg printf("load texture %s %d x %d\n", mat->map_kd, imgWidth, imgHeight); 26432001f49Smrg 26532001f49Smrg glBindTexture(GL_TEXTURE_2D, mat->texture_kd); 26632001f49Smrg gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight, 26732001f49Smrg imgFormat, GL_UNSIGNED_BYTE, image); 26832001f49Smrg free(image); 26932001f49Smrg 27032001f49Smrg glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); 27132001f49Smrg glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); 27232001f49Smrg glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); 27332001f49Smrg glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 27432001f49Smrg } 27532001f49Smrg} 27632001f49Smrg 27732001f49Smrgvoid 27832001f49SmrgglmLoadTextures(GLMmodel *model) 27932001f49Smrg{ 28032001f49Smrg uint i; 28132001f49Smrg 28232001f49Smrg for (i = 0; i < model->nummaterials; i++) { 28332001f49Smrg GLMmaterial *mat = &model->materials[i]; 28432001f49Smrg _glmLoadTexture(mat); 28532001f49Smrg } 28632001f49Smrg} 28732001f49Smrg 28832001f49Smrg 28932001f49Smrgvoid 29032001f49SmrgglmDrawVBO(GLMmodel *model) 29132001f49Smrg{ 29232001f49Smrg GLMgroup* group; 29332001f49Smrg uint prevMaterial = ~0; 29432001f49Smrg 29532001f49Smrg assert(model->vbo); 29632001f49Smrg 29732001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo); 29832001f49Smrg 29932001f49Smrg glVertexPointer(3, GL_FLOAT, model->vertexSize * sizeof(float), 30032001f49Smrg (const void *) (size_t) model->posOffset); 30132001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 30232001f49Smrg 30332001f49Smrg if (model->numnormals > 0) { 30432001f49Smrg glNormalPointer(GL_FLOAT, model->vertexSize * sizeof(float), 30532001f49Smrg (const void *) (size_t) model->normOffset); 30632001f49Smrg glEnableClientState(GL_NORMAL_ARRAY); 30732001f49Smrg } 30832001f49Smrg 30932001f49Smrg if (model->numtexcoords > 0) { 31032001f49Smrg glTexCoordPointer(2, GL_FLOAT, model->vertexSize * sizeof(float), 31132001f49Smrg (const void *) (size_t) model->texOffset); 31232001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 31332001f49Smrg } 31432001f49Smrg 31532001f49Smrg glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, model->index_vbo); 31632001f49Smrg 31732001f49Smrg glPushMatrix(); 31832001f49Smrg glTranslatef(model->position[0], model->position[1], model->position[2]); 31932001f49Smrg glScalef(model->scale, model->scale, model->scale); 32032001f49Smrg 32132001f49Smrg for (group = model->groups; group; group = group->next) { 32232001f49Smrg if (group->numtriangles > 0) { 32332001f49Smrg 32432001f49Smrg if (group->material != prevMaterial) { 32532001f49Smrg glmShaderMaterial(&model->materials[group->material]); 32632001f49Smrg prevMaterial = group->material; 32732001f49Smrg } 32832001f49Smrg 32932001f49Smrg glDrawRangeElements(GL_TRIANGLES, 33032001f49Smrg group->minIndex, group->maxIndex, 33132001f49Smrg 3 * group->numtriangles, 33232001f49Smrg GL_UNSIGNED_INT, 33332001f49Smrg (void *) (GLintptr) group->indexVboOffset); 33432001f49Smrg } 33532001f49Smrg } 33632001f49Smrg 33732001f49Smrg glPopMatrix(); 33832001f49Smrg 33932001f49Smrg glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 34032001f49Smrg glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); 34132001f49Smrg glDisableClientState(GL_VERTEX_ARRAY); 34232001f49Smrg glDisableClientState(GL_NORMAL_ARRAY); 34332001f49Smrg glDisableClientState(GL_TEXTURE_COORD_ARRAY); 34432001f49Smrg} 34532001f49Smrg 34632001f49Smrg 34732001f49Smrg 34832001f49Smrg/* glmList: Generates and returns a display list for the model using 34932001f49Smrg * the mode specified. 35032001f49Smrg * 35132001f49Smrg * model - initialized GLMmodel structure 35232001f49Smrg * mode - a bitwise OR of values describing what is to be rendered. 35332001f49Smrg * GLM_NONE - render with only vertices 35432001f49Smrg * GLM_FLAT - render with facet normals 35532001f49Smrg * GLM_SMOOTH - render with vertex normals 35632001f49Smrg * GLM_TEXTURE - render with texture coords 35732001f49Smrg * GLM_COLOR - render with colors (color material) 35832001f49Smrg * GLM_MATERIAL - render with materials 35932001f49Smrg * GLM_COLOR and GLM_MATERIAL should not both be specified. 36032001f49Smrg * GLM_FLAT and GLM_SMOOTH should not both be specified. 36132001f49Smrg */ 36232001f49SmrgGLuint 36332001f49SmrgglmList(GLMmodel* model, GLuint mode) 36432001f49Smrg{ 36532001f49Smrg GLuint list; 36632001f49Smrg 36732001f49Smrg list = glGenLists(1); 36832001f49Smrg glNewList(list, GL_COMPILE); 36932001f49Smrg glmDraw(model, mode); 37032001f49Smrg glEndList(); 37132001f49Smrg 37232001f49Smrg return list; 37332001f49Smrg} 37432001f49Smrg 37532001f49Smrg 37632001f49Smrg 37732001f49Smrgstatic const char *VertexShader = 37832001f49Smrg "varying vec3 normal; \n" 37932001f49Smrg "void main() { \n" 38032001f49Smrg " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n" 38132001f49Smrg " normal = gl_NormalMatrix * gl_Normal; \n" 38232001f49Smrg " gl_TexCoord[0] = gl_MultiTexCoord0; \n" 38332001f49Smrg "} \n"; 38432001f49Smrg 38532001f49Smrg/** 38632001f49Smrg * Two %s substitutions: 38732001f49Smrg * diffuse texture? true/false 38832001f49Smrg * specular texture? true/false 38932001f49Smrg */ 39032001f49Smrgstatic const char *TexFragmentShader = 39132001f49Smrg "uniform vec4 ambient, diffuse, specular; \n" 39232001f49Smrg "uniform vec4 ambientLight, diffuseLight, specularLight; \n" 39332001f49Smrg "uniform float shininess; \n" 39432001f49Smrg "uniform sampler2D diffTex; \n" 39532001f49Smrg "uniform samplerCube specTex; \n" 39632001f49Smrg "varying vec3 normal; \n" 39732001f49Smrg "\n" 39832001f49Smrg "void main() \n" 39932001f49Smrg "{ \n" 40032001f49Smrg " vec4 diffTerm, specTerm; \n" 40132001f49Smrg " float dotProd = max(dot(gl_LightSource[0].position.xyz, \n" 40232001f49Smrg " normalize(normal)), 0.0);\n" 40332001f49Smrg " float dotProd2 = max(dot(-gl_LightSource[0].position.xyz, \n" 40432001f49Smrg " normalize(normal)), 0.0);\n" 40532001f49Smrg " dotProd += dotProd2; \n" 40632001f49Smrg " \n" 40732001f49Smrg " diffTerm = diffuse * diffuseLight * dotProd; \n" 40832001f49Smrg " if (%s) \n" 40932001f49Smrg " diffTerm *= texture2D(diffTex, gl_TexCoord[0].st); \n" 41032001f49Smrg " \n" 41132001f49Smrg " specTerm = specular * specularLight * pow(dotProd, shininess); \n" 41232001f49Smrg " if (%s) \n" 41332001f49Smrg " specTerm *= textureCube(specTex, normal); \n" 41432001f49Smrg " \n" 41532001f49Smrg " gl_FragColor = ambient * ambientLight + diffTerm + specTerm; \n" 41632001f49Smrg "} \n"; 41732001f49Smrg 41832001f49Smrg 41932001f49Smrgvoid 42032001f49SmrgglmShaderMaterial(GLMmaterial *mat) 42132001f49Smrg{ 42232001f49Smrg static const float ambientLight[4] = { 0.1, 0.1, 0.1, 0.0 }; 42332001f49Smrg static const float diffuseLight[4] = { 0.75, 0.75, 0.75, 1.0 }; 42432001f49Smrg static const float specularLight[4] = { 1.0, 1.0, 1.0, 0.0 }; 42532001f49Smrg 42632001f49Smrg if (!mat->prog) { 42732001f49Smrg /* make shader now */ 42832001f49Smrg char newShader[10000]; 42932001f49Smrg GLuint vs, fs; 43032001f49Smrg const char *diffuseTex = mat->texture_kd ? "true" : "false"; 43132001f49Smrg const char *specularTex = mat->texture_ks ? "true" : "false"; 43232001f49Smrg GLint uAmbientLight, uDiffuseLight, uSpecularLight; 43332001f49Smrg 43432001f49Smrg /* replace %d with 0 or 1 */ 43532001f49Smrg sprintf(newShader, TexFragmentShader, diffuseTex, specularTex); 43632001f49Smrg if (0) 43732001f49Smrg printf("===== new shader =====\n%s\n============\n", newShader); 43832001f49Smrg 43932001f49Smrg vs = CompileShaderText(GL_VERTEX_SHADER, VertexShader); 44032001f49Smrg fs = CompileShaderText(GL_FRAGMENT_SHADER, newShader); 44132001f49Smrg mat->prog = LinkShaders(vs, fs); 44232001f49Smrg assert(mat->prog); 44332001f49Smrg 44432001f49Smrg glUseProgram(mat->prog); 44532001f49Smrg 44632001f49Smrg mat->uAmbient = glGetUniformLocation(mat->prog, "ambient"); 44732001f49Smrg mat->uDiffuse = glGetUniformLocation(mat->prog, "diffuse"); 44832001f49Smrg mat->uSpecular = glGetUniformLocation(mat->prog, "specular"); 44932001f49Smrg mat->uShininess = glGetUniformLocation(mat->prog, "shininess"); 45032001f49Smrg mat->uDiffTex = glGetUniformLocation(mat->prog, "diffTex"); 45132001f49Smrg mat->uSpecTex = glGetUniformLocation(mat->prog, "specTex"); 45232001f49Smrg 45332001f49Smrg uAmbientLight = glGetUniformLocation(mat->prog, "ambientLight"); 45432001f49Smrg uDiffuseLight = glGetUniformLocation(mat->prog, "diffuseLight"); 45532001f49Smrg uSpecularLight = glGetUniformLocation(mat->prog, "specularLight"); 45632001f49Smrg 45732001f49Smrg glUniform4fv(mat->uAmbient, 1, mat->ambient); 45832001f49Smrg glUniform4fv(mat->uDiffuse, 1, mat->diffuse); 45932001f49Smrg glUniform4fv(mat->uSpecular, 1, mat->specular); 46032001f49Smrg glUniform1f(mat->uShininess, mat->shininess); 46132001f49Smrg glUniform1i(mat->uDiffTex, 0); 46232001f49Smrg glUniform1i(mat->uSpecTex, 1); 46332001f49Smrg 46432001f49Smrg glUniform4fv(uAmbientLight, 1, ambientLight); 46532001f49Smrg glUniform4fv(uDiffuseLight, 1, diffuseLight); 46632001f49Smrg glUniform4fv(uSpecularLight, 1, specularLight); 46732001f49Smrg } 46832001f49Smrg 46932001f49Smrg glActiveTexture(GL_TEXTURE1); 47032001f49Smrg if (mat->texture_ks) 47132001f49Smrg glBindTexture(GL_TEXTURE_CUBE_MAP, mat->texture_ks); 47232001f49Smrg else 47332001f49Smrg glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 47432001f49Smrg 47532001f49Smrg glActiveTexture(GL_TEXTURE0); 47632001f49Smrg if (mat->texture_kd) 47732001f49Smrg glBindTexture(GL_TEXTURE_2D, mat->texture_kd); 47832001f49Smrg else 47932001f49Smrg glBindTexture(GL_TEXTURE_2D, 0); 48032001f49Smrg 48132001f49Smrg if (mat->diffuse[3] < 1.0) { 48232001f49Smrg glEnable(GL_BLEND); 48332001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 48432001f49Smrg } 48532001f49Smrg else { 48632001f49Smrg glDisable(GL_BLEND); 48732001f49Smrg } 48832001f49Smrg 48932001f49Smrg glUseProgram(mat->prog); 49032001f49Smrg} 49132001f49Smrg 49232001f49Smrg 49332001f49Smrgvoid 49432001f49SmrgglmSpecularTexture(GLMmodel *model, uint cubeTex) 49532001f49Smrg{ 49632001f49Smrg uint i; 49732001f49Smrg 49832001f49Smrg for (i = 0; i < model->nummaterials; i++) { 49932001f49Smrg model->materials[i].texture_ks = cubeTex; 50032001f49Smrg } 50132001f49Smrg} 502