CDR6275

Michio SHIRAISHI Official Site

CGプログラミング (2016 Fall)

12月15日の授業LookAt::draw

void LookAt::draw(){
  glEnable(GL_CULL_FACE);
  glEnable(GL_DEPTH_TEST);
  // 背景のクリア
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // 使用するプログラムオブジェクトをする
  glUseProgram(program);
 
  glUniform3f(uniforms[UNIFORM_VIEW_DIRECTION], 0.0f, 0.0f, 1.0f);
  glUniform3f(uniforms[UNIFORM_LIGHT_DIRECTION], 1.0f, 0.0f, 1.0f);
  glUniform3f(uniforms[UNIFORM_LIGHT_AMBIENT_COLOR], 1.0f, 1.0f, 1.0f);
  glUniform3f(uniforms[UNIFORM_LIGHT_DIFFUSE_COLOR], 1.0f, 1.0f, 1.0f);
  glUniform3f(uniforms[UNIFORM_LIGHT_SPECULAR_COLOR], 1.0f, 1.0f, 1.0f);
  glUniform1i(uniforms[UNIFORM_SHADING_ENABLED], 1);

  unsigned int* vertexCounts = polygonModel.getVertexCounts();
  float* ambientColors = polygonModel.getAmbientColors();
  float* diffuseColors = polygonModel.getDiffuseColors();
  float* specularColors = polygonModel.getSpecularColors();
  float* shinness = polygonModel.getShinness();

  for (int x = -1; x <= 1; x++){
	  Matrix::setIdentityM(modelMatrix, 0);
	  Matrix::translateM(modelMatrix, 0, x, 0.0, 0.0);
	  Matrix::scaleM(modelMatrix, 0, 0.07f, 0.07f, 0.07f);
	  Matrix::translateM(modelMatrix, 0, 0.0f, -polygonModel.getMaxHeight() / 2.0f, 0.0f);
	  Matrix::rotateM(modelMatrix, 0, 180.0, 0.0, 1.0, 0.0);
	  float modelViewMatrix[16];
	  Matrix::multiplyMM(modelViewMatrix, 0, viewMatrix, 0, modelMatrix, 0);

	  float invertMatrix[16];
	  Matrix::invertM(invertMatrix, 0, modelViewMatrix, 0);
	  Matrix::transposeM(normalMatrix, 0, invertMatrix, 0);

	// 投影行列を設定する
	glUniformMatrix4fv(uniforms[UNIFORM_PROJECTION_MATRIX], 1, 0, projectionMatrix);
	glUniformMatrix4fv(uniforms[UNIFORM_VIEW_MATRIX], 1, 0, viewMatrix);
	glUniformMatrix4fv(uniforms[UNIFORM_MODEL_MATRIX], 1, 0, modelMatrix);
	glUniformMatrix4fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, normalMatrix);
  
 
	  int sum = 0;
	  for (int i = 0; i < polygonModel.getNumMaterials(); i++){
		  glUniform3f(uniforms[UNIFORM_OBJECT_AMBIENT_COLOR], ambientColors[3 * i + 0], ambientColors[3 * i + 1], ambientColors[3 * i + 2]);
		  glUniform3f(uniforms[UNIFORM_OBJECT_DIFFUSE_COLOR], diffuseColors[3 * i + 0], diffuseColors[3 * i + 1], diffuseColors[3 * i + 2]);
		  glUniform3f(uniforms[UNIFORM_OBJECT_SPECULAR_COLOR], specularColors[3 * i + 0], specularColors[3 * i + 1], specularColors[3 * i + 2]);
		  glUniform1f(uniforms[UNIFORM_OBJECT_SHINNESS], shinness[i]);
		  if (textures[i] == 0){
			  glUniform1i(uniforms[UNIFORM_TEXTURE_ENABLED], 0);
			  glDrawElements(GL_TRIANGLES, vertexCounts[i], GL_UNSIGNED_INT, (GLvoid*)(sum*sizeof(GLuint)));
		  }
		  else{
			  glUniform1i(uniforms[UNIFORM_TEXTURE_ENABLED], 1);
			  //      glEnable(GL_BLEND);
			  //      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			  glBindTexture(GL_TEXTURE_2D, textures[i]);
			  //      glUniform1i(ATTRIBUTE_VERTEX_TEXTURE_COORDINATE, 0);
			  glEnable(ATTRIBUTE_VERTEX_TEXTURE_COORDINATE);
			  glDrawElements(GL_TRIANGLES, vertexCounts[i], GL_UNSIGNED_INT, (GLvoid*)(sum*sizeof(GLuint)));
			  glDisable(ATTRIBUTE_VERTEX_TEXTURE_COORDINATE);
			  //      glDisable(GL_BLEND);
			  glBindTexture(GL_TEXTURE_2D, 0);
		  }
		  sum += vertexCounts[i];
	  }
  }
  // 使用するプログラムオブジェクトを解除する
  glUseProgram(0);
#if _WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
  // バッファの入れ替え
  glfwSwapBuffers(window);
  // イベントの取得
  glfwPollEvents();
#endif
}

10月13日の授業PentagonEdges.cpp

//
//  PentagonEdges.cpp
//  稜線を描くプログラム
//
//  Written by Michio SHIRAISHI <shira@is.sci.toho-u.ac.jp>.
//

#include <iostream>

#define _USE_MATH_DEFINES
#include <math.h>


#include "PentagonEdges.h"

#include "SimpleProgramObject.h"

#include "Matrix.h"


enum
{
  ATTRIBUTE_VERTEX_COORDINATE,
  NUM_ATTRIBUTES
};

enum
{
  UNIFORM_PROJECTION_MATRIX,
  NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];

const int numVertex = 5;

const int numLines = numVertex * (numVertex - 1) / 2;

GLuint edgeIndices[numLines * 2];

bool PentagonEdges::initialize(){

#if !TARGET_OS_IPHONE
  BaseApplication::initializeWindow(640, 640, "PentagonEdges");
#endif
  
  // 五角形の頂点座標
  float pentagonVertices[3*numVertex];
  for(int i=0; i<numVertex; i++){
    pentagonVertices[3*i+0] = 0.8f * (float)cos(i*M_PI*2.0/numVertex);
    pentagonVertices[3*i+1] = 0.8f * (float)sin(i*M_PI*2.0/numVertex);
    pentagonVertices[3*i+2] = 0.0f;
  }

    int count = 0;
  for (int i = 0; i < numVertex; i++){
	  for (int j = 0; j < numVertex; j++){
		  if (i >= j) continue;
		  edgeIndices[2 * count]     = i;
		  edgeIndices[2 * count + 1] = j;
		  count++;
	  }
  }
  SimpleProgramObject programObject;
  const char* vertexShaderFileName = "first.vs";
  const char* fragmentShaderFileName = "first.fs";
  
  program = programObject.createProgram(vertexShaderFileName, fragmentShaderFileName, shaderSearchPath);

  // シェーダコード内の変数にインデックスを設定する
  glBindAttribLocation(program, ATTRIBUTE_VERTEX_COORDINATE, "vertexCoordinate");
  
  programObject.linkProgram();
  
  // 頂点配列オブジェクトを作成して設定する
#if TARGET_OS_IPHONE
  glGenVertexArraysOES(1, &vertexArrayObject);
  glBindVertexArrayOES(vertexArrayObject);
#else
  glGenVertexArrays(1, &vertexArrayObject);
  glBindVertexArray(vertexArrayObject);
#endif
  
  // 頂点バッファオブジェクトを作成する
  glGenBuffers(1, &vertexBufferObject);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
  glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, pentagonVertices, GL_STATIC_DRAW);
  
  // 頂点バッファオブジェクトにシェーダ内の変数vertexCoodrinateを結びつける
  glEnableVertexAttribArray(ATTRIBUTE_VERTEX_COORDINATE);
  glVertexAttribPointer(ATTRIBUTE_VERTEX_COORDINATE, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, 0);
  
  // 要素配列バッファオブジェクトを作成する
  glGenBuffers(1, &elementArrayBufferObject);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferObject);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* numLines * 2, edgeIndices, GL_STATIC_DRAW);

  // 背景色の設定
  glClearColor(0.75f, 0.75f, 0.75f, 1.0f);
  
  // 頂点シェーダ内のprojectionMatrixの位置を保存する
  uniforms[UNIFORM_PROJECTION_MATRIX] = glGetUniformLocation(program, "projectionMatrix");

  return true;
}


void PentagonEdges::update(){
  
}

void PentagonEdges::draw(){
#if TARGET_OS_IPHONE
  int viewport[4];
  glGetIntegerv(GL_VIEWPORT, viewport);
  glViewport(0, (viewport[3]-viewport[2])/2, viewport[2], viewport[2]);
#endif
  // 背景のクリア
  glClear(GL_COLOR_BUFFER_BIT);
  // 使用するプログラムオブジェクトをする
  glUseProgram(program);
  // 三角形を描く
//  glDrawArrays(GL_LINES, 0, 2*7);
  glDrawElements(GL_LINES, 2 * numLines , GL_UNSIGNED_INT, 0);
  // 使用するプログラムオブジェクトを解除する
  glUseProgram(0);
#if _WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
  // バッファの入れ替え
  glfwSwapBuffers(window);
  // イベントの取得
  glfwPollEvents();
#endif
}

10月6日の授業でのIndexedPentagon.cpp

データはnum角形に対応していて、faceVertexIndicesを埋めるところが8角形のバージョンをそのまま書いてあります。

//
//  IndexedPentagon.cpp
//  頂点インデックスを用いた三角形の描画
//
//  Written by Michio SHIRAISHI <shira@is.sci.toho-u.ac.jp>.
//

#include <iostream>

#define _USE_MATH_DEFINES
#include <math.h>

#include "IndexedPentagon.h"
#include "SimpleProgramObject.h"
#include "Matrix.h"

enum
{
  ATTRIBUTE_VERTEX_COORDINATE,
  NUM_ATTRIBUTES
};

enum
{
  UNIFORM_PROJECTION_MATRIX,
  NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];

const int num = 8;

GLuint faceVertexIndices[3 * (num - 2)];

bool IndexedPentagon::initialize(){
#if !TARGET_OS_IPHONE
  BaseApplication::initializeWindow(640, 640, "IndexedPentagon");
#endif
  
  GLfloat vertexCoordinates[3*num];
  for (int i = 0; i<num; i++){
	  vertexCoordinates[3 * i + 0] = 0.8f * (GLfloat)cos(i*M_PI*2.0 / num);
	  vertexCoordinates[3 * i + 1] = 0.8f * (GLfloat)sin(i*M_PI*2.0 / num);
	 vertexCoordinates[3*i+2] = 0.0f;
  }

  faceVertexIndices[0] = 0;
  faceVertexIndices[1] = 1;
  faceVertexIndices[2] = 2;
  faceVertexIndices[3] = 0;
  faceVertexIndices[4] = 2;
  faceVertexIndices[5] = 3;
  faceVertexIndices[6] = 0;
  faceVertexIndices[7] = 3;
  faceVertexIndices[8] = 4;
  faceVertexIndices[9] = 0;
  faceVertexIndices[10] = 4;
  faceVertexIndices[11] = 5;
  faceVertexIndices[12] = 0;
  faceVertexIndices[13] = 5;
  faceVertexIndices[14] = 6;
  faceVertexIndices[15] = 0;
  faceVertexIndices[16] = 6;
  faceVertexIndices[17] = 7;

  
  SimpleProgramObject programObject;
  const char* vertexShaderFileName = "first.vs";
  const char* fragmentShaderFileName = "first.fs";
  
  program = programObject.createProgram(vertexShaderFileName, fragmentShaderFileName, shaderSearchPath);

  // シェーダコード内の変数にインデックスを設定する
  glBindAttribLocation(program, ATTRIBUTE_VERTEX_COORDINATE, "vertexCoordinate");
  
  programObject.linkProgram();
  
  // 頂点配列オブジェクトを作成して設定する
#if TARGET_OS_IPHONE
  glGenVertexArraysOES(1, &vertexArrayObject);
  glBindVertexArrayOES(vertexArrayObject);
#else
  glGenVertexArrays(1, &vertexArrayObject);
  glBindVertexArray(vertexArrayObject);
#endif
  
  // 頂点バッファオブジェクトを作成する
  glGenBuffers(1, &vertexBufferObject);
  glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
  glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*num, vertexCoordinates, GL_STATIC_DRAW);
  
  // 頂点バッファオブジェクトにシェーダ内の変数vertexCoodrinateを結びつける
  glEnableVertexAttribArray(ATTRIBUTE_VERTEX_COORDINATE);
  glVertexAttribPointer(ATTRIBUTE_VERTEX_COORDINATE, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, 0);
  
  // 要素配列バッファオブジェクトを作成する
  glGenBuffers(1, &elementArrayBufferObject);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferObject);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*3*(num-2), faceVertexIndices, GL_STATIC_DRAW);

  // 背景色の設定
  glClearColor(0.75f, 0.75f, 0.75f, 1.0f);
  
  return true;
}

void IndexedPentagon::update(){
  
}

void IndexedPentagon::draw(){
#if TARGET_OS_IPHONE
  int viewport[4];
  glGetIntegerv(GL_VIEWPORT, viewport);
  glViewport(0, (viewport[3]-viewport[2])/2, viewport[2], viewport[2]);
#endif
  // 背景のクリア
  glClear(GL_COLOR_BUFFER_BIT);
  // 使用するプログラムオブジェクトをする
  glUseProgram(program);
  // 三角形を描く
  glDrawElements(GL_TRIANGLES, 3*3*(num-2), GL_UNSIGNED_INT, 0);
  // 使用するプログラムオブジェクトを解除する
  glUseProgram(0);
#if _WIN32 || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
  // バッファの入れ替え
  glfwSwapBuffers(window);
  // イベントの取得
  glfwPollEvents();
#endif
}

Copyright 2012-2013 Michio SHIRAISHI. All rights reserved. Disclaimer.