Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp')
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp591
1 files changed, 591 insertions, 0 deletions
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
new file mode 100644
index 00000000000..936f9ea0657
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -0,0 +1,591 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifdef GLES
+#include <GLES2/gl2.h>
+#endif
+
+#include "GPU_extensions.h"
+
+#include "RAS_StorageVA.h"
+
+#include "GPU_compatibility.h"
+#include "GPU_colors.h"
+#include "GPU_material.h"
+#include "GPU_object.h"
+#include "GPU_functions.h"
+
+RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) :
+ m_texco_num(texco_num),
+ m_texco(texco),
+ m_attrib_num(attrib_num),
+ m_attrib(attrib),
+ m_last_texco_num(0),
+ m_last_attrib_num(0)
+{
+}
+
+RAS_StorageVA::~RAS_StorageVA()
+{
+}
+
+bool RAS_StorageVA::Init()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ return true;
+}
+
+void RAS_StorageVA::Exit()
+{
+}
+
+
+#include REAL_GL_MODE
+#include <stdio.h>
+ GLuint programObject = 0;
+
+
+GLuint MobLoadShader(GLenum type, const char *src)
+{
+ GLuint shader;
+ GLint compiled;
+
+ shader = glCreateShader (type);
+
+ if (!shader)
+ return 0;
+
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader (shader);
+
+ glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
+
+ if (!compiled)
+ {
+ GLint infoLen = 0;
+
+ glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLen);
+
+ if(infoLen > 0)
+ {
+ char* log = (char*)malloc(sizeof(char) * infoLen);
+
+ glGetShaderInfoLog(shader, infoLen, NULL, log);
+ printf ("Error:\n%s\n", log);
+
+ free(log);
+ }
+
+ glDeleteShader(shader);
+ return 0;
+ }
+
+ return shader;
+}
+
+
+int MobInit ( void)
+{
+
+ const char vShaderStr[] =
+ "precision mediump float; \n"
+ "attribute vec4 vPosition; \n"
+ "attribute vec4 vNorm; \n"
+ "varying vec3 pos; \n"
+ "varying vec3 normv; \n"
+ "uniform mat4 bProjectionMatrix ; \n"
+ "uniform mat4 bModelViewMatrix ; \n"
+ "varying vec3 lightp; \n"
+ "void main() \n"
+ "{ \n"
+ "lightp = vec3(6.0, 6.0, 6.0);"
+ "vec4 posmodel = bModelViewMatrix * vPosition;\n"
+ "pos = vec3( posmodel); \n"
+ "normv = normalize(vec3(bModelViewMatrix *vNorm)); \n"
+ " gl_Position = bProjectionMatrix * posmodel; \n"
+ "} \n"
+ " \n";
+
+ const char fShaderStr[] =
+ "precision mediump float; \n"
+ "varying vec3 pos; \n"
+ "varying vec3 normv; \n"
+ "varying vec3 lightp ; \n"
+ "void main() \n"
+ "{ \n"
+ "vec3 diff = pos-lightp; \n"
+ "float mull = (1000.0*dot(normalize(diff),normv)/sqrt(dot(diff,diff))/dot(diff,diff)); \n"
+ "if(mull>1.0){mull=1.0;};\n"
+ //"if(mull<0.0){mull*=-1.0;};\n"
+ "gl_FragColor = vec4 (vec3(mull), 1.0 ); \n"
+ "} \n";
+
+ GLuint vertexShader;
+ GLuint fragmentShader;
+ GLint linked;
+
+ vertexShader = MobLoadShader(GL_VERTEX_SHADER, vShaderStr);
+ fragmentShader = MobLoadShader(GL_FRAGMENT_SHADER, fShaderStr);
+
+ programObject = glCreateProgram();
+
+ if (programObject == 0)
+ return 0;
+
+ glAttachShader(programObject, vertexShader);
+ glAttachShader(programObject, fragmentShader);
+
+ glBindAttribLocation(programObject, 0, "vPosition");
+ glBindAttribLocation(programObject, 1, "vNorm");
+
+ glLinkProgram(programObject);
+
+ glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
+
+ if (!linked)
+ {
+ GLint size = 0;
+
+ glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &size);
+ if (size > 0)
+ {
+ char* log = (char*)malloc(sizeof(char) * size);
+
+ glGetProgramInfoLog(programObject, size, NULL, log);
+ printf("Error:\n%s\n", log);
+
+ free (log);
+ }
+
+ glDeleteProgram(programObject);
+ return GL_FALSE;
+ }
+
+
+
+ return GL_TRUE;
+}
+
+
+#include FAKE_GL_MODE
+
+
+#ifdef GLES
+
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ GLint posmat;
+ float mat[16];
+
+
+ if (!wireframe)
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+ else {
+ gpuCurrentColor3x(CPACK_BLACK);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+ }
+ else
+ gpuCurrentColor3x(CPACK_BLACK);
+
+#include REAL_GL_MODE
+ //glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ if(programObject==0)
+ {
+
+ MobInit();
+ //programObject =1;
+
+ glEnable(GL_DEPTH_TEST);
+
+
+ }
+glFrontFace(GL_CCW);
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+glDepthMask( true );
+ glUseProgram (programObject );
+
+ gpuGetMatrix(GL_MODELVIEW_MATRIX, mat);
+ posmat = glGetUniformLocation(programObject, "bModelViewMatrix");
+ glUniformMatrix4fv(posmat,1,0,mat);
+
+ gpuGetMatrix(GL_PROJECTION_MATRIX, mat);
+ posmat = glGetUniformLocation(programObject, "bProjectionMatrix");
+ glUniformMatrix4fv(posmat,1,0,mat);
+
+ int infoLen;
+ glGetProgramiv ( programObject, GL_ACTIVE_UNIFORMS, &infoLen );
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, 0,stride, it.vertex->getXYZ());
+ glEnableVertexAttribArray ( 0 );
+ glVertexAttribPointer(1, 3, GL_FLOAT, 0,stride, it.vertex->getNormal());
+ glEnableVertexAttribArray ( 1 );
+
+#include FAKE_GL_MODE
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+
+ if (!wireframe) {
+ glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
+ if (glIsEnabled(GL_COLOR_ARRAY))
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+
+#include REAL_GL_MODE
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+#include FAKE_GL_MODE
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+}
+
+
+#else
+
+void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ gpuMatrixCommit();
+
+ if (!wireframe)
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ use_color_array = false;
+ }
+ else {
+ gpuCurrentColor3x(CPACK_BLACK);
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
+ }
+ else {
+ gpuCurrentColor3x(CPACK_BLACK);
+ }
+
+ glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+ if (!wireframe) {
+ glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0));
+ if (use_color_array)
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+}
+
+
+
+#endif
+
+void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms)
+{
+ static const GLsizei stride = sizeof(RAS_TexVert);
+ bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array;
+ RAS_MeshSlot::iterator it;
+ GLenum drawmode;
+
+ if (!wireframe)
+ EnableTextures(true);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ // use glDrawElements to draw each vertexarray
+ for (ms.begin(it); !ms.end(it); ms.next(it)) {
+ if (it.totindex == 0)
+ continue;
+
+ // drawing mode
+ if (it.array->m_type == RAS_DisplayArray::TRIANGLE)
+ drawmode = GL_TRIANGLES;
+ else if (it.array->m_type == RAS_DisplayArray::QUAD)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
+ // colors
+ if (drawmode != GL_LINES && !wireframe) {
+ if (ms.m_bObjectColor) {
+ const MT_Vector4& rgba = ms.m_RGBAcolor;
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ gpuCurrentColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+ use_color_array = false;
+ }
+ else {
+ gpuCurrentColor3x(CPACK_BLACK);
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
+ }
+ else {
+ gpuCurrentColor3x(CPACK_BLACK);
+ }
+
+
+ gpuMatrixCommit();
+
+
+ gpugameobj.gpuVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ());
+ gpugameobj.gpuNormalPointer(GL_FLOAT, stride, it.vertex->getNormal());
+
+ if (!wireframe) {
+ TexCoordPtr(it.vertex);
+ if (use_color_array)
+ glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA());
+ }
+
+ // here the actual drawing takes places
+#include REAL_GL_MODE
+ // here the actual drawing takes places
+ glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index);
+#include FAKE_GL_MODE
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ if (!wireframe) {
+ glDisableClientState(GL_COLOR_ARRAY);
+ EnableTextures(false);
+ }
+}
+
+void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv)
+{
+ /* note: this function must closely match EnableTextures to enable/disable
+ * the right arrays, otherwise coordinate and attribute pointers from other
+ * materials can still be used and cause crashes */
+ int unit;
+
+ if (GLEW_ARB_multitexture)
+ {
+ for (unit = 0; unit < *m_texco_num; unit++)
+ {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
+ switch (m_texco[unit])
+ {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
+ break;
+ default:
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+
+ if (GPU_EXT_GLSL_VERTEX_ENABLED) {
+ int uv = 0;
+ for (unit = 0; unit < *m_attrib_num; unit++) {
+ switch (m_attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ gpu_glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ gpu_glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++));
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ gpu_glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
+ break;
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ gpu_glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
+ break;
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ gpu_glVertexAttribPointer(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void RAS_StorageVA::EnableTextures(bool enable)
+{
+ RAS_IRasterizer::TexCoGen *texco, *attrib;
+ int unit, texco_num, attrib_num;
+
+ /* we cache last texcoords and attribs to ensure we disable the ones that
+ * were actually last set */
+ if (enable) {
+ texco = m_texco;
+ texco_num = *m_texco_num;
+ attrib = m_attrib;
+ attrib_num = *m_attrib_num;
+
+ memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num));
+ m_last_texco_num = *m_texco_num;
+ memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num));
+ m_last_attrib_num = *m_attrib_num;
+ }
+ else {
+ texco = m_last_texco;
+ texco_num = m_last_texco_num;
+ attrib = m_last_attrib;
+ attrib_num = m_last_attrib_num;
+ }
+
+ if (GLEW_ARB_multitexture) {
+ for (unit = 0; unit < texco_num; unit++) {
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + unit);
+
+ switch (texco[unit])
+ {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ default:
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ }
+ }
+
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ else {
+ if (texco_num) {
+ if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+
+ if (GPU_EXT_GLSL_VERTEX_ENABLED) {
+ for (unit = 0; unit < attrib_num; unit++) {
+ switch (attrib[unit]) {
+ case RAS_IRasterizer::RAS_TEXCO_ORCO:
+ case RAS_IRasterizer::RAS_TEXCO_GLOB:
+ case RAS_IRasterizer::RAS_TEXCO_UV:
+ case RAS_IRasterizer::RAS_TEXCO_NORM:
+ case RAS_IRasterizer::RAS_TEXTANGENT:
+ case RAS_IRasterizer::RAS_TEXCO_VCOL:
+ if (enable) gpu_glEnableVertexAttribArray(unit);
+ else gpu_glDisableVertexAttribArray(unit);
+ break;
+ default:
+ gpu_glDisableVertexAttribArray(unit);
+ break;
+ }
+ }
+ }
+
+ if (!enable) {
+ m_last_texco_num = 0;
+ m_last_attrib_num = 0;
+ }
+}
+