Paso 3: Crear al procesador de
A continuación vamos a comenzar con el código necesario para conseguir algo haciendo. Para esto sólo modifiqué el código en la plantilla de ángulo que dibuja un cubo hilado GLES. Ahora agregue una clase de SimpleRenderer a un nuevo proyecto C++ compartido que llamamos SharedRenderer. Esta voluntad más adelante también compartido por otros proyectos. También referencia a este proyecto en los componentes de tiempo de ejecución.
Por favor apenas comienzo apagando encabezados precompilados porque esto no juega actualmente con Android comparte C++ en VS 2015 RC. Esto es debido a un proyecto compartido de C++ VS actualmente no puede ver los archivos en un proyecto de biblioteca de C++ Android. Aquí espera que Microsoft lo arregla pronto. Puede hacer esto yendo a la página de propiedades de ángulo tanto Win WP y simplemente seleccionando "No utilizar precompilado encabezados" en el campo "Encabezado precompilado" en el grupo "C/C ++".
No voy a discutir lo que hace el siguiente código GLES como está fuera del alcance del tutorial. Así que poner lo siguiente en el encabezado:
#pragma once #include <GLES2/gl2.h>
class SimpleRenderer{ public: SimpleRenderer(); ~SimpleRenderer(); void Draw(); void UpdateWindowSize(GLsizei width, GLsizei height); void Init();
private: GLuint mProgram; GLsizei mWindowWidth; GLsizei mWindowHeight;
GLint mPositionAttribLocation; GLint mColorAttribLocation;
GLint mModelUniformLocation; GLint mViewUniformLocation; GLint mProjUniformLocation;
GLuint mVertexPositionBuffer; GLuint mVertexColorBuffer; GLuint mIndexBuffer;
int mDrawCount; };
Y la siguiente en el archivo CPP:
// This file is used by the template to render a basic scene using GL.
#include "SimpleRenderer.h" #include "MathHelper.h"
#include <vector> #include <string>
#include <GLES2/gl2.h> #include <GLES2/gl2ext.h>
#if defined(WIN_STORE) || defined(WIN_PHONE) #include <ppltasks.h>
using namespace Platform; #endif
#define STRING(s) #s
GLuint CompileShader(GLenum type, const std::string &source) { GLuint shader = glCreateShader(type);
const char *sourceArray[1] = { source.c_str() }; glShaderSource(shader, 1, sourceArray, NULL); glCompileShader(shader);
GLint compileResult; glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
if (compileResult == 0) { GLint infoLogLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
std::vector infoLog(infoLogLength); glGetShaderInfoLog(shader, (GLsizei)infoLog.size(), NULL, infoLog.data());
std::wstring errorMessage = std::wstring(L"Shader compilation failed: "); errorMessage += std::wstring(infoLog.begin(), infoLog.end());
#if defined(WIN_STORE) || defined(WIN_PHONE) throw Exception::CreateException(E_FAIL, ref new Platform::String(errorMessage.c_str())); #endif }
return shader; }
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) { GLuint program = glCreateProgram();
if (program == 0) { #if defined(WIN_STORE) || defined(WIN_PHONE) throw Exception::CreateException(E_FAIL, L"Program creation failed"); #else return -1; #endif }
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
if (vs == 0 || fs == 0) { glDeleteShader(fs); glDeleteShader(vs); glDeleteProgram(program); return 0; }
glAttachShader(program, vs); glDeleteShader(vs);
glAttachShader(program, fs); glDeleteShader(fs);
glLinkProgram(program);
GLint linkStatus; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == 0) { GLint infoLogLength; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
std::vector infoLog(infoLogLength); glGetProgramInfoLog(program, (GLsizei)infoLog.size(), NULL, infoLog.data());
std::wstring errorMessage = std::wstring(L"Program link failed: "); errorMessage += std::wstring(infoLog.begin(), infoLog.end());
#if defined(WIN_STORE) || defined(WIN_PHONE) throw Exception::CreateException(E_FAIL, ref new Platform::String(errorMessage.c_str())); #else return -1; #endif }
return program; }
SimpleRenderer::SimpleRenderer() : mWindowWidth(0), mWindowHeight(0), mDrawCount(0) { }
void SimpleRenderer::Init() { // Vertex Shader source const std::string vs = STRING ( uniform mat4 uModelMatrix; uniform mat4 uViewMatrix; uniform mat4 uProjMatrix; attribute vec4 aPosition; attribute vec4 aColor; varying vec4 vColor; void main() { gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * aPosition; vColor = aColor; } );
// Fragment Shader source const std::string fs = STRING ( precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; } );
// Set up the shader and its uniform/attribute locations. mProgram = CompileProgram(vs, fs); mPositionAttribLocation = glGetAttribLocation(mProgram, "aPosition"); mColorAttribLocation = glGetAttribLocation(mProgram, "aColor"); mModelUniformLocation = glGetUniformLocation(mProgram, "uModelMatrix"); mViewUniformLocation = glGetUniformLocation(mProgram, "uViewMatrix"); mProjUniformLocation = glGetUniformLocation(mProgram, "uProjMatrix");
// Then set up the cube geometry. GLfloat vertexPositions[] = { -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, };
glGenBuffers(1, &mVertexPositionBuffer); glBindBuffer(GL_ARRAY_BUFFER, mVertexPositionBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
GLfloat vertexColors[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, };
glGenBuffers(1, &mVertexColorBuffer); glBindBuffer(GL_ARRAY_BUFFER, mVertexColorBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexColors), vertexColors, GL_STATIC_DRAW);
short indices[] = { 0, 1, 2, // -x 1, 3, 2,
4, 6, 5, // +x 5, 6, 7,
0, 5, 1, // -y 0, 4, 5,
2, 7, 6, // +y 2, 3, 7,
0, 6, 4, // -z 0, 2, 6,
1, 7, 3, // +z 1, 5, 7, };
glGenBuffers(1, &mIndexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); }
SimpleRenderer::~SimpleRenderer() { if (mProgram != 0) { glDeleteProgram(mProgram); mProgram = 0; }
if (mVertexPositionBuffer != 0) { glDeleteBuffers(1, &mVertexPositionBuffer); mVertexPositionBuffer = 0; }
if (mVertexColorBuffer != 0) { glDeleteBuffers(1, &mVertexColorBuffer); mVertexColorBuffer = 0; }
if (mIndexBuffer != 0) { glDeleteBuffers(1, &mIndexBuffer); mIndexBuffer = 0; } }
void SimpleRenderer::Draw() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (mProgram == 0) return;
glUseProgram(mProgram);
glBindBuffer(GL_ARRAY_BUFFER, mVertexPositionBuffer); glEnableVertexAttribArray(mPositionAttribLocation); glVertexAttribPointer(mPositionAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, mVertexColorBuffer); glEnableVertexAttribArray(mColorAttribLocation); glVertexAttribPointer(mColorAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
MathHelper::Matrix4 modelMatrix = MathHelper::SimpleModelMatrix((float)mDrawCount / 50.0f); glUniformMatrix4fv(mModelUniformLocation, 1, GL_FALSE, &(modelMatrix.m[0][0]));
MathHelper::Matrix4 viewMatrix = MathHelper::SimpleViewMatrix(); glUniformMatrix4fv(mViewUniformLocation, 1, GL_FALSE, &(viewMatrix.m[0][0]));
MathHelper::Matrix4 projectionMatrix = MathHelper::SimpleProjectionMatrix(float(mWindowWidth) / float(mWindowHeight)); glUniformMatrix4fv(mProjUniformLocation, 1, GL_FALSE, &(projectionMatrix.m[0][0]));
// Draw 36 indices: six faces, two triangles per face, 3 indices per triangle glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); glDrawElements(GL_TRIANGLES, (6 * 2) * 3, GL_UNSIGNED_SHORT, 0);
mDrawCount += 1; }
void SimpleRenderer::UpdateWindowSize(GLsizei width, GLsizei height) { glViewport(0, 0, width, height); mWindowWidth = width; mWindowHeight = height; }
En el proyecto de SharedRenderer usted necesitará añadir un fichero MathHelper.h con el siguiente contenido:
#pragma once // These are some simple math helpers to enable the template to render a spinning cube. It is not a complete math library. // You can replace this with your favorite math library that's suitable for your target platforms, e.g. DirectXMath or GLM.
#include <math.h>
namespace MathHelper {
struct Matrix4 { Matrix4(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) { m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; }
float m[4][4]; };
inline static Matrix4 SimpleModelMatrix(float radians) { float cosine = cosf(radians); float sine = sinf(radians);
return Matrix4(cosine, 0.0f, -sine, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, sine, 0.0f, cosine, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
inline static Matrix4 SimpleViewMatrix() { // Camera is at 60 degrees to the ground, in the YZ plane. // Camera Look-At is hardcoded to (0, 0, 0). // Camera Up is hardcoded to (0, 1, 0). const float sqrt3over2 = 0.86603f; const float cameraDistance = 5.0f;
return Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, sqrt3over2, 0.5f, 0.0f, 0.0f, -0.5f, sqrt3over2, 0.0f, 0.0f, 0.0f, -cameraDistance, 1.0f); }
inline static Matrix4 SimpleProjectionMatrix(float aspectRatio) { // Far plane is at 50.0f, near plane is at 1.0f. // FoV is hardcoded to pi/3. const float cotangent = 1 / tanf(3.14159f / 6.0f);
return Matrix4(cotangent / aspectRatio, 0.0f, 0.0f, 0.0f, 0.0f, cotangent, 0.0f, 0.0f, 0.0f, 0.0f, -50.0f / (50.0f - 1.0f), (-50.0f * 1.0f) / (50.0f - 1.0f), 0.0f, 0.0f, -1.0f, 0.0f); }
}
Usted debe ser capaz de compilar su proyecto ahora mismo otra vez. Si no, volver atrás y comprobar lo que podría haber perdido. También, te recomiendo borrar los archivos "Class1.h" y "Class.cpp" en los componentes de tiempo de ejecución como no los necesitamos. A Escriba el espacio de nombres predeterminado utilizado en ellos primero que necesitará más adelante.