C++ OpenGL ES Viewer in C# (3 / 8 stap)

Stap 3: Maak de Renderer


Wij gaan volgende om te beginnen met de code die nodig is om iets renderen te krijgen. Voor dit gewijzigde ik zojuist de GLES code in de hoek-sjabloon die een draaiende kubus tekent. Dus nu een SimpleRenderer-klasse toevoegen aan een nieuwe gedeelde C++-project dat we SharedRenderer zullen noemen. Dit zal worden later ook gedeeld door de andere projecten. Ook verwijst enkel naar dit project in de Runtime-onderdelen.

Gelieve enkel start door het uitschakelen van vooraf gecompileerde headers, omdat dit momenteel niet mooi met Android speelt gedeeld C++ in VS 2015 RC. Dit is omdat C++-project van een VS-gedeelde bestanden op een Android C++ library project momenteel niet kan zien. Hier de hoop dat Microsoft bevestigt het binnenkort. U kunt dit doen door te gaan naar de eigenschappenpagina van uw hoek op zowel Win als WP en simpelweg selecteren van "Niet met behulp van gecompileerde Headers" in het veld "Voorgecompileerd Header" in de groep "C/C++".

Ik ga niet om te bespreken wat de volgende GLES code doet zoals het valt buiten het bestek van de tutorial. Zet dus gewoon de volgende in de header:

 #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; }; 

En de volgende handelingen uit in het CPP-bestand:

 // 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; } 

In het SharedRenderer-project moet u ook een MathHelper.h-bestand met de volgende inhoud toe te voegen:

 #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); } 
 } 

U moet zitten kundig voor uw project nu opnieuw compileren. Als dat niet het geval is, ga terug en controleer wat u zou kunnen gemist hebben. Ik adviseer ook verwijderen van de bestanden "Class1.h" en "Class.cpp" in de Runtime-onderdelen, zoals we ze niet nodig. Net noteer de standaardnaamruimte gebruikt in hen eerst als u zult het later nodig hebben.

Gerelateerde Artikelen

Beginners Guide to OpenGL: Maak uw eigen CAD-software

Beginners Guide to OpenGL: Maak uw eigen CAD-software

Mijn Autodesk Maya student licentie verlopen onlangs. Dus ik deed wat iedereen zou doen, bouwen mijn eigen 3D CAD software (Let op Autodesk).Dus ik begon te schrijven van mijn toepassing in C++ met behulp van OpenGL, SDL en in ongeveer een week, dit
Zonsverduistering Viewer

Zonsverduistering Viewer

Meeste zonsverduistering kijkers zijn zo gemaakt dat u niet hoeft te staren naar de zon. Terwijl goed bedoelingen goed zijn, vind ik dat saai. Zo hier gaat u. Volg alle waarschuwingen en veilig.Stap 1: Waarom dit doen?Ik vaak een hekel aan de meeste
Het gebruik van Pepakura Viewer

Het gebruik van Pepakura Viewer

Deze tutorial beschrijft Pepakura Viewer.In geval u op zoek bent voor Pepakura designer tutorial, hoofd hier:Bijgewerkt: 2013/01/11... 5 uur werken tot nu toe :)Stap 1: Video op Youtube (HD 720p)In geval liever u video lezing. Op mijn kanaal zo goed
Verwijderen de knop verwijderen op een digitale foto-viewer om er veilig voor oma

Verwijderen de knop verwijderen op een digitale foto-viewer om er veilig voor oma

geïnspireerd door de zelfgemaakte digitale fotolijst hier, ik ging op zoek naar de onderdelen voor het bouwen van mijn eigen. Beschamend, vond ik een goedkoop genoeg afgewerkt product dat ik kocht in plaats van het opbouwen van mijn eigen. Echter, ik
Zonsverduistering Viewer uit de lezing van glazen en karton

Zonsverduistering Viewer uit de lezing van glazen en karton

Zonsverduisteringen zijn zeldzame astronomische gebeurtenissen spannend zijn om te kijken, maar vereist enige vorm van apparatuur voor het veilig bekijken. Zelfs als de meeste van de zon is verduisterd, straalt het nog voldoende licht, met name ultra
Een VR Viewer voor tabletten met uitstekende optiek

Een VR Viewer voor tabletten met uitstekende optiek

Dit Instructable toont u hoe te maken van een VR-viewer zoals Googles karton maar geoptimaliseerd voor tabletten. Afgezien van de tablet zijn de kosten zeer laag. Het maakt gebruik van twee paar Leesbrillen van een dollaropslag (Dollar boom), een kun
Goedkope aangepaste VR Viewer van telefooncel

Goedkope aangepaste VR Viewer van telefooncel

Ik kocht een goedkope Google karton viewer van ebay, maar spoedig na het gebruik ervan heb ik besloten om mijn eigen te bouwen. Het was vervelend hoe ik moest blijven bewegen de kijker gewoon om te zien het hele scherm. Ik besefte dat dit was omdat d
Oneindige werelden Viewer!

Oneindige werelden Viewer!

Uw eigen kloon leger is nog nooit zo echt geweest. Als u ooit bij de kapper tussen twee spiegels en voelde zat hebt alsof u in de schemerzone vast zaten, maak je klaar om het gevoel weer helemaal dat tintelen van oneindigheid. En opnieuw en opnieuw e
Maak je eigen VR-ervaring met DODOcase Virtual Reality Viewer

Maak je eigen VR-ervaring met DODOcase Virtual Reality Viewer

The Google karton en DODOcase virtuele werkelijkheid Viewer zijn netjes, goedkope manieren om immersieve Virtual Reality ervaring met hoofd bijhouden van de navigatie. Ik wilde enkele grote voorbeelden van VR Apps vinden en vooral voor het maken van
Sun Viewer: Observeren de zon veilig met een verrekijker

Sun Viewer: Observeren de zon veilig met een verrekijker

Met verrekijkers naar project een beeld van de zon is een oude truc, maar het is een goeie! Echter, de meeste oudere boeken bellen voor een installatie die gebruikmaakt van een fotografische statief en is moeilijk te zetten en gericht houden (met nam
Zelfgemaakte nachtzicht infrarood Goggle toepassingsgebied DIY CCTV View Finder Camera leidde Module

Zelfgemaakte nachtzicht infrarood Goggle toepassingsgebied DIY CCTV View Finder Camera leidde Module

Night vision goggles werden uitgevonden voor gebruik door het leger. De technologie die het mogelijk maakt van nachtzicht heet een infrarood image intensifier buis. De buizen Pipetteer fotonen in elektronen door een lading passeren een foto kathode e
Delphi tutorial - Picture Viewer

Delphi tutorial - Picture Viewer

Dus, dit kan ook worden opgeroepen een instructable, hoe Maak eenvoudige (en nog complexer) foto-viewer met Delphi programmeer gereedschap (of met Lazarus, gratis pascal programming tool).Om dit te doen is het duidelijk dat één moeten hebben van Delp
DYI polariserende Viewer

DYI polariserende Viewer

Inleiding: It's about time die iemand geboden instructies met oude lenzen van een paar 3D bril. Zodra u deze viewer maakt, zult u kunnen experimenteren met gepolariseerd licht. De meer kijkers die u aanbrengt, leuke hoe meer wetenschap u kunt hebben.
Maak uw eigen 3D-viewer (A glazen prisma), Cross kant van het oog door SIDE(CES) stereogrammen, afbeeldingen en video's bekijken in 3D

Maak uw eigen 3D-viewer (A glazen prisma), Cross kant van het oog door SIDE(CES) stereogrammen, afbeeldingen en video's bekijken in 3D

A doen het zelf glazen prisma, gevuld met water of glycerine olie, bekijken van 3D Kant door kant (CES) foto's, dat wil zeggen (CES) stereogrammen en (CES)Videosclearly en eenvoudig zonder dat u hoeft te leren de methode cross oog.Dit project toont u